dol: initial dol commit
[jump.git] / dol / src / dol / helper / profiler / ProfileParser.java
diff --git a/dol/src/dol/helper/profiler/ProfileParser.java b/dol/src/dol/helper/profiler/ProfileParser.java
new file mode 100644 (file)
index 0000000..5ad1304
--- /dev/null
@@ -0,0 +1,273 @@
+/* $Id: ProfileParser.java 203 2010-10-11 08:59:47Z dchokshi $ */\r
+package dol.helper.profiler;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.FileReader;\r
+import java.io.IOException;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * Class for parsing a profile and collecting parameter statistics.\r
+ */\r
+public class ProfileParser {\r
+\r
+    /**\r
+     * Constructor.\r
+     **/\r
+    public ProfileParser(String filename) {\r
+        try {\r
+            _in = new BufferedReader(new FileReader(filename));\r
+        } catch (IOException e) {\r
+            System.err.println(e.getLocalizedMessage());\r
+        }\r
+\r
+        _processProfiles = new HashMap<String, ProcessProfile>();\r
+        _channelProfiles = new HashMap<String, ChannelProfile>();\r
+        _inPortToChannelMapping = new HashMap<String, String>();\r
+        _outPortToChannelMapping = new HashMap<String, String>();\r
+        _processCommOrder = new HashMap<String, Vector<String>>();\r
+    }\r
+\r
+    /**\r
+     * Parse the profile file and generate the profiles for processes and\r
+     * channels. After calling this function, use\r
+     * {@link #getProcessProfiles()} and {@link #getChannelProfiles()} to\r
+     * obtain the result of parsing.\r
+     *\r
+     * @see #getChannelProfiles()\r
+     * @see #getProcessProfiles()\r
+     */\r
+    public void parseProfile() {\r
+        String nextWord;\r
+        String line = null;\r
+\r
+        while (true) {\r
+            try {\r
+                //PERFORMANCE: do not read line-by-line but read in larger\r
+                //chunks from the file. has much more influence on the\r
+                //performance than the data structures in this class.\r
+                line = _in.readLine();\r
+                if (line == null) {\r
+                    _in.close();\r
+\r
+                    Iterator<String> iterator = _processProfiles.keySet().iterator();\r
+                    while (iterator.hasNext()) {\r
+                        _processProfiles.get(iterator.next()).stop();\r
+                    }\r
+                    return;\r
+                }\r
+            } catch (IOException e) {\r
+                System.err.println(e.getLocalizedMessage());\r
+                return;\r
+            }\r
+\r
+            StringTokenizer tokenizer = new StringTokenizer(line);\r
+            nextWord = tokenizer.nextToken();\r
+\r
+            if (nextWord.equals("c")) {\r
+                //'c' stands for a channel connection line. example:\r
+                //c filterchannel 8 o filter 0x23c738 i filter 0x23c6e8\r
+                String channelName = tokenizer.nextToken();\r
+                int capacity = Integer.parseInt(\r
+                        tokenizer.nextToken());\r
+                String portAType = tokenizer.nextToken();\r
+                String processAName = tokenizer.nextToken();\r
+                String portAName = tokenizer.nextToken();\r
+                String portBType = tokenizer.nextToken();\r
+                String processBName = tokenizer.nextToken();\r
+                String portBName = tokenizer.nextToken();\r
+                addChannelProfile(channelName, capacity,\r
+                        portAType, processAName, portAName,\r
+                        portBType, processBName, portBName);\r
+            } else {\r
+                //current line is an event. examples:\r
+                //examples:\r
+                //78 filter started.\r
+                //79 filter r 0x23c6c0 8\r
+                //80 filter w 0x23c738 8\r
+                //81 filter stopped.\r
+\r
+                int i = Integer.parseInt(nextWord);\r
+                if (i != _lineCounter) {\r
+                    System.err.println("Input file corrupt: line number "\r
+                            + "expected.");\r
+                    return;\r
+                }\r
+\r
+                //get process name\r
+                String processName = tokenizer.nextToken();\r
+                if (_processProfiles.get(processName) == null) {\r
+                    ProcessProfile processProfile = new ProcessProfile(\r
+                            processName);\r
+                    _processProfiles.put(processName, processProfile);\r
+                }\r
+                if(_processCommOrder.get(processName) == null) {\r
+                    _processCommOrder.put(processName, new Vector<String>());\r
+                }\r
+\r
+                nextWord = tokenizer.nextToken();\r
+                if(nextWord.equals("started.")) {\r
+                    _processProfiles.get(processName).start();\r
+                }\r
+                else if(nextWord.equals("stopped.")) {\r
+                    _processProfiles.get(processName).stop();\r
+                }\r
+                else if (nextWord.equals("r") || nextWord.equals("w")) {\r
+                    String accessType = nextWord;\r
+                    String portName = tokenizer.nextToken();\r
+                    int amount = Integer.parseInt(\r
+                            tokenizer.nextToken());\r
+                    try {\r
+                        _processProfiles.get(processName).\r
+                                portAccess(portName, amount);\r
+                        if (accessType.equals("r")) {\r
+                            String channelName =\r
+                                _inPortToChannelMapping.get(portName);\r
+                            _channelProfiles.get(channelName).\r
+                                    readAccess(amount);\r
+                            _processCommOrder.get(processName).add(channelName);\r
+\r
+                        } else {\r
+                            String channelName =\r
+                                _outPortToChannelMapping.get(portName);\r
+                            _channelProfiles.get(channelName).\r
+                                    writeAccess(amount);\r
+                            _processCommOrder.get(processName).add(channelName);\r
+                        }\r
+                    } catch (NullPointerException e) {\r
+                        System.err.println("Input file corrupt: cannot "\r
+                                + "find channel associated to port "\r
+                                + portName + "(line "\r
+                                + _lineCounter + ").");\r
+                        e.printStackTrace();\r
+                        return;\r
+                    }\r
+                } else {\r
+                    System.err.println("Input file corrupt: unknown "\r
+                            + "event type (line " + _lineCounter + ").");\r
+                    return;\r
+                }\r
+                _lineCounter++;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Return the profiles of all processes.\r
+     *\r
+     *  @return profile of all processes\r
+     */\r
+    public HashMap<String, ProcessProfile> getProcessProfiles() {\r
+        return _processProfiles;\r
+    }\r
+\r
+    /**\r
+     * Return the profiles of all channels.\r
+     *\r
+     *  @return profile of all channels\r
+     */\r
+    public HashMap<String, ChannelProfile> getChannelProfiles() {\r
+        return _channelProfiles;\r
+    }\r
+\r
+    /**\r
+     * Return the order in which processes write to channels.\r
+     *\r
+     *  @return profile of all processes\r
+     */\r
+    public HashMap<String, Vector<String>> getProcessCommOrder() {\r
+        return _processCommOrder;\r
+    }\r
+\r
+    /**\r
+     * Return the channel to which the port with the specified name is\r
+     * connected.\r
+     *\r
+     * @param port port name\r
+     * @return name of connected channel\r
+     */\r
+    public String getChannel(String port) {\r
+        if (_inPortToChannelMapping.get(port) != null) {\r
+            return _inPortToChannelMapping.get(port);\r
+        } else if (_outPortToChannelMapping.get(port) != null) {\r
+            return _outPortToChannelMapping.get(port);\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Return the type of the channel with the specified name.\r
+     *\r
+     * @param port port name\r
+     * @return type of port\r
+     */\r
+    public String getPortType(String port) {\r
+        if (_inPortToChannelMapping.get(port) != null) {\r
+            return "INPUT";\r
+        } else if (_outPortToChannelMapping.get(port) != null) {\r
+            return "OUTPUT";\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Add a channel profile to the HashMap of channel profiles.\r
+     *\r
+     * @param channelName name of the channel\r
+     * @param capacity capacity of the channel\r
+     * @param portAType type of first port (either "o" or "i")\r
+     * @param processAName name of process connected to first port\r
+     * @param portAName name of first port\r
+     * @param portBType type of second port (either "o" or "i")\r
+     * @param processBName name of process connected to second port\r
+     * @param portBName name of second port\r
+     */\r
+    protected void addChannelProfile(String channelName, int capacity,\r
+            String portAType, String processAName, String portAName,\r
+            String portBType, String processBName, String portBName) {\r
+\r
+        ChannelProfile channelProfile =\r
+            new ChannelProfile(channelName, capacity);\r
+        _channelProfiles.put(channelName, channelProfile);\r
+\r
+        if (portAType.equals("o")) {\r
+            //first output port, then input port\r
+            _outPortToChannelMapping.put(portAName, channelName);\r
+            if (!(portBType.equals("i"))) {\r
+                System.err.println("Input file corrupt: each "\r
+                        + "channel needs one input- and one "\r
+                        + "output port.");\r
+                return;\r
+            }\r
+            _inPortToChannelMapping.put(portBName, channelName);\r
+        } else if (portAType.equals("i")) {\r
+            //first input port, then output port\r
+            _inPortToChannelMapping.put(portAName, channelName);\r
+            if (!(portBType.equals("o"))) {\r
+                System.err.println("Input file corrupt: each "\r
+                        + "channel needs one input- and one "\r
+                        + "output port.");\r
+                return;\r
+            }\r
+            _outPortToChannelMapping.put(portBName, channelName);\r
+        } else {\r
+            System.err.println("Input file corrupt: bad channel "\r
+                    + "specification:");\r
+            System.err.println(channelName + " " + capacity + " "\r
+                    + portAType + " " + processAName + " " + portAName\r
+                    + " "\r
+                    + portBType + " " + processBName + " " + portBName);\r
+        }\r
+    }\r
+\r
+    private BufferedReader _in = null;\r
+    protected int _lineCounter = 0;\r
+    HashMap<String, ProcessProfile> _processProfiles;\r
+    HashMap<String, ChannelProfile> _channelProfiles;\r
+    HashMap<String, String> _inPortToChannelMapping;\r
+    HashMap<String, String> _outPortToChannelMapping;\r
+    HashMap<String, Vector<String>> _processCommOrder;\r
+}\r