001: /*
002: * Created on 08.06.2005
003: *
004: */
005: package de.schlund.pfixxml.perflogging;
006:
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Map;
011:
012: /**
013: * @author jh
014: *
015: */
016: public class PerfStatistic {
017: private Map<String, Map<String, int[]>> category_map = new HashMap<String, Map<String, int[]>>();
018:
019: private static PerfStatistic instance = new PerfStatistic();
020:
021: static PerfStatistic getInstance() {
022: return instance;
023: }
024:
025: private int[] createCount(int size) {
026: int[] count = new int[size];
027: return count;
028: }
029:
030: synchronized void reset() {
031: category_map = new HashMap<String, Map<String, int[]>>();
032: }
033:
034: /**
035: * @param pe
036: */
037: synchronized void process(PerfEvent pe) {
038:
039: List<Interval> intervals = IntervalFactory.getInstance()
040: .getIntervalForCategory(pe.getCategory());
041:
042: if (!category_map.containsKey(pe.getCategory())) {
043: category_map.put(pe.getCategory(),
044: new HashMap<String, int[]>());
045: }
046:
047: Map<String, int[]> identity_map = category_map.get(pe
048: .getCategory());
049:
050: if (!identity_map.containsKey(pe.getIdentifier())) {
051: int[] c = createCount(intervals.size());
052: identity_map.put(pe.getIdentifier(), c);
053: }
054:
055: int[] count = identity_map.get(pe.getIdentifier());
056: int index = search(pe.getDuration(), intervals);
057: count[index]++;
058: }
059:
060: synchronized String toXML() {
061: StringBuffer sb = new StringBuffer(1024);
062: if (category_map.isEmpty())
063: return "";
064:
065: Formatter v = new XMLFormatter();
066: format(sb, v);
067:
068: return sb.toString();
069: }
070:
071: synchronized String toLogfilePresentation() {
072: StringBuffer sb = new StringBuffer(1024);
073: if (category_map.isEmpty())
074: return "";
075:
076: Formatter v = new StringFormatter();
077: format(sb, v);
078:
079: return sb.toString();
080: }
081:
082: synchronized Map<String, Map<String, int[]>> toMap() {
083: if (category_map.isEmpty())
084: return null;
085: return category_map;
086: }
087:
088: /**
089: * @param sb
090: */
091: private void format(StringBuffer sb, Formatter v) {
092: v.printHeader(sb);
093: for (Iterator<String> i = category_map.keySet().iterator(); i
094: .hasNext();) {
095: String category = (String) i.next();
096: v.categoryStart(sb, category);
097: Map<String, int[]> identity_map = category_map
098: .get(category);
099: for (Iterator<String> j = identity_map.keySet().iterator(); j
100: .hasNext();) {
101: String identfier = (String) j.next();
102: int[] cc = (int[]) identity_map.get(identfier);
103: List<Interval> intervals = IntervalFactory
104: .getInstance().getIntervalForCategory(category);
105:
106: int count = 0;
107: int total = getTotal(category, identfier);
108:
109: v.identfierStart(sb, identfier, total);
110:
111: for (Iterator<Interval> k = intervals.iterator(); k
112: .hasNext();) {
113: Interval interval = (Interval) k.next();
114: // if(cc[count] > 0) {
115: int per = getPercent(cc, count, total);
116: v.formatCountElement(sb, cc, count, interval, per);
117: // }
118: count++;
119: }
120: v.identierEnd(sb);
121: }
122: v.catgeoryStop(sb);
123: }
124: v.printFooter(sb);
125:
126: }
127:
128: /**
129: * @param cc
130: * @param count
131: * @param total
132: * @return
133: */
134: private int getPercent(int[] cc, int count, int total) {
135: int per = total == 0 ? total : (cc[count] * 100 / total);
136: return per;
137: }
138:
139: private int getTotal(String category, String ident) {
140: Map<String, int[]> identity_map = category_map.get(category);
141: int[] cc = (int[]) identity_map.get(ident);
142: List<Interval> intervals = IntervalFactory.getInstance()
143: .getIntervalForCategory(category);
144: int count = 0;
145: int total = 0;
146: for (Iterator<Interval> k = intervals.iterator(); k.hasNext(); k
147: .next()) {
148: if (cc[count] > 0) {
149: total += cc[count];
150: }
151: count++;
152: }
153: return total;
154: }
155:
156: String toStr() {
157: return category_map.toString();
158: }
159:
160: private int search(long time, List<Interval> intervals) {
161: boolean success = false;
162: int first = 0;
163: int last = intervals.size();
164: int middle = 0;
165: int index = 0;
166:
167: if (time >= Long.MAX_VALUE) {
168: time = Long.MAX_VALUE - 1;
169: }
170:
171: while (!success && first <= last) {
172:
173: middle = (first + last) / 2;
174: /*System.out.println("Middle=" + middle + " first=" + first
175: + ", last=" + last + ", time=" + time);*/
176:
177: Interval midd = (Interval) intervals.get(middle);
178: if (midd.contains(time)) {
179: index = middle;
180: success = true;
181: break;
182: }
183:
184: // search left
185: if (midd.isLess(time)) {
186: last = middle - 1;
187: }
188: // search right
189: if (midd.isGreater(time)) {
190: first = middle + 1;
191: }
192:
193: }
194: return index;
195: }
196:
197: }
198:
199: interface Formatter {
200: void printHeader(StringBuffer sb);
201:
202: void printFooter(StringBuffer sb);
203:
204: void formatCountElement(StringBuffer sb, int[] cc, int count,
205: Interval interval, int per);
206:
207: void identfierStart(StringBuffer sb, String id, int total);
208:
209: void identierEnd(StringBuffer sb);
210:
211: void categoryStart(StringBuffer sb, String category);
212:
213: void catgeoryStop(StringBuffer sb);
214: }
215:
216: class StringFormatter implements Formatter {
217:
218: public void printHeader(StringBuffer sb) {
219: sb.append("\n----------------------------------------------");
220: sb.append("\n*** Performance ***").append("\n");
221: }
222:
223: public void formatCountElement(StringBuffer sb, int[] cc,
224: int count, Interval interval, int per) {
225: sb.append(
226: "\t\t[" + interval.getFrom() + "-"
227: + interval.getUntil() + "]" + "=>" + cc[count]
228: + "|" + per).append("\n");
229: }
230:
231: public void identfierStart(StringBuffer sb, String identifier,
232: int total) {
233: sb.append("\t" + identifier + "[" + total + "]" + ":");
234: }
235:
236: public void categoryStart(StringBuffer sb, String category) {
237: sb.append(category);
238: }
239:
240: public void identierEnd(StringBuffer sb) {
241: sb.append("\n");
242: }
243:
244: public void catgeoryStop(StringBuffer sb) {
245: sb.append("\n");
246: }
247:
248: public void printFooter(StringBuffer sb) {
249: sb.append("----------------------------------------------\n");
250: }
251: }
252:
253: class XMLFormatter implements Formatter {
254:
255: public void printHeader(StringBuffer sb) {
256: sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
257: sb.append("<perf>").append("\n");
258: sb.append("<status>").append("\n");
259: sb.append("<enabled>").append(
260: PerfLogging.getInstance().isPerfLogggingEnabled())
261: .append("</enabled>").append("\n");
262: sb.append("<active>").append(
263: PerfLogging.getInstance().isPerfLoggingActive())
264: .append("</active>").append("\n");
265:
266: sb.append("</status>").append("\n");
267: }
268:
269: public void printFooter(StringBuffer sb) {
270: sb.append("</perf>").append("\n");
271: }
272:
273: public void formatCountElement(StringBuffer sb, int[] cc,
274: int count, Interval interval, int per) {
275: sb.append(
276: "<count from=\"" + interval.getFrom() + "\" to=\""
277: + interval.getUntil() + "\" per=\"" + per
278: + "\">" + cc[count++] + "</count>")
279: .append("\n");
280: }
281:
282: public void identfierStart(StringBuffer sb, String id, int total) {
283: sb.append("<id name=\"" + id + "\" total=\"" + total + "\">")
284: .append("\n");
285: }
286:
287: public void identierEnd(StringBuffer sb) {
288: sb.append("</id>").append("\n");
289: }
290:
291: public void categoryStart(StringBuffer sb, String category) {
292: sb.append("<category name=\"" + category + "\">").append("\n");
293: }
294:
295: public void catgeoryStop(StringBuffer sb) {
296: sb.append("</category>").append("\n");
297: }
298:
299: }
|