001    package org.shiftone.jrat.core;
002    
003    
004    import org.shiftone.jrat.util.log.Logger;
005    
006    import java.io.Serializable;
007    
008    
009    /**
010     * @author jeff@shiftone.org (Jeff Drost)
011     */
012    public class Accumulator implements Serializable {
013    
014        private static final Logger LOG = Logger.getLogger(Accumulator.class);
015        private static final long serialVersionUID = 1;
016        private long totalEnters = 0;
017        private long totalExits = 0;
018        private long totalErrors = 0;
019        private long totalDuration = 0;    // used for mean
020        private long sumOfSquares = 0;    // used for std dev
021        private long maxDuration = Long.MIN_VALUE;
022        private long minDuration = Long.MAX_VALUE;
023        private int concurThreads = 0;
024        private int maxConcurrentThreads = 0;
025    
026        public Accumulator() {
027        }
028    
029        public Accumulator(long totalEnters,
030                           long totalExits,
031                           long totalErrors,
032                           long totalDuration,
033                           long totalOfSquares,
034                           long maxDuration,
035                           long minDuration,
036                           int maxConcurThreads) {
037            setStatistics(totalEnters, totalExits, totalErrors, totalDuration,    //
038                    totalOfSquares, maxDuration, minDuration, maxConcurThreads);
039        }
040    
041        public void setStatistics(long totalEnters,
042                                  long totalExits,
043                                  long totalErrors,
044                                  long totalDuration,
045                                  long totalOfSquares,
046                                  long maxDuration,
047                                  long minDuration,
048                                  int maxConcurThreads) {
049    
050            this.totalEnters = totalEnters;
051            this.totalExits = totalExits;
052            this.totalErrors = totalErrors;
053            this.totalDuration = totalDuration;
054            this.sumOfSquares = totalOfSquares;
055            this.maxDuration = maxDuration;
056            this.minDuration = minDuration;
057            this.maxConcurrentThreads = maxConcurThreads;
058        }
059    
060        /**
061         * this method takes two Accumulators and smashes them together to column a
062         * third.
063         */
064        public void combine(Accumulator accumulator) {
065    
066            this.totalEnters = this.totalEnters + accumulator.totalEnters;
067            this.totalExits = this.totalExits + accumulator.totalExits;
068            this.totalErrors = this.totalErrors + accumulator.totalErrors;
069            this.totalDuration = this.totalDuration + accumulator.totalDuration;
070            this.sumOfSquares = this.sumOfSquares + accumulator.sumOfSquares;
071            this.maxDuration = Math.max(this.maxDuration, accumulator.maxDuration);
072            this.minDuration = Math.min(this.minDuration, accumulator.minDuration);
073            this.concurThreads = this.concurThreads + accumulator.concurThreads;
074            this.maxConcurrentThreads = Math.max(this.maxConcurrentThreads, accumulator.maxConcurrentThreads);
075        }
076    
077        public synchronized void reset() {
078    
079            this.totalEnters = 0;
080            this.totalExits = 0;
081            this.totalErrors = 0;
082            this.totalDuration = 0;
083            this.sumOfSquares = 0;
084            this.maxDuration = 0;
085            this.minDuration = 0;
086            //this.concurThreads    = this.concurThreads ;
087            this.maxConcurrentThreads = this.concurThreads;
088        }
089    
090        public final synchronized void onMethodStart() {
091    
092            totalEnters++;
093            concurThreads++;
094    
095            if (concurThreads > maxConcurrentThreads) {
096                maxConcurrentThreads = concurThreads;
097            }
098        }
099    
100        public final synchronized void onMethodFinish(long durationMs, boolean success) {
101    
102            totalExits++;
103    
104            totalDuration += durationMs;
105            sumOfSquares += (durationMs * durationMs);
106    
107            if (!success) {
108                totalErrors++;
109            }
110    
111            if (durationMs < minDuration) {
112                minDuration = durationMs;
113            }
114    
115            if (durationMs > maxDuration) {
116                maxDuration = durationMs;
117            }
118    
119            concurThreads--;
120        }
121    
122        public final Double getAverageDuration() {
123    
124            Double average = null;
125    
126            if (totalExits > 0) {
127                average = new Double((double) totalDuration / (double) totalExits);
128            }
129    
130            return average;
131        }
132    
133        public final Double getStdDeviation() {
134    
135            Double stdDeviation = null;
136    
137            if (totalExits > 1) {
138                double numerator = sumOfSquares - ((double) (totalDuration * totalDuration) / (double) totalExits);
139                double denominator = totalExits - 1.0;
140    
141                stdDeviation = new Double(Math.sqrt(numerator / denominator));
142            }
143    
144            return stdDeviation;
145        }
146    
147        public long getTotalDuration() {
148            return totalDuration;
149        }
150    
151        public int getMaxConcurrentThreads() {
152            return maxConcurrentThreads;
153        }
154    
155        public long getSumOfSquares() {
156            return sumOfSquares;
157        }
158    
159        public final int getConcurrentThreads() {
160            return concurThreads;
161        }
162    
163        public long getTotalErrors() {
164            return totalErrors;
165        }
166    
167        public final long getTotalEnters() {
168            return totalEnters;
169        }
170    
171        public final long getTotalExits() {
172            return totalExits;
173        }
174    
175        public final long getMinDuration() {
176            return minDuration;
177        }
178    
179        public final long getMaxDuration() {
180            return maxDuration;
181        }
182    }