View Javadoc

1   /*
2    ~ Copyright 2006-2007 Nicolas De Loof.
3    ~
4    ~ Licensed under the Apache License, Version 2.0 (the "License");
5    ~ you may not use this file except in compliance with the License.
6    ~ You may obtain a copy of the License at
7    ~
8    ~      http://www.apache.org/licenses/LICENSE-2.0
9    ~
10   ~ Unless required by applicable law or agreed to in writing, software
11   ~ distributed under the License is distributed on an "AS IS" BASIS,
12   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   ~ See the License for the specific language governing permissions and
14   ~ limitations under the License.
15   */
16  package org.jmonit.features;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  
21  import org.jmonit.events.DataMonitoredEvent;
22  import org.jmonit.events.MonitoringEvent;
23  import org.jmonit.reporting.Visitable;
24  import org.jmonit.reporting.Visitor;
25  
26  /**
27   * Computes some statistics from monitored datas.
28   * 
29   * @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
30   */
31  public class Statistics
32      extends AbstractFeature<Statistics>
33      implements Visitable
34  {
35      /** hits counter */
36      private long hits;
37  
38      /** Total counter */
39      private long total;
40  
41      /** Min value counter */
42      private long min;
43  
44      /** Max value counter */
45      private long max;
46  
47      /** total of squares */
48      private long squares;
49  
50      /**
51       * {@inheritDoc}
52       * 
53       * @see org.jmonit.events.MonitoringEventListener#onMonitoringEvent(org.jmonit.events.MonitoringEvent)
54       */
55      public void onMonitoringEvent( MonitoringEvent event )
56      {
57          if ( event instanceof DataMonitoredEvent )
58          {
59              DataMonitoredEvent data = (DataMonitoredEvent) event;
60              added( data.getData() );
61          }
62      }
63  
64      /**
65       * {@inheritDoc}
66       */
67      public synchronized void added( long value )
68      {
69          total += value;
70          squares += value * value;
71          if ( hits == 0 || min > value )
72          {
73              min = value;
74          }
75          if ( hits == 0 || max < value )
76          {
77              max = value;
78          }
79          hits++;
80      }
81  
82      /**
83       * @return the hits
84       */
85      public long getHits()
86      {
87          return hits;
88      }
89  
90      /**
91       * @return the max
92       */
93      public long getMax()
94      {
95          return max;
96      }
97  
98      public synchronized double getMean()
99      {
100         if ( hits == 0 )
101         {
102             return Double.NaN;
103         }
104         return ( (double) total ) / hits;
105     }
106 
107     /**
108      * @return the min
109      */
110     public long getMin()
111     {
112         return min;
113     }
114 
115     /**
116      * Compute the standard deviation (measures the dispersion of values around
117      * the average value) = sqrt( variance )
118      * 
119      * @return the standard deviation
120      */
121     public double getStandardDeviation()
122     {
123         return Math.sqrt( getVariance() );
124     }
125 
126     /**
127      * @return the total
128      */
129     public long getTotal()
130     {
131         return total;
132     }
133 
134     /**
135      * Computes the
136      * {@link http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance}
137      * unbiased variance.
138      * <p>
139      * 
140      * @return the variance
141      */
142     public synchronized double getVariance()
143     {
144         long n = hits;
145         if ( n <= 1 )
146         {
147             return Double.NaN;
148         }
149         double sumOfSqr = squares;
150         double sum = total;
151         double mean = getMean();
152         return ( sumOfSqr - sum * mean ) / ( n - 1 );
153     }
154 
155     public void clear()
156     {
157         hits = 0;
158         max = 0;
159         min = 0;
160         squares = 0;
161         total = 0;
162     }
163 
164     /**
165      * {@inheritDoc}
166      * 
167      * @see org.jmonit.spi.Plugin#getFeature()
168      */
169     public Statistics getFeature()
170     {
171         return this;
172     }
173 
174     /**
175      * {@inheritDoc}
176      * 
177      * @see org.jmonit.reporting.Visitable#accept(org.jmonit.reporting.Visitor)
178      */
179     public synchronized void accept( Visitor visitor )
180     {
181         Map<String, Object> attributes = new HashMap<String, Object>();
182         attributes.put( "hits", getHits() );
183         attributes.put( "mean", getMean() );
184         attributes.put( "min", getMin() );
185         attributes.put( "max", getMax() );
186         attributes.put( "standardDeviation", getStandardDeviation() );
187         attributes.put( "total", getTotal() );
188         visitor.visit( attributes );
189     }
190 
191     public static final org.jmonit.spi.Factory<Statistics> FACTORY =
192         new org.jmonit.spi.Factory<Statistics>()
193         {
194             public Statistics newPluginInstance()
195             {
196                 return new Statistics();
197             }
198         };
199 
200     /**
201      * {@inheritDoc}
202      * 
203      * @see java.lang.Object#toString()
204      */
205     public String toString()
206     {
207         StringBuffer stb = new StringBuffer( "Statistics" );
208         stb.append( "[\n" );
209         stb.append( "  hits    = " ).append( this.hits ).append( "\n" );
210         stb.append( "  total   = " ).append( this.total ).append( "\n" );
211         stb.append( "  min     = " ).append( this.min ).append( "\n" );
212         stb.append( "  max     = " ).append( this.max ).append( "\n" );
213         stb.append( "  mean    = " ).append( getMean() ).append( "\n" );
214         stb.append( "  std.dev = " ).append( getStandardDeviation() ).append( "\n" );
215         stb.append( "]" );
216         return stb.toString();
217     }
218 }