View Javadoc

1   /* ==========================================
2    * JperfProbe : Java Performance Probes
3    * ==========================================
4    *
5    * Project Info:  http://jperfprobe.sourceforge.net/
6    * Project Lead:  Tor-Erik Larsen (http://sourceforge.net/users/uptime62)
7    *
8    * (C) Copyright 2005, by Tor-Erik Larsen and Contributors.
9    *
10   * This library is free software; you can redistribute it and/or modify it
11   * under the terms of the GNU Lesser General Public License as published by
12   * the Free Software Foundation; either version 2.1 of the License, or
13   * (at your option) any later version.
14   *
15   * This library is distributed in the hope that it will be useful, but
16   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17   * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18   * License for more details.
19   *
20   * You should have received a copy of the GNU Lesser General Public License
21   * along with this library; if not, write to the Free Software Foundation, Inc.,
22   * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
23   */
24  
25  package net.sf.jperfprobe;
26  
27  import org.slf4j.*;
28  
29  import java.io.*;
30  import java.util.*;
31  
32  
33  /**
34   * Class Result.
35   * A Result contains the statistics. All calculations are done in this class.
36   * There can be multiple probes in a Result identified by the Probes threadname.
37   *
38   * @author Tor-Erik Larsen
39   *         Date: 01.feb.2007
40   *         Time: 10:48:56
41   */
42  public class Result implements Serializable {
43      final Logger log = LoggerFactory.getLogger(Result.class);
44  
45      private int samplesToSkip;
46  
47      private int currentSamplesSkip;
48      /**
49       * default maximum number of samples stored in a probe.
50       */
51      static int DEFAULT_MAXSAMPLES = 300;
52      // list of the last max samples, the oldest samples will be removed.
53      private long[] samples = new long[DEFAULT_MAXSAMPLES];
54  
55      final transient private Map<String, Probe> probeMap = new HashMap<String, Probe>();
56  
57      // current number of samples in this probe.
58      private int nSamples;
59  
60      // index of the current sample
61      private int sampleIndex;
62  
63      // maximum registered time sample in probe.
64      private double max;
65  
66      // minimum registered time sample in probe.
67      private double min;
68  
69      // average time calculated in this probe, based on all recorded samples, even the discarded ones,
70      // more than DEFAULT_MAXSAMPLES.
71      private double average;
72  
73      // name of Result.
74      private final String name;
75  
76      private long lastSample;
77  
78      private Probe singleProbe;
79  
80      private long total;
81  
82      private double squareSum;
83  
84  
85      Result(String name) {
86          this.name = name;
87      }
88  
89      Result(int nSkip, String name) {
90          this.samplesToSkip = nSkip;
91          this.name = name;
92      }
93  
94      public long[] getSamples() {
95          long[] dest = new long[sampleIndex];
96          System.arraycopy(samples, 0, dest, 0, sampleIndex);
97  
98          return dest;
99      }
100 
101     public int getNSamples() {
102         return nSamples;
103     }
104 
105     /*
106     int getSampleIndex() {
107         return sampleIndex;
108     }
109     */
110 
111     public double getMax() {
112         return max;
113     }
114 
115     public double getMin() {
116         return min;
117 
118     }
119 
120     public double getAverage() {
121         return average;
122     }
123 
124     /**
125      * Get the sample standard deviation
126      *
127      * @return
128      */
129     public double getStdev() {
130         double nMinus1 = (nSamples <= 1) ? 1 : nSamples - 1;
131         double numerator = squareSum - ((total * total) / nSamples);
132 
133         return java.lang.Math.sqrt(numerator / nMinus1);
134     }
135 
136     /**
137      * Get the probe for the calling thread
138      * @return
139      */
140     Probe getProbe() {
141         return probeMap.get(Thread.currentThread().getName());
142     }
143 
144 
145     /**
146      * Add a probe to Result
147      *
148      * @param probe
149      */
150     void addprobe(Probe probe) {
151         synchronized (probeMap) {
152             probeMap.put(Thread.currentThread().getName(), probe);
153         }
154     }
155 
156     /**
157      * Clear the map of probes and all values (max, min, samples, average...) all the probes will be removed
158      */
159     public void clear() {
160         probeMap.clear();
161         max = 0.0;
162         min = 0.0;
163         sampleIndex = 0;
164         nSamples = 0;
165         average = 0.0;
166         samples = new long[DEFAULT_MAXSAMPLES];
167         total = 0;
168 
169     }
170 
171     public void disable() {
172         for (Probe p : probeMap.values()) {
173             p.disable();
174         }
175     }
176 
177     public void enable() {
178         for (Probe p : probeMap.values()) {
179             p.enable();
180         }
181     }
182 
183 
184     public String getName() {
185         return name;
186     }
187 
188     /*
189     public void addSample(Probe p) {
190         addSample(p.getElapsed());
191     }
192     */
193 
194     /**
195      * Add a sample to the probe, and recalculate the average & min/max values.
196      *
197      * @param time sample to add
198      */
199     public void addSample(long time) {
200         if (currentSamplesSkip < samplesToSkip) {
201             currentSamplesSkip++;
202         } else {
203             lastSample = time;
204             if (sampleIndex >= DEFAULT_MAXSAMPLES) {
205                 // rollover
206                 sampleIndex = 0;
207             }
208 
209             samples[sampleIndex++] = time;
210             total += time;
211             average = (average * (double) nSamples + (double) time) / (double) ++nSamples;
212             squareSum += time * time;
213 
214             if (time > max) {
215                 max = time;
216             }
217             if (nSamples > 1) {
218                 if (time < min) {
219                     min = time;
220                 }
221             } else {
222                 min = time;
223             }
224         }
225     }
226 
227     /**
228      * Get the singleprobe, there is then only one instance of a probe
229      *
230      * @return
231      */
232     public Probe getSingleProbe() {
233         return singleProbe;
234     }
235 
236     public void setSingleProbe(Probe singleProbe) {
237         this.singleProbe = singleProbe;
238     }
239 
240     /**
241      * Get the last sample from the probe
242      *
243      * @return
244      */
245     public long getLastSample() {
246         return lastSample;
247     }
248 
249     public long getTotal() {
250         return total;
251     }
252 
253     /**
254      * Get all info from result to string
255      *
256      * @return string with all result info
257      */
258     @Override
259     public String toString() {
260         return "probe name=" + name + ", #samples=" + nSamples + " , average=" + average + " , stdev=" + getStdev() + " ,max=" + max + " , min=" + min;
261     }
262 }