StatisticsAccumulator.java revision 672:2bb058ce572e
1/* 2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25package com.sun.corba.se.spi.monitoring; 26 27import java.util.*; 28 29/** 30 * @author Hemanth Puttaswamy 31 * 32 * StatisticsAccumulator accumulates the samples provided by the user and 33 * computes the value of minimum, maximum, sum and sample square sum. When 34 * the StatisticMonitoredAttribute calls getValue(), it will compute all 35 * the statistics for the collected samples (Which are Minimum, Maximum, 36 * Average, StandardDeviation) and provides a nice printable record as a 37 * String. 38 * 39 * Users can easily extend this class and provide the implementation of 40 * toString() method to format the stats as desired. By default all the stats 41 * are printed in a single line. 42 */ 43public class StatisticsAccumulator { 44 45 /////////////////////////////////////// 46 // attributes 47 48 49 // Users can extend this class to get access to current Max value 50 protected double max = Double.MIN_VALUE; 51 52 // Users can extend this class to get access to current Min value 53 protected double min = Double.MAX_VALUE; 54 55 private double sampleSum; 56 57 private double sampleSquareSum; 58 59 private long sampleCount; 60 61 protected String unit; 62 63 64 65 /////////////////////////////////////// 66 // operations 67 68 69 70/** 71 * User will use this method to just register a sample with the 72 * StatisticsAccumulator. This is the only method that User will use to 73 * expose the statistics, internally the StatisticMonitoredAttribute will 74 * collect the information when requested from the ASAdmin. 75 * 76 * @param value a double value to make it more precise 77 */ 78 public void sample(double value) { 79 sampleCount++; 80 if( value < min ) min = value; 81 if( value > max) max = value; 82 sampleSum += value; 83 sampleSquareSum += (value * value); 84 } // end sample 85 86 87 88 /** 89 * Computes the Standard Statistic Results based on the samples collected 90 * so far and provides the complete value as a formatted String 91 */ 92 public String getValue( ) { 93 return toString(); 94 } 95 96 /** 97 * Users can extend StatisticsAccumulator to provide the complete 98 * Stats in the format they prefer, if the default format doesn't suffice. 99 */ 100 public String toString( ) { 101 return "Minimum Value = " + min + " " + unit + " " + 102 "Maximum Value = " + max + " " + unit + " " + 103 "Average Value = " + computeAverage() + " " + unit + " " + 104 "Standard Deviation = " + computeStandardDeviation() + " " + unit + 105 " " + "Samples Collected = " + sampleCount; 106 } 107 108 /** 109 * If users choose to custom format the stats. 110 */ 111 protected double computeAverage( ) { 112 return (sampleSum / sampleCount); 113 } 114 115 116 /** 117 * We use a derived Standard Deviation formula to compute SD. This way 118 * there is no need to hold on to all the samples provided. 119 * 120 * The method is protected to let users extend and format the results. 121 */ 122 protected double computeStandardDeviation( ) { 123 double sampleSumSquare = sampleSum * sampleSum; 124 return Math.sqrt( 125 (sampleSquareSum-((sampleSumSquare)/sampleCount))/(sampleCount-1)); 126 } 127 128/** 129 * Construct the Statistics Accumulator by providing the unit as a String. 130 * The examples of units are "Hours", "Minutes", 131 * "Seconds", "MilliSeconds", "Micro Seconds" etc. 132 * 133 * @param unit a String representing the units for the samples collected 134 */ 135 public StatisticsAccumulator( String unit ) { 136 this.unit = unit; 137 sampleCount = 0; 138 sampleSum = 0; 139 sampleSquareSum = 0; 140 } 141 142 143 /** 144 * Clears the samples and starts fresh on new samples. 145 */ 146 void clearState( ) { 147 min = Double.MAX_VALUE; 148 max = Double.MIN_VALUE; 149 sampleCount = 0; 150 sampleSum = 0; 151 sampleSquareSum = 0; 152 } 153 154 /** 155 * This is an internal API to test StatisticsAccumulator... 156 */ 157 public void unitTestValidate( String expectedUnit, double expectedMin, 158 double expectedMax, long expectedSampleCount, double expectedAverage, 159 double expectedStandardDeviation ) 160 { 161 if( !expectedUnit.equals( unit ) ){ 162 throw new RuntimeException( 163 "Unit is not same as expected Unit" + 164 "\nUnit = " + unit + "ExpectedUnit = " + expectedUnit ); 165 } 166 if( min != expectedMin ) { 167 throw new RuntimeException( 168 "Minimum value is not same as expected minimum value" + 169 "\nMin Value = " + min + "Expected Min Value = " + expectedMin); 170 } 171 if( max != expectedMax ) { 172 throw new RuntimeException( 173 "Maximum value is not same as expected maximum value" + 174 "\nMax Value = " + max + "Expected Max Value = " + expectedMax); 175 } 176 if( sampleCount != expectedSampleCount ) { 177 throw new RuntimeException( 178 "Sample count is not same as expected Sample Count" + 179 "\nSampleCount = " + sampleCount + "Expected Sample Count = " + 180 expectedSampleCount); 181 } 182 if( computeAverage() != expectedAverage ) { 183 throw new RuntimeException( 184 "Average is not same as expected Average" + 185 "\nAverage = " + computeAverage() + "Expected Average = " + 186 expectedAverage); 187 } 188 // We are computing Standard Deviation from two different methods 189 // for comparison. So, the values will not be the exact same to the last 190 // few digits. So, we are taking the difference and making sure that 191 // the difference is not greater than 1. 192 double difference = Math.abs( 193 computeStandardDeviation() - expectedStandardDeviation); 194 if( difference > 1 ) { 195 throw new RuntimeException( 196 "Standard Deviation is not same as expected Std Deviation" + 197 "\nStandard Dev = " + computeStandardDeviation() + 198 "Expected Standard Dev = " + expectedStandardDeviation); 199 } 200 } 201 202 203} // end StatisticsAccumulator 204