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 */ getStart()49 public Date getStart(); 50 51 /** 52 * Return the end of the sample period for which the 53 * statistic is representative. 54 */ getEnd()55 public Date getEnd(); 56 57 /** 58 * Get the value of this statistic. 59 */ getValue()60 public Object getValue(); 61 62 /** 63 * Get the value of this statistic as a Long. 64 */ getLongValue()65 public Long getLongValue(); 66 67 /** 68 * Get the value of this statistic as a Double. 69 */ getDoubleValue()70 public Double getDoubleValue(); 71 72 /** 73 * Get the value of this statistic as a UnsignedInt64. 74 */ getUnsignedInt64Value()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 */ add(AggregateStatistic o)88 public AggregateStatistic add(AggregateStatistic o); 89 90 /** 91 * Subtract the supplied statistic from this. 92 * 93 * @param o The other statistic. 94 */ subtract(AggregateStatistic o)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 */ getSnapshotForInterval(Iterator it, Date start, Date end)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 */ AbstractStatistic(Object value)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 */ AbstractStatistic(Object value, Date start, Date end)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 */ getStart()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 */ getEnd()183 public Date getEnd() 184 { 185 return (end); 186 } 187 188 /** 189 * Get the value of this statistic. 190 */ getValue()191 public Object getValue() 192 { 193 return (value); 194 } 195 getLongValue()196 public abstract Long getLongValue(); getDoubleValue()197 public abstract Double getDoubleValue(); getUnsignedInt64Value()198 public abstract UnsignedInt64 getUnsignedInt64Value(); 199 200 /** 201 * Return the string representation of this statistic. 202 */ toString()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 */ DoubleStatistic(Double value)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 */ DoubleStatistic(Double value, Date start, Date end)244 public DoubleStatistic(Double value, Date start, Date end) 245 { 246 super(value, start, end); 247 } 248 getDoubleValue()249 public Double getDoubleValue() 250 { 251 return ((Double) getValue()); 252 } 253 getLongValue()254 public Long getLongValue() 255 { 256 return (new Long(((Double) getValue()).longValue())); 257 } 258 getUnsignedInt64Value()259 public UnsignedInt64 getUnsignedInt64Value() 260 { 261 return (new UnsignedInt64(Long.toString(((Double) getValue()). 262 longValue()))); 263 } 264 add(AggregateStatistic o)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 subtract(AggregateStatistic o)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 getSnapshotForInterval(Iterator it, Date start, Date end)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 */ LongStatistic(Long value, Date start, Date end)332 public LongStatistic(Long value, Date start, Date end) 333 { 334 super(value, start, end); 335 } 336 getDoubleValue()337 public Double getDoubleValue() 338 { 339 return (new Double(((Long) getValue()).longValue())); 340 } 341 getLongValue()342 public Long getLongValue() 343 { 344 return ((Long) getValue()); 345 } 346 getUnsignedInt64Value()347 public UnsignedInt64 getUnsignedInt64Value() 348 { 349 return (new UnsignedInt64(Long.toString(((Long) getValue()). 350 longValue()))); 351 } 352 add(AggregateStatistic o)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 subtract(AggregateStatistic o)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 getSnapshotForInterval(Iterator it, Date start, Date end)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 */ UnsignedInt64Statistic(UnsignedInt64 value, Date start, Date end)419 public UnsignedInt64Statistic(UnsignedInt64 value, Date start, 420 Date end) 421 { 422 super(value, start, end); 423 } 424 getDoubleValue()425 public Double getDoubleValue() 426 { 427 return (new Double(((UnsignedInt64) getValue()).longValue())); 428 } 429 getLongValue()430 public Long getLongValue() 431 { 432 return (new Long(((UnsignedInt64) getValue()).longValue())); 433 } 434 getUnsignedInt64Value()435 public UnsignedInt64 getUnsignedInt64Value() 436 { 437 return ((UnsignedInt64) getValue()); 438 } 439 add(AggregateStatistic o)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 subtract(AggregateStatistic o)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 getSnapshotForInterval(Iterator it, Date start, Date end)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