001: package org.columba.core.util;
002:
003: import java.util.Hashtable;
004: import java.util.Iterator;
005: import java.util.Vector;
006:
007: import org.columba.core.logging.Logging;
008:
009: public class StackProfiler {
010:
011: private static final java.util.logging.Logger LOG = java.util.logging.Logger
012: .getLogger("org.columba.core.util"); //$NON-NLS-1$
013:
014: /**
015: * keeps a list of profile point ids
016: */
017: private Vector vector = new Vector();
018:
019: /**
020: * key is the id, value is the profile data
021: */
022: private Hashtable hashtable = new Hashtable();
023:
024: /**
025: * current path in simple tree-like hierarchy
026: */
027: private String currentPath = "";
028:
029: /**
030: * Set new profiling starting point. This is where the time measurment
031: * actually starts.
032: *
033: * @param id
034: * unique id of profiling point
035: */
036: public void push(String id) {
037: // abort if not in debugging mode
038: if (Logging.DEBUG == false)
039: return;
040:
041: // current time
042: long currentTime = System.currentTimeMillis();
043:
044: // store profiling point data
045: hashtable.put(id, new ProfileData(id, currentPath, new Long(
046: currentTime).longValue()));
047:
048: // this profiling point is parent of the next one
049: currentPath = currentPath + "/" + id;
050:
051: // store id
052: vector.add(id);
053: }
054:
055: /**
056: * Close profiling point. This is where the time measurement actually ends.
057: *
058: * @param id
059: * unique id of profiling point
060: */
061: public void pop(String id) {
062: System.out.println("id=" + id);
063: // abort if not in debugging mode
064: if (Logging.DEBUG == false)
065: return;
066:
067: if (id == null)
068: throw new IllegalArgumentException("id == null");
069:
070: if (hashtable.containsKey(id) == false)
071: throw new IllegalArgumentException("id=" + id
072: + " not found");
073:
074: long currentTime = System.currentTimeMillis();
075:
076: ProfileData bean = (ProfileData) hashtable.get(id);
077: bean.endTime = currentTime;
078:
079: String firstItem = (String) vector.get(0);
080: if (firstItem.equals(id)) {
081: // print all collected profile data
082:
083: LOG.info("profiler info:"); //$NON-NLS-1$
084: Iterator it = vector.listIterator();
085:
086: while (it.hasNext()) {
087: String nextId = (String) it.next();
088: printDuration(nextId);
089: }
090: } else {
091: // current path is the parent of the current element
092: int index = currentPath.lastIndexOf("/");
093: currentPath = currentPath.substring(0, index);
094: }
095: }
096:
097: /**
098: * Print debug data.
099: *
100: * @param id
101: * unique profiling point id
102: */
103: private void printDuration(String id) {
104: if (id == null)
105: throw new IllegalArgumentException("id == null");
106: if (hashtable.containsKey(id) == false)
107: throw new IllegalArgumentException("id not found");
108:
109: ProfileData bean = (ProfileData) hashtable.get(id);
110: String splits[] = bean.path.split("/");
111:
112: for (int i = 0; i < splits.length; i++)
113: System.out.print(" ");
114:
115: long duration = bean.endTime - bean.startTime;
116: LOG.info("[" + duration + "ms] - " + id); //$NON-NLS-2$
117: }
118:
119: /**
120: * Structure containing profiling data.
121: */
122: private class ProfileData {
123: protected String id;
124:
125: protected String path;
126:
127: protected long startTime;
128:
129: protected long endTime;
130:
131: protected ProfileData(String id, String path, long startTime) {
132: this.id = id;
133: this.path = path;
134: this.startTime = startTime;
135: }
136:
137: }
138: }
|