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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * ident "%Z%%M% %I% %E% SMI" 27 */ 28 package org.opensolaris.os.dtrace; 29 30 import java.io.*; 31 import java.beans.*; 32 33 /** 34 * A {@code long} value aggregated by the DTrace {@code avg()} action. 35 * <p> 36 * Immutable. Supports persistence using {@link java.beans.XMLEncoder}. 37 * 38 * @see Aggregation 39 * @author Tom Erickson 40 */ 41 public final class AvgValue extends AbstractAggregationValue { 42 static final long serialVersionUID = 1633169020110237906L; 43 44 /** @serial */ 45 private final long total; 46 /** @serial */ 47 private final long count; 48 49 static { 50 try { 51 BeanInfo info = Introspector.getBeanInfo(AvgValue.class); 52 PersistenceDelegate persistenceDelegate = 53 new DefaultPersistenceDelegate( 54 new String[] {"value", "total", "count"}); 55 BeanDescriptor d = info.getBeanDescriptor(); 56 d.setValue("persistenceDelegate", persistenceDelegate); 57 } catch (IntrospectionException e) { 58 System.out.println(e); 59 } 60 } 61 62 /** 63 * Creates a value aggregated by the DTrace {@code avg()} action. 64 * Supports XML persistence. 65 * 66 * @param v average 67 * @param averagedTotal sum total of all values averaged 68 * @param averagedValueCount number of values averaged 69 * @throws IllegalArgumentException if the given count is negative 70 * or if the given average is not the value expected for the given 71 * total and count 72 */ 73 public AvgValue(long v, long averagedTotal, long averagedValueCount)74 AvgValue(long v, long averagedTotal, long averagedValueCount) 75 { 76 super(v); 77 total = averagedTotal; 78 count = averagedValueCount; 79 validate(); 80 } 81 82 private final void validate()83 validate() 84 { 85 if (count < 0) { 86 throw new IllegalArgumentException("count is negative"); 87 } 88 long average = super.getValue().longValue(); 89 if (count == 0) { 90 if (average != 0) { 91 throw new IllegalArgumentException( 92 "count of values is zero, average is non-zero (" + 93 average + ")"); 94 } 95 } else { 96 if (average != (total / count)) { 97 throw new IllegalArgumentException( 98 getValue().toString() + " is not the expected " + 99 "average of total " + total + " and count " + 100 count); 101 } 102 } 103 } 104 105 // Needed to support XML persistence since XMLDecoder cannot find 106 // the public method of the non-public superclass. 107 108 /** 109 * Gets the average of the aggregated values. 110 * 111 * @return average of the aggregated values, equal to <code>({@link 112 * #getTotal()} / {@link #getCount()})</code> rounded down 113 */ 114 public Long getValue()115 getValue() 116 { 117 return (Long)super.getValue(); 118 } 119 120 /** 121 * Gets the sum total of the aggregated values. 122 * 123 * @return the sum total of the aggregated values 124 */ 125 public long getTotal()126 getTotal() 127 { 128 return total; 129 } 130 131 /** 132 * Gets the number of aggregated values included in the average. 133 * 134 * @return the number of aggregated values included in the average 135 */ 136 public long getCount()137 getCount() 138 { 139 return count; 140 } 141 142 private void readObject(ObjectInputStream s)143 readObject(ObjectInputStream s) 144 throws IOException, ClassNotFoundException 145 { 146 s.defaultReadObject(); 147 // check invariants 148 try { 149 validate(); 150 } catch (Exception e) { 151 InvalidObjectException x = new InvalidObjectException( 152 e.getMessage()); 153 x.initCause(e); 154 throw x; 155 } 156 } 157 } 158