001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.async.impl;
005:
006: import com.tc.async.api.StageMonitor;
007: import com.tc.text.StringFormatter;
008:
009: import java.util.ArrayList;
010: import java.util.Iterator;
011: import java.util.List;
012:
013: class StageMonitorImpl implements StageMonitor {
014:
015: private final String name;
016: private final StringFormatter formatter;
017:
018: private final List snapshots = new ArrayList();
019: private long begin = System.currentTimeMillis();
020:
021: StageMonitorImpl(String name, StringFormatter formatter) {
022: this .name = formatter.rightPad(30, name);
023: this .formatter = formatter;
024: }
025:
026: public synchronized void eventBegin(int queueDepth) {
027: snapshots.add(new Snapshot(queueDepth));
028: }
029:
030: public synchronized String dumpAndFlush() {
031: long elapsed = System.currentTimeMillis() - begin;
032: StringBuffer rv = new StringBuffer();
033: dump(elapsed, rv);
034: flush();
035: return rv.toString();
036: }
037:
038: private StringBuffer dump(long elapsed, StringBuffer buf) {
039: Analysis an = analyze();
040: buf.append(name).append("| period: ").append(
041: formatter.leftPad(10, an.getElapsedTime())).append(
042: "ms.| events: ").append(
043: formatter.leftPad(10, an.getEventCount()));
044:
045: buf.append("| events/sec: ").append(
046: formatter.leftPad(10, an.getEventsPerSecond()));
047:
048: buf.append("| Q depth, min: ").append(
049: formatter.leftPad(10, an.getMinQueueDepth()));
050: buf.append(", max: ").append(
051: formatter.leftPad(10, an.getMaxQueueDepth()));
052: buf.append(", avg: ").append(
053: formatter.leftPad(10, an.getAvgQueueDepth()));
054:
055: return buf;
056: }
057:
058: // XXX: Yeah, I know this is dumb.
059: private Double safeDiv(long numerator, long denominator) {
060: if (denominator > 0) {
061: return new Double(((double) numerator)
062: / ((double) denominator));
063: } else {
064: return new Double(-1);
065: }
066: }
067:
068: public synchronized Analysis analyze() {
069: long elapsed = System.currentTimeMillis() - begin;
070: int min = -1, max = 0;
071: long sum = 0;
072: for (Iterator i = snapshots.iterator(); i.hasNext();) {
073: int qd = ((Snapshot) i.next()).getQueueDepth();
074: if (qd < min || min < 0)
075: min = qd;
076: if (qd > max)
077: max = qd;
078: sum += qd;
079: }
080:
081: return new AnalysisImpl(new Long(elapsed), new Integer(
082: snapshots.size()), safeDiv(snapshots.size() * 1000,
083: elapsed), new Integer(min), new Integer(max), safeDiv(
084: sum, snapshots.size()));
085: }
086:
087: public synchronized void flush() {
088: snapshots.clear();
089: begin = System.currentTimeMillis();
090: }
091:
092: public static class AnalysisImpl implements Analysis {
093: private final Number eventCount;
094: private final Number eventsPerSecond;
095: private final Number minQueueDepth;
096: private final Number maxQueueDepth;
097: private final Number avgQueueDepth;
098: private final Number elapsedTime;
099:
100: private AnalysisImpl(Number elapsedTime, Number eventCount,
101: Number eventsPerSecond, Number minQueueDepth,
102: Number maxQueueDepth, Number avgQueueDepth) {
103: this .elapsedTime = elapsedTime;
104: this .eventCount = eventCount;
105: this .eventsPerSecond = eventsPerSecond;
106: this .minQueueDepth = minQueueDepth;
107: this .maxQueueDepth = maxQueueDepth;
108: this .avgQueueDepth = avgQueueDepth;
109: }
110:
111: public Number getElapsedTime() {
112: return elapsedTime;
113: }
114:
115: public Number getAvgQueueDepth() {
116: return avgQueueDepth;
117: }
118:
119: public Number getMaxQueueDepth() {
120: return maxQueueDepth;
121: }
122:
123: public Number getMinQueueDepth() {
124: return minQueueDepth;
125: }
126:
127: public Number getEventsPerSecond() {
128: return eventsPerSecond;
129: }
130:
131: public Number getEventCount() {
132: return eventCount;
133: }
134:
135: }
136:
137: private static class Snapshot {
138: private final int queueDepth;
139:
140: private Snapshot(int queueDepth) {
141: this .queueDepth = queueDepth;
142: }
143:
144: public int getQueueDepth() {
145: return queueDepth;
146: }
147: }
148: }
|