1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.sensor.meter;
18
19 /***
20 *
21 *
22 */
23 class MeterData {
24
25
26
27
28
29 /*** The label that uniquely identifies an instance of this class. */
30 private final String label;
31
32 /*** Lazy-initialized hierarchical (tree) view on this instance. */
33 private MeterStatistics meterStatistics;
34
35
36
37
38
39
40 private long currentValue = 0L;
41 private long sumOfValues = 0L;
42 private long averageValue = 0L;
43 private long minimumValue = 0L;
44 private long maximumValue = 0L;
45 private long standardDeviation = 0L;
46
47 private long numberOfValueChanges = 0L;
48 private long sumOfSquaresOfValues = 0L;
49
50 private long timeOfFirstUpdate = 0L;
51 private long timeOfLastUpdate = 0L;
52
53
54
55
56
57
58 /***
59 * Creates a new MeterData instance uniquely identified by the specified label.
60 *
61 * @param runtime the associated {@link MeterRuntime}.
62 * @param label the label that uniquely identifies an instance of this class.
63 */
64 MeterData(String label) {
65 this.label = label;
66 }
67
68
69
70
71
72
73 /***
74 * Returns the label.
75 * @return Returns the label.
76 */
77 String getLabel() {
78 return label;
79 }
80
81 /***
82 * Resets all statistics data.
83 */
84 synchronized void reset() {
85 currentValue = 0L;
86 sumOfValues = 0L;
87 averageValue = 0L;
88 minimumValue = 0L;
89 maximumValue = 0L;
90 standardDeviation = 0L;
91
92 timeOfFirstUpdate = 0L;
93 timeOfLastUpdate = 0L;
94
95 numberOfValueChanges = 0L;
96 sumOfSquaresOfValues = 0L;
97 }
98
99
100
101
102
103
104 /***
105 * Creates a new instance of Meter linked to this MeterData instance.
106 * @return a new instance of Meter linked to this MeterData instance.
107 */
108 Meter createMeter() {
109 return new Meter(this);
110 }
111
112 /***
113 * Callback method used by Meter instances to report back a timing measurement.
114 * @param newValue the time (in milliseconds) it took to execute the code that was being measured.
115 */
116 synchronized void updateFromMeter(long newValue) {
117
118 numberOfValueChanges++;
119 currentValue = newValue;
120 sumOfValues = sumOfValues + newValue;
121 averageValue = sumOfValues / numberOfValueChanges;
122 sumOfSquaresOfValues = sumOfSquaresOfValues + (newValue * newValue);
123
124
125 timeOfLastUpdate = System.currentTimeMillis();
126
127 if (numberOfValueChanges == 1L) {
128 minimumValue = newValue;
129 maximumValue = newValue;
130 timeOfFirstUpdate = timeOfLastUpdate;
131 } else {
132 if (newValue < minimumValue) {
133 minimumValue = newValue;
134 }
135
136 if (newValue > maximumValue) {
137 maximumValue = newValue;
138 }
139 }
140
141
142 long nMinus1 = (numberOfValueChanges <= 1) ? 1 : numberOfValueChanges - 1;
143 long numerator = sumOfSquaresOfValues - ((sumOfValues * sumOfValues) / numberOfValueChanges);
144
145 standardDeviation = (long) java.lang.Math.sqrt(numerator / nMinus1);
146 }
147
148 /***
149 * Returns a hierarchical statistical view of this instance of MeterData.
150 * @return a hierarchical statistical view of this instance of MeterData.
151 */
152 MeterStatistics getStatistics() {
153 if (meterStatistics == null) {
154 meterStatistics = new MeterStatistics(this);
155 }
156
157
158 refreshStatistics();
159
160 return meterStatistics;
161 }
162
163 /***
164 * Callback method used by {@link MeterStatistics#refresh()} to extract
165 * the latest data from this instance.
166 * This method is synchronized to prevent half-updated data, etc.
167 * The reason for this elaborate callback mechanism is to get all internal
168 * values out of this instance in one synchronized call instead of calling
169 * a number of synchronized getters from the statistics class. The latter
170 * could lead to inconsistent data.
171 */
172 synchronized void refreshStatistics() {
173 meterStatistics.refreshFromData(
174 currentValue,
175 numberOfValueChanges ,
176 sumOfValues,
177 averageValue,
178 standardDeviation,
179 minimumValue,
180 maximumValue,
181 timeOfFirstUpdate,
182 timeOfLastUpdate,
183 sumOfSquaresOfValues);
184 }
185
186
187
188
189
190
191
192
193 /***
194 * Returns the currentValue.
195 * @return Returns the currentValue.
196 */
197 long getCurrentValue() {
198 return currentValue;
199 }
200
201 /***
202 * Returns the numberOfValueChanges.
203 * @return Returns the numberOfValueChanges.
204 */
205 long getNumberOfValueChanges() {
206 return numberOfValueChanges;
207 }
208
209 /***
210 * Returns the sumOfValues.
211 * @return Returns the sumOfValues.
212 */
213 long getSumOfValues() {
214 return sumOfValues;
215 }
216
217 /***
218 * Returns the averageValue.
219 * @return Returns the averageValue.
220 */
221 long getAverageValue() {
222 return averageValue;
223 }
224
225 /***
226 * Returns the sumOfSquaresOfValues.
227 * @return Returns the sumOfSquaresOfValues.
228 */
229 long getSumOfSquaresOfValues() {
230 return sumOfSquaresOfValues;
231 }
232
233 /***
234 * Returns the standardDeviation.
235 * @return Returns the standardDeviation.
236 */
237 long getStandardDeviation() {
238 return standardDeviation;
239 }
240
241 /***
242 * Returns the minimumValue.
243 * @return Returns the minimumValue.
244 */
245 long getMinimumValue() {
246 return minimumValue;
247 }
248
249 /***
250 * Returns the maximumValue.
251 * @return Returns the maximumValue.
252 */
253 long getMaximumValue() {
254 return maximumValue;
255 }
256
257 /***
258 * Returns the timeOfFirstUpdate.
259 * @return Returns the timeOfFirstUpdate.
260 */
261 long getTimeOfFirstUpdate() {
262 return timeOfFirstUpdate;
263 }
264
265 /***
266 * Returns the timeOfLastUpdate.
267 * @return Returns the timeOfLastUpdate.
268 */
269 long getTimeOfLastUpdate() {
270 return timeOfLastUpdate;
271 }
272
273
274
275
276
277
278 /***
279 * @see java.lang.Object#toString()
280 */
281 public String toString() {
282 return "Current value: " + currentValue
283 + ", Number of value changes: " + numberOfValueChanges
284 + ", Sum of values: " + sumOfValues
285 + ", Average value: " + averageValue
286 + ", Standard deviation: " + standardDeviation
287 + ", Minimum value: " + minimumValue
288 + ", Maximum value: " + maximumValue
289 + ", Time of first update: " + timeOfFirstUpdate
290 + ", Time of last update: " + timeOfLastUpdate
291 + ", Sum of squares of values: " + sumOfSquaresOfValues;
292 }
293
294 }