xref: /illumos-gate/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Statistic.java (revision fe4627ef755b7c263f91a0e6f07cdca5d7083501)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * ident	"%Z%%M%	%I%	%E% SMI"
27  */
28 
29 package com.sun.solaris.domain.pools;
30 
31 import java.math.BigInteger;
32 import java.util.Date;
33 import java.util.Iterator;
34 import java.text.*;
35 
36 import com.sun.solaris.service.pools.UnsignedInt64;
37 
38 /**
39  * Contains the information relating to a specific statistic for an
40  * object. The Statistic has no notion of the source of the data, it
41  * is simply a repository for holding statistical information.
42  */
43 interface Statistic
44 {
45 	/**
46 	 * Return the start of the sample period for which the
47 	 * statistic is representative.
48 	 */
49 	public Date getStart();
50 
51 	/**
52 	 * Return the end of the sample period for which the
53 	 * statistic is representative.
54 	 */
55 	public Date getEnd();
56 
57 	/**
58 	 * Get the value of this statistic.
59 	 */
60 	public Object getValue();
61 
62 	/**
63 	 * Get the value of this statistic as a Long.
64 	 */
65 	public Long getLongValue();
66 
67 	/**
68 	 * Get the value of this statistic as a Double.
69 	 */
70 	public Double getDoubleValue();
71 
72 	/**
73 	 * Get the value of this statistic as a UnsignedInt64.
74 	 */
75 	public UnsignedInt64 getUnsignedInt64Value();
76 }
77 
78 /**
79  * An interface for Statistics which may be aggregated.
80  */
81 interface AggregateStatistic extends Statistic
82 {
83 	/**
84 	 * Add the supplied statistic to this.
85 	 *
86 	 * @param o The other statistic.
87 	 */
88 	public AggregateStatistic add(AggregateStatistic o);
89 
90 	/**
91 	 * Subtract the supplied statistic from this.
92 	 *
93 	 * @param o The other statistic.
94 	 */
95 	public AggregateStatistic subtract(AggregateStatistic o);
96 
97 	/**
98 	 * Produce the aggregate of all objects in the supplied
99 	 * iterator (which must be of the same type) whose start and
100 	 * end dates lie within the supplied ranges. If either start
101 	 * or end is null, then that bound is not applied. i.e. if no
102 	 * start date is supplied, then start checking is disabled.
103 	 *
104 	 * @param start The start date for qualification in the snapshot.
105 	 * @param end The end date for qualification in the snapshot.
106 	 * @throws IllegalArgumentException If the iterator is empty.
107 	 */
108 	public AggregateStatistic getSnapshotForInterval(Iterator it,
109 	    Date start, Date end) throws IllegalArgumentException;
110 }
111 
112 /**
113  * A basic Statistic implementation which makes it easy to derive
114  * concrete statistic types. This is an immutable class, the state is
115  * set when the object is constructed and cannot be later changed.
116  */
117 abstract class AbstractStatistic implements Statistic
118 {
119 	/**
120 	 * The value of the statistic.
121 	 */
122 	private final Object value;
123 
124 	/**
125 	 * The start of the interval during which the statistic was
126 	 * captured.
127 	 */
128 	private final Date start;
129 
130 	/**
131 	 * The end of the interval during which the statistic was
132 	 * captured.
133 	 */
134 	private final Date end;
135 
136 	/**
137 	 * Formatter for the sample start time, used by toString().
138 	 */
139 	private static final DateFormat df = new SimpleDateFormat("kk:mm:ss");
140 
141 	/**
142 	 * Constructor. This is provided as a mechanism to allow
143 	 * inherited classes to correctly initialize their state.
144 	 *
145 	 * @param value The value of this statistic.
146 	 */
147 	protected AbstractStatistic(Object value)
148 	{
149 		this(value, null, null);
150 	}
151 
152 	/**
153 	 * Constructor. This is provided as a mechanism to allow
154 	 * inherited classes to correctly initialize their state.
155 	 *
156 	 * @param value The value of this statistic.
157 	 * @param start The start of the sample period which this
158 	 * statistic represents.
159 	 * @param end The end of the sample period which this
160 	 * statistic represents.
161 	 */
162 	protected AbstractStatistic(Object value, Date start, Date end)
163 	{
164 		this.value = value;
165 		this.start = start;
166 		this.end = end;
167 	}
168 
169 	/**
170 	 * Return the start of the sample period for which the
171 	 * statistic is representative.
172 	 */
173 	public Date getStart()
174 	{
175 		return (start);
176 	}
177 
178 
179 	/**
180 	 * Return the end of the sample period for which the
181 	 * statistic is representative.
182 	 */
183 	public Date getEnd()
184 	{
185 		return (end);
186 	}
187 
188 	/**
189 	 * Get the value of this statistic.
190 	 */
191 	public Object getValue()
192 	{
193 		return (value);
194 	}
195 
196 	public abstract Long getLongValue();
197 	public abstract Double getDoubleValue();
198 	public abstract UnsignedInt64 getUnsignedInt64Value();
199 
200 	/**
201 	 * Return the string representation of this statistic.
202 	 */
203 	public String toString()
204 	{
205 		StringBuffer buf = new StringBuffer();
206 
207 		buf.append(value);
208 		if (start != null && end != null) {
209 			buf.append(" from ");
210 			buf.append(df.format(start));
211 			buf.append(" to ");
212 			buf.append(df.format(end));
213 		}
214 		return (buf.toString());
215 	}
216 }
217 
218 /**
219  * A statistic of type Double.
220  */
221 final class DoubleStatistic extends AbstractStatistic
222     implements AggregateStatistic
223 {
224 
225 	/**
226 	 * Constructor.
227 	 *
228 	 * @param value The value of this statistic.
229 	 */
230 	public DoubleStatistic(Double value)
231 	{
232 		super(value);
233 	}
234 
235 	/**
236 	 * Constructor.
237 	 *
238 	 * @param value The value of this statistic.
239 	 * @param start The start of the interval over which this
240 	 * statistic is representative.
241 	 * @param end The end of the interval over which this
242 	 * statistic is representative.
243 	 */
244 	public DoubleStatistic(Double value, Date start, Date end)
245 	{
246 		super(value, start, end);
247 	}
248 
249 	public Double getDoubleValue()
250 	{
251 		return ((Double) getValue());
252 	}
253 
254 	public Long getLongValue()
255 	{
256 		return (new Long(((Double) getValue()).longValue()));
257 	}
258 
259 	public UnsignedInt64 getUnsignedInt64Value()
260 	{
261 		return (new UnsignedInt64(Long.toString(((Double) getValue()).
262 					      longValue())));
263 	}
264 
265 	public AggregateStatistic add(AggregateStatistic o)
266 	{
267 		Double v1 = getDoubleValue();
268 		Double v2 = o.getDoubleValue();
269 
270 		return (new DoubleStatistic(new Double(v1.doubleValue() +
271 					    v2.doubleValue()),
272 			getStart(), getEnd()));
273 	}
274 
275 	public AggregateStatistic subtract(AggregateStatistic o)
276 	{
277 		Double v1 = getDoubleValue();
278 		Double v2 = o.getDoubleValue();
279 
280 		return (new DoubleStatistic(new Double(v1.doubleValue() -
281 					    v2.doubleValue()),
282 			getStart(), getEnd()));
283 	}
284 
285 	public AggregateStatistic getSnapshotForInterval(Iterator it,
286 	    Date start, Date end) throws IllegalArgumentException
287 	{
288 		double total = 0;
289 		int count = 0;
290 		Date first = start, last = end;
291 
292 		while (it.hasNext()) {
293 			DoubleStatistic s = (DoubleStatistic) it.next();
294 			if (start != null) {
295 				if (s.getStart().compareTo(start) < 0)
296 					continue;
297 			}
298 			if (first == null)
299 				first = s.getStart();
300 			if (end != null) {
301 				if (s.getEnd().compareTo(end) > 0)
302 					continue;
303 			}
304 			last = s.getEnd();
305 			total += s.getDoubleValue().doubleValue();
306 			count++;
307 		}
308 		if (count == 0)
309 			throw new IllegalArgumentException("Cannot derive a " +
310 			    "snapshot from an empty iterator");
311 		return (new DoubleStatistic(new Double(total / count), first,
312 			last));
313 	}
314 }
315 
316 /**
317  * A statistic of type Long.
318  */
319 final class LongStatistic extends AbstractStatistic
320     implements AggregateStatistic
321 {
322 
323 	/**
324 	 * Constructor.
325 	 *
326 	 * @param value The value of this statistic.
327 	 * @param start The start of the interval over which this
328 	 * statistic is representative.
329 	 * @param end The end of the interval over which this
330 	 * statistic is representative.
331 	 */
332 	public LongStatistic(Long value, Date start, Date end)
333 	{
334 		super(value, start, end);
335 	}
336 
337 	public Double getDoubleValue()
338 	{
339 		return (new Double(((Long) getValue()).longValue()));
340 	}
341 
342 	public Long getLongValue()
343 	{
344 		return ((Long) getValue());
345 	}
346 
347 	public UnsignedInt64 getUnsignedInt64Value()
348 	{
349 		return (new UnsignedInt64(Long.toString(((Long) getValue()).
350 					      longValue())));
351 	}
352 
353 	public AggregateStatistic add(AggregateStatistic o)
354 	{
355 		Long v1 = getLongValue();
356 		Long v2 = o.getLongValue();
357 
358 		return (new LongStatistic(new Long(v1.longValue() +
359 					    v2.longValue()),
360 			getStart(), getEnd()));
361 	}
362 
363 	public AggregateStatistic subtract(AggregateStatistic o)
364 	{
365 		Long v1 = getLongValue();
366 		Long v2 = o.getLongValue();
367 
368 		return (new LongStatistic(new Long(v1.longValue() -
369 					    v2.longValue()),
370 			getStart(), getEnd()));
371 	}
372 
373 	public AggregateStatistic getSnapshotForInterval(Iterator it,
374 	    Date start, Date end) throws IllegalArgumentException
375 	{
376 		long total = 0;
377 		int count = 0;
378 		Date first = start, last = end;
379 		while (it.hasNext()) {
380 			LongStatistic s = (LongStatistic) it.next();
381 			if (start != null) {
382 				if (s.getStart().compareTo(start) < 0)
383 					continue;
384 			}
385 			if (first == null)
386 				first = s.getStart();
387 			if (end != null) {
388 				if (s.getEnd().compareTo(end) > 0)
389 					continue;
390 			}
391 			last = s.getEnd();
392 			total += s.getLongValue().longValue();
393 			count++;
394 		}
395 		if (count == 0)
396 			throw new IllegalArgumentException("Cannot derive a " +
397 			    "snapshot from an empty iterator");
398 		return (new LongStatistic(new Long(total / count), first,
399 			last));
400 	}
401 }
402 
403 /**
404  * A statistic of type UnsignedInt64.
405  */
406 final class UnsignedInt64Statistic extends AbstractStatistic
407     implements AggregateStatistic
408 {
409 
410 	/**
411 	 * Constructor.
412 	 *
413 	 * @param value The value of this statistic.
414 	 * @param start The start of the interval over which this
415 	 * statistic is representative.
416 	 * @param end The end of the interval over which this
417 	 * statistic is representative.
418 	 */
419 	public UnsignedInt64Statistic(UnsignedInt64 value, Date start,
420 	    Date end)
421 	{
422 		super(value, start, end);
423 	}
424 
425 	public Double getDoubleValue()
426 	{
427 		return (new Double(((UnsignedInt64) getValue()).longValue()));
428 	}
429 
430 	public Long getLongValue()
431 	{
432 		return (new Long(((UnsignedInt64) getValue()).longValue()));
433 	}
434 
435 	public UnsignedInt64 getUnsignedInt64Value()
436 	{
437 		return ((UnsignedInt64) getValue());
438 	}
439 
440 	public AggregateStatistic add(AggregateStatistic o)
441 	{
442 		UnsignedInt64 v1 = getUnsignedInt64Value();
443 		UnsignedInt64 v2 = o.getUnsignedInt64Value();
444 
445 		return (new UnsignedInt64Statistic(
446 		    new UnsignedInt64(v1.add(v2)),
447 		        getStart(), getEnd()));
448 	}
449 
450 	public AggregateStatistic subtract(AggregateStatistic o)
451 	{
452 		UnsignedInt64 v1 = getUnsignedInt64Value();
453 		UnsignedInt64 v2 =  o.getUnsignedInt64Value();
454 
455 		return (new UnsignedInt64Statistic(
456 		    new UnsignedInt64(v1.subtract(v2)),
457 		        getStart(), getEnd()));
458 	}
459 
460 	public AggregateStatistic getSnapshotForInterval(Iterator it,
461 	    Date start, Date end) throws IllegalArgumentException
462 	{
463 		BigInteger total = new BigInteger("0");
464 		int count = 0;
465 		Date first = start, last = end;
466 		while (it.hasNext()) {
467 			UnsignedInt64Statistic s = (UnsignedInt64Statistic)
468 			    it.next();
469 			if (start != null) {
470 				if (s.getStart().compareTo(start) < 0)
471 					continue;
472 			}
473 			if (first == null)
474 				first = s.getStart();
475 
476 			if (end != null) {
477 				if (s.getEnd().compareTo(end) > 0)
478 					continue;
479 			}
480 			last = s.getEnd();
481 			total = total.add(s.getUnsignedInt64Value());
482 			count++;
483 		}
484 		if (count == 0)
485 			throw new IllegalArgumentException("Cannot derive a " +
486 			    "snapshot from an empty iterator");
487 		return (new UnsignedInt64Statistic(
488 		    new UnsignedInt64(total.divide(new BigInteger(
489 	            Integer.toString(count)))), first, last));
490 	}
491 }
492