dol: initial dol commit
[jump.git] / dol / src / dol / helper / profiler / ProfileParser.java
1 /* $Id: ProfileParser.java 203 2010-10-11 08:59:47Z dchokshi $ */\r
2 package dol.helper.profiler;\r
3 \r
4 import java.io.BufferedReader;\r
5 import java.io.FileReader;\r
6 import java.io.IOException;\r
7 import java.util.HashMap;\r
8 import java.util.Iterator;\r
9 import java.util.StringTokenizer;\r
10 import java.util.Vector;\r
11 \r
12 /**\r
13  * Class for parsing a profile and collecting parameter statistics.\r
14  */\r
15 public class ProfileParser {\r
16 \r
17     /**\r
18      * Constructor.\r
19      **/\r
20     public ProfileParser(String filename) {\r
21         try {\r
22             _in = new BufferedReader(new FileReader(filename));\r
23         } catch (IOException e) {\r
24             System.err.println(e.getLocalizedMessage());\r
25         }\r
26 \r
27         _processProfiles = new HashMap<String, ProcessProfile>();\r
28         _channelProfiles = new HashMap<String, ChannelProfile>();\r
29         _inPortToChannelMapping = new HashMap<String, String>();\r
30         _outPortToChannelMapping = new HashMap<String, String>();\r
31         _processCommOrder = new HashMap<String, Vector<String>>();\r
32     }\r
33 \r
34     /**\r
35      * Parse the profile file and generate the profiles for processes and\r
36      * channels. After calling this function, use\r
37      * {@link #getProcessProfiles()} and {@link #getChannelProfiles()} to\r
38      * obtain the result of parsing.\r
39      *\r
40      * @see #getChannelProfiles()\r
41      * @see #getProcessProfiles()\r
42      */\r
43     public void parseProfile() {\r
44         String nextWord;\r
45         String line = null;\r
46 \r
47         while (true) {\r
48             try {\r
49                 //PERFORMANCE: do not read line-by-line but read in larger\r
50                 //chunks from the file. has much more influence on the\r
51                 //performance than the data structures in this class.\r
52                 line = _in.readLine();\r
53                 if (line == null) {\r
54                     _in.close();\r
55 \r
56                     Iterator<String> iterator = _processProfiles.keySet().iterator();\r
57                     while (iterator.hasNext()) {\r
58                         _processProfiles.get(iterator.next()).stop();\r
59                     }\r
60                     return;\r
61                 }\r
62             } catch (IOException e) {\r
63                 System.err.println(e.getLocalizedMessage());\r
64                 return;\r
65             }\r
66 \r
67             StringTokenizer tokenizer = new StringTokenizer(line);\r
68             nextWord = tokenizer.nextToken();\r
69 \r
70             if (nextWord.equals("c")) {\r
71                 //'c' stands for a channel connection line. example:\r
72                 //c filterchannel 8 o filter 0x23c738 i filter 0x23c6e8\r
73                 String channelName = tokenizer.nextToken();\r
74                 int capacity = Integer.parseInt(\r
75                         tokenizer.nextToken());\r
76                 String portAType = tokenizer.nextToken();\r
77                 String processAName = tokenizer.nextToken();\r
78                 String portAName = tokenizer.nextToken();\r
79                 String portBType = tokenizer.nextToken();\r
80                 String processBName = tokenizer.nextToken();\r
81                 String portBName = tokenizer.nextToken();\r
82                 addChannelProfile(channelName, capacity,\r
83                         portAType, processAName, portAName,\r
84                         portBType, processBName, portBName);\r
85             } else {\r
86                 //current line is an event. examples:\r
87                 //examples:\r
88                 //78 filter started.\r
89                 //79 filter r 0x23c6c0 8\r
90                 //80 filter w 0x23c738 8\r
91                 //81 filter stopped.\r
92 \r
93                 int i = Integer.parseInt(nextWord);\r
94                 if (i != _lineCounter) {\r
95                     System.err.println("Input file corrupt: line number "\r
96                             + "expected.");\r
97                     return;\r
98                 }\r
99 \r
100                 //get process name\r
101                 String processName = tokenizer.nextToken();\r
102                 if (_processProfiles.get(processName) == null) {\r
103                     ProcessProfile processProfile = new ProcessProfile(\r
104                             processName);\r
105                     _processProfiles.put(processName, processProfile);\r
106                 }\r
107                 if(_processCommOrder.get(processName) == null) {\r
108                     _processCommOrder.put(processName, new Vector<String>());\r
109                 }\r
110 \r
111                 nextWord = tokenizer.nextToken();\r
112                 if(nextWord.equals("started.")) {\r
113                     _processProfiles.get(processName).start();\r
114                 }\r
115                 else if(nextWord.equals("stopped.")) {\r
116                     _processProfiles.get(processName).stop();\r
117                 }\r
118                 else if (nextWord.equals("r") || nextWord.equals("w")) {\r
119                     String accessType = nextWord;\r
120                     String portName = tokenizer.nextToken();\r
121                     int amount = Integer.parseInt(\r
122                             tokenizer.nextToken());\r
123                     try {\r
124                         _processProfiles.get(processName).\r
125                                 portAccess(portName, amount);\r
126                         if (accessType.equals("r")) {\r
127                             String channelName =\r
128                                 _inPortToChannelMapping.get(portName);\r
129                             _channelProfiles.get(channelName).\r
130                                     readAccess(amount);\r
131                             _processCommOrder.get(processName).add(channelName);\r
132 \r
133                         } else {\r
134                             String channelName =\r
135                                 _outPortToChannelMapping.get(portName);\r
136                             _channelProfiles.get(channelName).\r
137                                     writeAccess(amount);\r
138                             _processCommOrder.get(processName).add(channelName);\r
139                         }\r
140                     } catch (NullPointerException e) {\r
141                         System.err.println("Input file corrupt: cannot "\r
142                                 + "find channel associated to port "\r
143                                 + portName + "(line "\r
144                                 + _lineCounter + ").");\r
145                         e.printStackTrace();\r
146                         return;\r
147                     }\r
148                 } else {\r
149                     System.err.println("Input file corrupt: unknown "\r
150                             + "event type (line " + _lineCounter + ").");\r
151                     return;\r
152                 }\r
153                 _lineCounter++;\r
154             }\r
155         }\r
156     }\r
157 \r
158     /**\r
159      * Return the profiles of all processes.\r
160      *\r
161      *  @return profile of all processes\r
162      */\r
163     public HashMap<String, ProcessProfile> getProcessProfiles() {\r
164         return _processProfiles;\r
165     }\r
166 \r
167     /**\r
168      * Return the profiles of all channels.\r
169      *\r
170      *  @return profile of all channels\r
171      */\r
172     public HashMap<String, ChannelProfile> getChannelProfiles() {\r
173         return _channelProfiles;\r
174     }\r
175 \r
176     /**\r
177      * Return the order in which processes write to channels.\r
178      *\r
179      *  @return profile of all processes\r
180      */\r
181     public HashMap<String, Vector<String>> getProcessCommOrder() {\r
182         return _processCommOrder;\r
183     }\r
184 \r
185     /**\r
186      * Return the channel to which the port with the specified name is\r
187      * connected.\r
188      *\r
189      * @param port port name\r
190      * @return name of connected channel\r
191      */\r
192     public String getChannel(String port) {\r
193         if (_inPortToChannelMapping.get(port) != null) {\r
194             return _inPortToChannelMapping.get(port);\r
195         } else if (_outPortToChannelMapping.get(port) != null) {\r
196             return _outPortToChannelMapping.get(port);\r
197         }\r
198         return null;\r
199     }\r
200 \r
201     /**\r
202      * Return the type of the channel with the specified name.\r
203      *\r
204      * @param port port name\r
205      * @return type of port\r
206      */\r
207     public String getPortType(String port) {\r
208         if (_inPortToChannelMapping.get(port) != null) {\r
209             return "INPUT";\r
210         } else if (_outPortToChannelMapping.get(port) != null) {\r
211             return "OUTPUT";\r
212         }\r
213         return null;\r
214     }\r
215 \r
216     /**\r
217      * Add a channel profile to the HashMap of channel profiles.\r
218      *\r
219      * @param channelName name of the channel\r
220      * @param capacity capacity of the channel\r
221      * @param portAType type of first port (either "o" or "i")\r
222      * @param processAName name of process connected to first port\r
223      * @param portAName name of first port\r
224      * @param portBType type of second port (either "o" or "i")\r
225      * @param processBName name of process connected to second port\r
226      * @param portBName name of second port\r
227      */\r
228     protected void addChannelProfile(String channelName, int capacity,\r
229             String portAType, String processAName, String portAName,\r
230             String portBType, String processBName, String portBName) {\r
231 \r
232         ChannelProfile channelProfile =\r
233             new ChannelProfile(channelName, capacity);\r
234         _channelProfiles.put(channelName, channelProfile);\r
235 \r
236         if (portAType.equals("o")) {\r
237             //first output port, then input port\r
238             _outPortToChannelMapping.put(portAName, channelName);\r
239             if (!(portBType.equals("i"))) {\r
240                 System.err.println("Input file corrupt: each "\r
241                         + "channel needs one input- and one "\r
242                         + "output port.");\r
243                 return;\r
244             }\r
245             _inPortToChannelMapping.put(portBName, channelName);\r
246         } else if (portAType.equals("i")) {\r
247             //first input port, then output port\r
248             _inPortToChannelMapping.put(portAName, channelName);\r
249             if (!(portBType.equals("o"))) {\r
250                 System.err.println("Input file corrupt: each "\r
251                         + "channel needs one input- and one "\r
252                         + "output port.");\r
253                 return;\r
254             }\r
255             _outPortToChannelMapping.put(portBName, channelName);\r
256         } else {\r
257             System.err.println("Input file corrupt: bad channel "\r
258                     + "specification:");\r
259             System.err.println(channelName + " " + capacity + " "\r
260                     + portAType + " " + processAName + " " + portAName\r
261                     + " "\r
262                     + portBType + " " + processBName + " " + portBName);\r
263         }\r
264     }\r
265 \r
266     private BufferedReader _in = null;\r
267     protected int _lineCounter = 0;\r
268     HashMap<String, ProcessProfile> _processProfiles;\r
269     HashMap<String, ChannelProfile> _channelProfiles;\r
270     HashMap<String, String> _inPortToChannelMapping;\r
271     HashMap<String, String> _outPortToChannelMapping;\r
272     HashMap<String, Vector<String>> _processCommOrder;\r
273 }\r