FileDocCategorySizeDatePackage
ProfView.javaAPI DocphoneME MR2 API (J2ME)88497Wed May 02 17:59:48 BST 2007None

Profile

public class Profile extends Object

Fields Summary
Hashtable
nodes
This hashtable is a collection of all CallGraphNodes in the callgraph. It's indexed by each CallGraphNode's index member, whose type is Integer.
Hashtable
nodesByName
This hashtable is a collection of all CallGraphNodes in the callgraph. It's indexed by each CallGraphNodes's name, whose type is String.

Each entry in this hashtable is either a CallGraphNodes (if only one CallGraphNode of that name exists in the callgraph), or a Vector (if two or more CallGraphNodes of that name exist in the callgraph).

CallGraphNode
root
The root of all call records. This root is artificially created. It's the parent of all the parent-less CallGraphNode read from a profile.
int
numParents
Number of CallGraphNodes in this profile that has one or more children, including this.root.
int
numFiles
Number of graph files to parse.
double
period
Duration (in msec) of the period when the profile data was collected.
Constructors Summary
Profile(String[] files)

        nodes = new Hashtable();
        nodesByName = new Hashtable();
        root = createTopNode(null, -1, "root");
        numParents = 0;
        numFiles = files.length;

        if (isMultifile()) {
            for (int i = 0; i < numFiles; i++) {
                readInputFile(new FileParserContext(files[i], i + 1, this));
            }
        } else {
            readInputFile(new FileParserContext(files[0], 0, this));
        }

        createCallGraph();

        if (numParents > 0) {
            root.endTime = period;
            root.computeSummary();
        }

        root.computePercentage();
    
Methods Summary
voidaddToIndexByName(CallGraphNode cgNode)
Add this cgNode to the index of all CallGraphNodes by its name. This index is maintained by the hashtable nodesByName

        Object obj = nodesByName.get(cgNode.name);

        //System.out.println(cgNode.name + "=" + obj);
        if (obj == null) {
            // Not in the table yet, store the cgNode itself
            nodesByName.put(cgNode.name, cgNode);
        }
        else if (obj instanceof Vector) {
            // Already has two more more cgNodes of the same name, append
            // to the list
            ((Vector)obj).addElement(cgNode);
        }
        else {
            // We've seen the second cgNode of the same name. Store both
            // cgNodes inside a Vector and put that Vector in the hashtable.
            //
            // By doing this, we only create Vector for those method names
            // that correspond to more than one CallGraphNode
            Vector v = new Vector(2);
            v.addElement(obj);
            v.addElement(cgNode);
            nodesByName.put(cgNode.name, v);
        }
    
voidcreateCallGraph()

        // Now all the CallGraphNodes are created. We're ready to
        // construct the call graph
        for (Enumeration e = nodes.elements(); e.hasMoreElements() ;) {
            CallGraphNode cgNode = (CallGraphNode)e.nextElement();

            if (cgNode.parentIdx == null) {
                // This is the root record. Do nothing
            } else {
                CallGraphNode parent;
                parent = (CallGraphNode)nodes.get(cgNode.parentIdx);
                if (parent == null) {
                    System.out.println("WARNING: no parent found for element " + 
                                       cgNode);
                    parent = root;
                }

                if (parent.children == null) {
                    parent.children = new Vector();
                    numParents ++;
                }
                parent.children.addElement(cgNode);
                cgNode.parent = parent;
            }
        }
    
CallGraphNodecreateTopNode(CallGraphNode parent, int index, java.lang.String name)

        CallGraphNode r = new CallGraphNode(parent);

        r.parent = parent;
        r.parentIdx = parent == null ? null : parent.index;
        r.index = new Integer(index);
        r.name = name;

        nodes.put(r.index, r);

        addToIndexByName(r);
        return r;
    
booleanisMultifile()

        return numFiles > 1;
    
voidprintRecord(CallGraphNode cgNode, java.lang.String prefix)

        if (cgNode.parent != null) {
            System.out.print(prefix);
            System.out.print(cgNode.name);
            System.out.print(", D=" + cgNode.depth);
            System.out.print(", K=" + cgNode.count);
            System.out.print(", C=" + cgNode.kidsCycles);
            System.out.print(", M=" + cgNode.kidsMsec);
            System.out.println();
            prefix += " ";
        }
        if (cgNode.children != null) {
            Vector v = cgNode.children;
            for (int i=0; i<v.size(); i++) {
                printRecord((CallGraphNode)v.elementAt(i), prefix);
            }
        }
    
voidreadInputFile(FileParserContext ctx)
Read the entire content of an input file

        FileReader fr = new FileReader(ctx.file);
        BufferedReader reader = new BufferedReader(fr);
        String line;

        /* Skip the first line. It's for human consumption only */
        line = reader.readLine();
        //line = reader.readLine(); /* need revisit */

        // Read all lines in the input file
        //
        while ((line = reader.readLine()) != null) {
            readInputLine(line, ctx);
        }
    
voidreadInputLine(java.lang.String line, FileParserContext ctx)

        StringTokenizer st = new StringTokenizer(line);
        if (st.countTokens() != 15) {
            return;
        }

        // Read the raw content of the input line into the CallGraphNode
        try {
            CallGraphNode cgNode;
            int index = Integer.parseInt(st.nextToken());
            if (index == -1) {
                // We also have a predefined root node in our source file -
                // so modify the existing root node
                cgNode = ctx.root;
                st.nextToken(); // parent token is meaningless for the root
            } else {
                cgNode = new CallGraphNode(ctx.root);
                cgNode.index = new Integer(ctx.indexOffset + index);
                cgNode.parentIdx = new Integer(ctx.indexOffset +
                    Integer.parseInt(st.nextToken()));
            }

            cgNode.depth = Integer.parseInt(st.nextToken());
            cgNode.name = st.nextToken();
            cgNode.count = Integer.parseInt(st.nextToken());

            cgNode.onlyCycles = Long.parseLong(st.nextToken());
            cgNode.onlyMsec   = Double.parseDouble(st.nextToken());
            cgNode.onlyPerc   = Double.parseDouble(st.nextToken());

            if (index != -1) {
                // kidsCylcles is calculated automatically for the root node
                cgNode.kidsCycles = Long.parseLong(st.nextToken());
                cgNode.kidsMsec   = Double.parseDouble(st.nextToken());
                cgNode.kidsPerc   = Double.parseDouble(st.nextToken());

                // Timeline information
                cgNode.startTime  = Double.parseDouble(st.nextToken());
                cgNode.endTime    = Double.parseDouble(st.nextToken());
                if (cgNode.endTime > period) {
                    period = cgNode.endTime;
                }

                // Store new CallGraphNode into the hashtable
                nodes.put(cgNode.index, cgNode);
                // Add it to another index table, searchable by cgNode.name
                addToIndexByName(cgNode);
            }
        } catch (NumberFormatException e) {
            // IMPL_NOTE: warning
        }