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 }