1 // ========================================================================
2 // Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
3 // ------------------------------------------------------------------------
4 // All rights reserved. This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v1.0
6 // and Apache License v2.0 which accompanies this distribution.
7 // The Eclipse Public License is available at
8 // http://www.eclipse.org/legal/epl-v10.html
9 // The Apache License v2.0 is available at
10 // http://www.opensource.org/licenses/apache2.0.php
11 // You may elect to redistribute this code under either of these licenses.
12 // ========================================================================
13
14 package org.eclipse.jetty.util.statistic;
15
16 import java.util.concurrent.atomic.AtomicLong;
17
18
19 /* ------------------------------------------------------------ */
20 /**
21 * SampledStatistics
22 * <p>
23 * Provides max, total, mean, count, variance, and standard
24 * deviation of continuous sequence of samples.
25 * <p>
26 * Calculates estimates of mean, variance, and standard deviation
27 * characteristics of a sample using a non synchronized
28 * approximation of the on-line algorithm presented
29 * in Donald Knuth's Art of Computer Programming, Volume 2,
30 * Seminumerical Algorithms, 3rd edition, page 232,
31 * Boston: Addison-Wesley. that cites a 1962 paper by B.P. Welford
32 * that can be found by following the link http://www.jstor.org/pss/1266577
33 * <p>
34 * This algorithm is also described in Wikipedia at
35 * http://en.wikipedia.org/w/index.php?title=Algorithms_for_calculating_variance§ion=4#On-line_algorithm
36 */
37 public class SampleStatistic
38 {
39 protected final AtomicLong _max = new AtomicLong();
40 protected final AtomicLong _total = new AtomicLong();
41 protected final AtomicLong _count = new AtomicLong();
42 protected final AtomicLong _totalVariance100 = new AtomicLong();
43
44 public void reset()
45 {
46 _max.set(0);
47 _total.set(0);
48 _count.set(0);
49 _totalVariance100.set(0);
50 }
51
52 public void set(final long sample)
53 {
54 long total = _total.addAndGet(sample);
55 long count = _count.incrementAndGet();
56
57 if (count>1)
58 {
59 long mean10 = total*10/count;
60 long delta10 = sample*10 - mean10;
61 _totalVariance100.addAndGet(delta10*delta10);
62 }
63
64 long oldMax = _max.get();
65 while (sample > oldMax)
66 {
67 if (_max.compareAndSet(oldMax, sample))
68 break;
69 oldMax = _max.get();
70 }
71
72 }
73
74 /* ------------------------------------------------------------ */
75 /**
76 * @return the max value
77 */
78 public long getMax()
79 {
80 return _max.get();
81 }
82
83 /* ------------------------------------------------------------ */
84 public long getTotal()
85 {
86 return _total.get();
87 }
88
89 /* ------------------------------------------------------------ */
90 public long getCount()
91 {
92 return _count.get();
93 }
94
95 /* ------------------------------------------------------------ */
96 public double getMean()
97 {
98 return (double)_total.get()/_count.get();
99 }
100
101 /* ------------------------------------------------------------ */
102 public double getVariance()
103 {
104 final long variance100 = _totalVariance100.get();
105 final long count = _count.get();
106
107 return count>1?((double)variance100)/100.0/(count-1):0.0;
108 }
109
110 /* ------------------------------------------------------------ */
111 public double getStdDev()
112 {
113 return Math.sqrt(getVariance());
114 }
115
116 }