001: package com.jamonapi;
002:
003: import java.util.*;
004:
005: /** Monitor that keeps track of various timing statistics such as max, min, average, hits, total, and standard deviation.**/
006:
007: public class TimeStatsMonitor extends AccumulateMonitor {
008: private long min = Integer.MAX_VALUE;
009: private long max = Long.MIN_VALUE;
010: private int hits;
011: private long total;
012: private long sumOfSquares;
013:
014: /*
015: The std deviation caclulation that does not require keeping all data points. xi below stands for the ith
016: data point.
017:
018: required info to calculate:
019:
020: n - count of all x's
021: sum (xi^2) - must add the newest xi data point squared to this totoal each time - sumOfSquares
022: sum(xi) - must add the newest xi data point to this total each time - total
023:
024: numerator=sum(xi^2) - (sum(xi)^2)/n;
025: std_dev=square_root(numerator/(n-1));
026: */
027:
028: public TimeStatsMonitor() {
029: super ();
030: }
031:
032: public TimeStatsMonitor(AccumulateMonitorInterface childMonitor) {
033: super (childMonitor);
034: }
035:
036: /** Called when increase() is called by the stop() method. This is the method that keeps track of the various statistics being tracked
037: **/
038: synchronized protected void increaseThis(long value) {
039: // calculate min
040: if (value < min)
041: min = value;
042:
043: // calculate max
044: if (value > max)
045: max = value;
046:
047: // calculate hits i.e. n
048: hits++;
049:
050: // calculate total i.e. sumofX's
051: total += value;
052:
053: sumOfSquares += value * value;
054:
055: }
056:
057: /** Reset all variables for this object. The effect of this is to reset this objects variables to the state they were in when the object
058: * was first created.
059: **/
060: synchronized protected void resetThis() {
061: min = Long.MAX_VALUE;
062: max = Long.MIN_VALUE;
063: total = sumOfSquares = hits = 0;
064: }
065:
066: /** Make a String representation of this object. Information displayed in the string include hits, average, total, min and max **/
067: synchronized protected String toStringThis() {
068: return getDisplayString(HITS, convertToString(hits), NONE)
069: + getDisplayString(AVG, convertToString(avg()),
070: MILLISECONDS)
071: + getDisplayString(TOTAL, convertToString(total),
072: MILLISECONDS)
073: +
074: //getDisplayString(STANDARD_DEVIATION, convertToString(stdDev()), MILLISECONDS) +
075: getDisplayString(MIN, convertToString(min),
076: MILLISECONDS)
077: + getDisplayString(MAX, convertToString(max),
078: MILLISECONDS);
079: }
080:
081: private long avg() {
082: if (hits == 0)
083: return 0;
084: else
085: return total / hits;
086: }
087:
088: private long stdDev() {
089: long stdDeviation = 0;
090: if (hits != 0) {
091: long sumOfX = total;
092: int n = hits;
093: int nMinus1 = (n <= 1) ? 1 : n - 1; // avoid 0 divides;
094:
095: long numerator = sumOfSquares - ((sumOfX * sumOfX) / n);
096: stdDeviation = (long) java.lang.Math.sqrt(numerator
097: / nMinus1);
098: }
099:
100: return stdDeviation;
101: }
102:
103: synchronized protected void getDataThis(ArrayList rowData) {
104: rowData.add(convertToString(hits));
105: rowData.add(convertToString(avg()));
106: rowData.add(convertToString(total));
107: rowData.add(convertToString(stdDev()));
108: rowData.add(convertToString(min));
109: rowData.add(convertToString(max));
110:
111: }
112:
113: protected void getHeaderThis(ArrayList header) {
114: header.add(HITS + " " + NONE);
115: header.add(AVG + " " + MILLISECONDS);
116: header.add(TOTAL + " " + MILLISECONDS);
117: header.add(STANDARD_DEVIATION + " " + MILLISECONDS);
118: header.add(MIN + " " + MILLISECONDS);
119: header.add(MAX + " " + MILLISECONDS);
120: }
121:
122: /** Returned the total accrued time for this monitor **/
123: synchronized public long getAccrued() {
124: return total;
125: }
126:
127: /** The main method contains this classes test code **/
128: public static void main(String[] args) throws Exception {
129: TimeStatsMonitor mon = new TimeStatsMonitor();
130:
131: System.out.println("should not have 0 divide error=" + mon);
132: for (int i = 1; i < 5; i++)
133: mon.increase(i);
134:
135: mon.increase(100);
136:
137: System.out.println("toString()=" + mon);
138:
139: }
140: }
|