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/*
e77b06d21580f630e0a7c437495ab283d3672828tomee * Copyright 2008 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 frequency distribution aggregated by the DTrace {@code quantize()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * or {@code lquantize()} action. Each aggregated value falls into a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * range known as a bucket and counts toward the frequency of that
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bucket. Bucket ranges are consecutive, with the maximum of one
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bucket's range always one less than the minimum of the next bucket's
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * range. By convention each bucket is identified by the minimum of its
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * range.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @author Tom Erickson
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeepublic abstract class Distribution implements AggregationValue,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Iterable <Distribution.Bucket>, Serializable
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static final long serialVersionUID = 1186243118882654932L;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /** @serial */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private List <Bucket> buckets;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private transient double total;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private transient boolean initialized;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Package level access, called by subclasses LinearDistribution and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * LogDistribution, but not available outside the API.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param base the lower bound of this distribution, or zero if not
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * applicable
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param constant the constant term of the distribution function
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * used to calculate the lower bound of any bucket given the lower
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bound of the previous bucket, for example the step in a linear
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * distribution or the log base in a logarithmic distribution.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param frequencies for each bucket, the number of aggregated
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * values falling into that bucket's range; each element must be a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * positive integer
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws NullPointerException if frequencies is null
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalArgumentException if any element of frequencies
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * does not have the expected range as defined by checkBucketRange()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Distribution(long base, long constant, long[] frequencies)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee total = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long frequency;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (int i = 0, len = frequencies.length; i < len; ++i) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee frequency = frequencies[i];
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee total += frequency;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buckets = createBuckets(base, constant, frequencies);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee initialized = true;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Supports XML persistence of subclasses. Sub-class implementation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * must call initialize() after setting any state specific to that
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * subclass for determining bucket ranges.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws NullPointerException if frequencies is null
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalArgumentException if any element of frequencies
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * does not have the expected range as defined by checkBucketRange()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Distribution(List <Bucket> frequencies)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // defensively copy frequencies list
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int len = frequencies.size();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // don't need gratuitous capacity % added by constructor that
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // takes a Collection argument; list will not be modified
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buckets = new ArrayList <Bucket> (len);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buckets.addAll(frequencies);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee final void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee initialize()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Called by constructor and readObject() (deserialization).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // 1. Check class invariants, throw exception if deserialized
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // state inconsistent with a Distribution that can result
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // from the public constructor.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // 2. Compute total (transient property derived from buckets)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee total = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long frequency;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Bucket bucket;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int len = buckets.size();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (int i = 0; i < len; ++i) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee bucket = buckets.get(i);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee frequency = bucket.getFrequency();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // relies on package-private getBucketRange()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // implementation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkBucketRange(i, len, bucket);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee total += frequency;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee initialized = true;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Must be called by public instance methods (since the AbstractList
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // methods all depend on get() and size(), it is sufficient to call
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // checkInit() only in those inherited methods).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!initialized) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("Uninitialized");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
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 * Implemented by subclasses LinearDistribution and LogDistribution
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * to define bucket ranges for this distribution and not available
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * outside the API. Used by the private general purpose constructor
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * called from native code. Implementation must not use
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * subclass-specific state, since subclass state has not yet been
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * allocated.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see #Distribution(long base, long constant, long[] frequencies)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee abstract long[]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getBucketRange(int i, int len, long base, long constant);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Used by public constructors and deserialization only after
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * state specific to the subclass is available to the method.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee abstract long[]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getBucketRange(int i, int len);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private List <Distribution.Bucket>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee createBuckets(long base, long constant, long[] frequencies)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int len = frequencies.length;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Bucket bucket;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee List <Bucket> buckets = new ArrayList <Bucket> (len);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long min; // current bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long max; // next bucket minus one
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long[] range; // two element array: { min, max }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (int i = 0; i < len; ++i) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee range = getBucketRange(i, len, base, constant);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee min = range[0];
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee max = range[1];
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee bucket = new Distribution.Bucket(min, max, frequencies[i]);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buckets.add(bucket);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buckets;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Validates that bucket has the expected range for the given bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * index. Uses {@code base} and {@code constant} constructor args
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * to check invariants specific to each subclass, since state
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * derived from these args in a subclass is not yet available in the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * superclass constructor.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalArgumentException if bucket does not have the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * expected range for the given bucket index {@code i}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkBucketRange(int i, int bucketCount, Distribution.Bucket bucket,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long base, long constant)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long[] range = getBucketRange(i, bucketCount, base, constant);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkBucketRange(i, bucket, range);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkBucketRange(int i, int bucketCount, Distribution.Bucket bucket)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long[] range = getBucketRange(i, bucketCount);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkBucketRange(i, bucket, range);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkBucketRange(int i, Distribution.Bucket bucket, long[] range)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long min = range[0];
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long max = range[1];
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (bucket.getMin() != min) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalArgumentException("bucket min " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee bucket.getMin() + " at index " + i + ", expected " + min);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (bucket.getMax() != max) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalArgumentException("bucket max " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee bucket.getMax() + " at index " + i + ", expected " + max);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a modifiable list of this distribution's buckets ordered by
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bucket range. Modifying the returned list has no effect on this
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * distribution. Supports XML persistence.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return a modifiable list of this distribution's buckets ordered
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * by bucket range
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public List <Bucket>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getBuckets()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return new ArrayList <Bucket> (buckets);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
e77b06d21580f630e0a7c437495ab283d3672828tomee * Gets a read-only {@code List} view of this distribution.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
e77b06d21580f630e0a7c437495ab283d3672828tomee * @return a read-only {@code List} view of this distribution
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public List <Bucket>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee asList()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
e77b06d21580f630e0a7c437495ab283d3672828tomee return Collections. <Bucket> unmodifiableList(buckets);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the number of buckets in this distribution.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return non-negative bucket count
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee size()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buckets.size();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the bucket at the given distribution index (starting at
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * zero).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return non-null distribution bucket at the given zero-based
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * index
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public Bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee get(int index)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buckets.get(index);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets an iterator over the buckets of this distribution.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return an iterator over the buckets of this distribution
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public Iterator<Bucket>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee iterator()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buckets.iterator();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Compares the specified object with this {@code Distribution}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * instance for equality. Defines equality as having the same
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * buckets with the same values.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return {@code true} if and only if the specified object is of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * type {@code Distribution} and both instances have the same size
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * and equal buckets at corresponding distribution indexes
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee equals(Object o)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (o instanceof Distribution) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Distribution d = (Distribution)o;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buckets.equals(d.buckets);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return false;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Overridden to ensure that equals instances have equal hash codes.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hashCode()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buckets.hashCode();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the total frequency across all buckets.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return sum of the frequency of all buckets in this distribution
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public double
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getTotal()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return total;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the numeric value of this distribution used to compare
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * distributions by overall magnitude, defined as the sum total of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * each bucket's frequency times the minimum of its range.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public abstract Number getValue();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee normalizeBuckets(long normal)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (Bucket b : buckets) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee b.frequency /= normal;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * A range inclusive at both endpoints and a count of aggregated
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * values that fall in that range. Buckets in a {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Distribution} are consecutive, such that the max of one bucket is
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * always one less than the min of the next bucket (or {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Long#MAX_VALUE} if it is the last bucket in the {@code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Distribution}).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <p>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Immutable. Supports persistence using {@link java.beans.XMLEncoder}.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public static final class Bucket implements Serializable {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static final long serialVersionUID = 4863264115375406295L;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /** @serial */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private final long min;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /** @serial */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private final long max;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /** @serial */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private long frequency; // non-final so native code can normalize
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee try {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee BeanInfo info = Introspector.getBeanInfo(Bucket.class);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee PersistenceDelegate persistenceDelegate =
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee new DefaultPersistenceDelegate(
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee new String[] {"min", "max", "frequency"})
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Need to prevent DefaultPersistenceDelegate from using
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * overridden equals() method, resulting in a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * StackOverFlowError. Revert to PersistenceDelegate
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * implementation. See
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * http://forum.java.sun.com/thread.jspa?threadID=
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 477019&tstart=135
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee mutatesTo(Object oldInstance, Object newInstance)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (newInstance != null && oldInstance != null &&
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (oldInstance.getClass() ==
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee newInstance.getClass()));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee };
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee BeanDescriptor d = info.getBeanDescriptor();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee d.setValue("persistenceDelegate", persistenceDelegate);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } catch (IntrospectionException e) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee System.out.println(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Creates a distribution bucket with the given range and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * frequency.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param rangeMinimumInclusive sets the lower bound (inclusive)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * returned by {@link #getMin()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param rangeMaximumInclusive sets the upper bound (inclusive)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * returned by {@link #getMax()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param valuesInRange sets the value frequency in this
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bucket's range returned by {@link #getFrequency()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalArgumentException if {@code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * rangeMaximumInclusive} is less than {@code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * rangeMinimumInclusive}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Bucket(long rangeMinimumInclusive, long rangeMaximumInclusive,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee long valuesInRange)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rangeMaximumInclusive < rangeMinimumInclusive) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalArgumentException("upper bound " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rangeMaximumInclusive + " is less than lower bound " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rangeMinimumInclusive);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee min = rangeMinimumInclusive;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee max = rangeMaximumInclusive;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee frequency = valuesInRange;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the lower bound of this bucket's range (inclusive).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public long
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getMin()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return min;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the upper bound of this bucket's range (inclusive).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public long
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getMax()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return max;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the number of values in a {@link Distribution} that fall
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * into the range defined by this bucket.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public long
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getFrequency()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return frequency;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Compares the specified object with this distribution bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * for equality. Defines equality of two distribution buckets
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * as having the same range and the same frequency.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return false if the specified object is not a {@code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Distribution.Bucket}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee equals(Object o)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (o instanceof Bucket) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Bucket b = (Bucket)o;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return ((min == b.min) &&
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (max == b.max) &&
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (frequency == b.frequency));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return false;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Overridden to ensure that equal buckets have equal hashcodes.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hashCode()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int hash = 17;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hash = (37 * hash) + ((int)(min ^ (min >>> 32)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hash = (37 * hash) + ((int)(max ^ (max >>> 32)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hash = (37 * hash) + ((int)(frequency ^ (frequency >>> 32)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return hash;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee readObject(ObjectInputStream s)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throws IOException, ClassNotFoundException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s.defaultReadObject();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // check class invariants (as constructor does)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (max < min) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new InvalidObjectException("upper bound " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee max + " is less than lower bound " + min);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a string representation of this distribution bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * useful for logging and not intended for display. The exact
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * details of the representation are unspecified and subject to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * change, but the following format may be regarded as typical:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre><code>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * class-name[property1 = value1, property2 = value2]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * </code></pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee toString()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee StringBuilder buf = new StringBuilder();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(Bucket.class.getName());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append("[min = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(min);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(", max = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(max);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(", frequency = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(frequency);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(']');
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buf.toString();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a list of buckets of interest by excluding empty buckets at
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * both ends of the distribution. Leaves one empty bucket on each
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * end if possible to convey the distribution context more
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * effectively in a display.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return an unmodifiable sublist that includes the range starting
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * from the first bucket with a non-zero frequency and ending with
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the last bucket with a non-zero frequency, plus one empty bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * before and after that range if possible
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public List <Bucket>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getDisplayRange()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int min = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int max = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int len = size();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Bucket b;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Get first non-empty bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (int i = 0; i < len; ++i) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee b = buckets.get(i);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (b.getFrequency() > 0L) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee min = i;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (min < 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return Collections. <Bucket> emptyList();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Get last non-empty bucket
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (int i = (len - 1); i >= 0; --i) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee b = buckets.get(i);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (b.getFrequency() > 0L) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee max = i;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // If possible, pad non-empty range with one empty bucket at
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // each end.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (min > 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee --min;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (max < (len - 1)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ++max;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // subList inclusive at low index, exclusive at high index
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return Collections. <Bucket>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee unmodifiableList(buckets).subList(min, max + 1);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee readObject(ObjectInputStream s)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throws IOException, ClassNotFoundException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s.defaultReadObject();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Defensively copy buckets _before_ validating. Subclass
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // validates by calling initialize() after reading any state
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // specific to that subclass needed for validation.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int len = buckets.size();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ArrayList <Bucket> copy = new ArrayList <Bucket> (len);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee copy.addAll(buckets);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buckets = copy;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a string representation of this {@code Distribution} useful
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * for logging and not intended for display. The exact details of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the representation are unspecified and subject to change, but the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * following format may be regarded as typical:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre><code>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * class-name[property1 = value1, property2 = value2]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * </code></pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee toString()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee checkInit();
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee StringBuilder buf = new StringBuilder();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(Distribution.class.getName());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append("[buckets = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee List <Bucket> list = getDisplayRange();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (list.isEmpty()) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append("<empty>");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(Arrays.toString(getDisplayRange().toArray()));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(", total = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(getTotal());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(']');
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buf.toString();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}