fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER START
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The contents of this file are subject to the terms of the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Common Development and Distribution License (the "License").
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You may not use this file except in compliance with the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * or http://www.opensolaris.org/os/licensing.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * See the License for the specific language governing permissions
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * and limitations under the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * When distributing Covered Code, include this CDDL HEADER in each
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * If applicable, add the following below this CDDL HEADER, with the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * fields enclosed by brackets "[]" replaced with your own identifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * information: Portions Copyright [yyyy] [name of copyright owner]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER END
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Use is subject to license terms.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * ident "%Z%%M% %I% %E% SMI"
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeepackage org.opensolaris.os.dtrace;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeimport java.util.*;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeimport java.io.*;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeimport java.beans.*;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * A power-of-two logarithmic frequency distribution aggregated by the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTrace {@code quantize()} action. Aggregated values fall into
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * consecutive ranges, each twice as large as the previous range. Each
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * range, known as a bucket, begins at two to the power of <i>n</i> and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * ends at one less than the beginning of the next bucket, two to the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * power of <i>n + 1</i>. The zero bucket is the degenerate case and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * holds the frequency of the base value zero. For example, the first
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bucket after 0 starts at 1 (2 to the power of 0) and ends at 1 (one
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * less than 2 to the power of 1). The next bucket starts at 2 (2 to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the power of 1) and ends at 3 (one less than 2 to the power of 2).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Each bucket frequency is incremented for each aggregated value that
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * falls into its range. Buckets are typically identified by their
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * lower bound: 1, 2, 4, 8, etc. Mirroring these are buckets with
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * negative ranges: -1, -2, -4, -8, etc. The range of an entire {@code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * LogDistribution} is (<code>-2<sup>63</sup> ..
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 2<sup>63</sup></code>).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <p>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Immutable. Supports persistence using {@link java.beans.XMLEncoder}.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see LinearDistribution
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see Aggregation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @author Tom Erickson
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeepublic final class LogDistribution extends Distribution
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee implements Serializable, Comparable <LogDistribution>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static final long serialVersionUID = -1279719751212721961L;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static final int ZERO_BUCKET_INDEX = 63;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee try {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee BeanInfo info = Introspector.getBeanInfo(LogDistribution.class);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee PersistenceDelegate persistenceDelegate =
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee new DefaultPersistenceDelegate(
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee new String[] {"buckets"});
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee BeanDescriptor d = info.getBeanDescriptor();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee d.setValue("persistenceDelegate", persistenceDelegate);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } catch (IntrospectionException e) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee System.out.println(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native C code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee LogDistribution(long[] buckets)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee super(0, 2, buckets); // initializes using base 0, power of 2
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Creates a logarithmic distribution with the given frequencies.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Supports XML persistence.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param frequencies list of frequencies in bucket ranges bounded
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * by consucutive powers of two
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws NullPointerException if {@code frequencies} is {@code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * null}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalArgumentException if any bucket does not have the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * expected range (bounded by consecutive powers of two)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee LogDistribution(List <Bucket> frequencies)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee super(frequencies);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee initialize();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a two element array: the first elelemt is the range minimum
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * (inclusive), the second element is the range maximum (inclusive).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long[]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getBucketRange(int i, int len, long base, long constant)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long min = LocalConsumer._quantizeBucket(i);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long max = (LocalConsumer._quantizeBucket(i + 1) - 1);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long[] range = new long[] {min, max};
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return range;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long[]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getBucketRange(int i, int len)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return getBucketRange(i, len, 0, 2);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public Number
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getValue()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee double total = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee List <Distribution.Bucket> buckets = getBuckets();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (Distribution.Bucket bucket : buckets) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee total += ((double)bucket.getFrequency() * (double)bucket.getMin());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (new Double(total));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private long
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getZeroBucketValue()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Distribution.Bucket b = get(ZERO_BUCKET_INDEX);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return b.getFrequency();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Compares the {@code double} values of {@link #getValue()} for
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * overall magnitude, and if those are equal, compares the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * frequencies at the zero bucket (the bucket whose range has a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * minimum and maximum value of zero).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee compareTo(LogDistribution d)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Number v1 = getValue();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Number v2 = d.getValue();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee double d1 = v1.doubleValue();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee double d2 = v2.doubleValue();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int cmp = (d1 < d2 ? -1 : (d1 > d2 ? 1 : 0));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (cmp == 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long z1 = getZeroBucketValue();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long z2 = d.getZeroBucketValue();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee cmp = (z1 < z2 ? -1 : (z1 > z2 ? 1 : 0));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (cmp);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee readObject(ObjectInputStream s)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throws IOException, ClassNotFoundException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s.defaultReadObject();
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee try {
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee initialize();
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee } catch (Exception e) {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee InvalidObjectException x = new InvalidObjectException(
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee e.getMessage());
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee x.initCause(e);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee throw x;
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}