diff options
| author | Richard Lowe <richlowe@richlowe.net> | 2011-04-20 01:14:34 -0400 |
|---|---|---|
| committer | Richard Lowe <richlowe@richlowe.net> | 2011-04-20 01:14:34 -0400 |
| commit | ae94d716ff8759d2dc2de680b5b85a291219a4c1 (patch) | |
| tree | 0f523727dd30fc8501cdfb265effcf07b3d7380e /usr/src/lib/libdtrace_jni/java | |
| parent | 49048e7cecf159f9670295fa125e062ebd39bd57 (diff) | |
| download | illumos-joyent-ae94d716ff8759d2dc2de680b5b85a291219a4c1.tar.gz | |
940 llquantize() dreams of JNI
Reviewed by: Albert Lee <trisk@opensolaris.org>
Reviewed by: Gordon Ross <gwr@nexenta.com>
Approved by: Garrett D'Amore <garrett@nexenta.com>
Diffstat (limited to 'usr/src/lib/libdtrace_jni/java')
| -rw-r--r-- | usr/src/lib/libdtrace_jni/java/Makefile | 3 | ||||
| -rw-r--r-- | usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LogLinearDistribution.java | 241 |
2 files changed, 242 insertions, 2 deletions
diff --git a/usr/src/lib/libdtrace_jni/java/Makefile b/usr/src/lib/libdtrace_jni/java/Makefile index 3ecad3d242..90c0eb6b78 100644 --- a/usr/src/lib/libdtrace_jni/java/Makefile +++ b/usr/src/lib/libdtrace_jni/java/Makefile @@ -23,8 +23,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# include $(SRC)/Makefile.master @@ -131,6 +129,7 @@ API_CLASSNAMES=\ LinearDistribution \ LocalConsumer \ LogDistribution \ + LogLinearDistribution \ MaxValue \ MinValue \ NativeException \ diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LogLinearDistribution.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LogLinearDistribution.java new file mode 100644 index 0000000000..8dead05e19 --- /dev/null +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LogLinearDistribution.java @@ -0,0 +1,241 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2011, Richard Lowe + */ + +package org.opensolaris.os.dtrace; + +import java.beans.*; +import java.io.*; +import java.util.*; + +/** + * A log/linear distribution aggregated by the DTrace {@code llquantize()} + * action. Aggregated values are aggregated logarithmicly by order of + * magnitude (between the low and high magnitude arguments of the {@code + * llquantize()} action, but linearly within each order of magnitude bounded + * by the step parameter of the {@code llquantize()} action. + * + * @see LinearDistribution + * @see LogLinearDistribution + * @see Aggregation + */ +public final class LogLinearDistribution extends Distribution + implements Serializable, Comparable <LogLinearDistribution> +{ + static final long serialVersionUID = 6271156690706677711L; + + static final long UINT16_MAX = 0xffff; + + static final long FACTOR_SHIFT = 48; + static final long LOW_SHIFT = 32; + static final long HIGH_SHIFT = 16; + static final long NSTEP_SHIFT = 0; + + private static long unpack(long x, long thing) { + return (x & (UINT16_MAX << thing)) >> thing; + } + + /** @serial */ + private long encValue; + /** @serial */ + private long base; + + static { + try { + BeanInfo info = Introspector.getBeanInfo( + LogLinearDistribution.class); + PersistenceDelegate persistenceDelegate = + new DefaultPersistenceDelegate( + new String[] { "encValue", "base", "buckets" }); + BeanDescriptor d = info.getBeanDescriptor(); + d.setValue("persistenceDelegate", persistenceDelegate); + } catch (IntrospectionException e) { + System.out.println(e); + } + } + + /** + * Called by the native C code + */ + private LogLinearDistribution(long constant, long[] frequencies) { + super(0, constant, frequencies); + encValue = constant; + } + + + /** + * Creates a log/linear distribution with the given parameters, base value + * and frequencies. Used by XML Persistence. + * + * @param enc The encoded representation of the high, low, step and steps + * {@code llquantize()} paramaters. + * @param base The base value of the distirbution + * @param frequencies list of frequencies in each bucket range + */ + public LogLinearDistribution(long enc, long base, + List<Bucket> frequencies) { + super(frequencies); + + encValue = enc; + base = base; + + initialize(); + } + + /** + * Creates a log/linear distribution with the given parameters, base + * values and frequencies. + * + * @param scaleFactor factor + * @param lowMagnitude the low magnitude + * @param highMagnitude the high magnitude + * @param bucketSteps number of linear steps per magnitude + * @param baseVal basue value + * @param frequencies list of frequencies in each bucket range + */ + public LogLinearDistribution(long scaleFactor, long lowMagnitude, + long highMagnitude, long bucketSteps, long baseVal, + List<Bucket> frequencies) { + + super(frequencies); + + encValue = (scaleFactor << FACTOR_SHIFT) | (lowMagnitude << LOW_SHIFT) | + (highMagnitude << HIGH_SHIFT) | (bucketSteps << NSTEP_SHIFT); + base = baseVal; + + initialize(); + } + + private long[][] rangeCache = null; + + private void fillRangeCache(long constant, int len) { + long value = 1; + long next, step; + long low, high, nsteps, factor; + int order, bucket = 0; + + low = unpack(constant, LOW_SHIFT); + high = unpack(constant, HIGH_SHIFT); + nsteps = unpack(constant, NSTEP_SHIFT); + factor = unpack(constant, FACTOR_SHIFT); + + if (rangeCache == null) + rangeCache = new long[len][2]; + + for (order = 0; order < low; order++) + value *= factor; + + base = value; + + rangeCache[bucket][0] = Long.MIN_VALUE; + rangeCache[bucket][1] = value - 1; + bucket++; + + next = value * factor; + step = (next > nsteps) ? (next / nsteps) : 1; + + while (order <= high) { + rangeCache[bucket][0] = value; + rangeCache[bucket][1] = value + step - 1; + bucket++; + + if ((value += step) != next) + continue; + + next = value * factor; + step = (next > nsteps) ? (next / nsteps) : 1; + order++; + } + + rangeCache[bucket][0] = value; + rangeCache[bucket][1] = Long.MAX_VALUE; + } + + /** + * Gets a two element array: the first element is the range minimum + * (inclusive), the second element is the range maximum (inclusive). + */ + @Override + long[] getBucketRange(int i, int len, long base, long constant) { + if (rangeCache == null) + fillRangeCache(constant, len); + + return rangeCache[i]; + } + + @Override + long[] getBucketRange(int i, int len) { + return getBucketRange(i, len, 0, encValue); + } + + public Number getValue() { + double total = 0; + + List<Distribution.Bucket> buckets = getBuckets(); + for (Distribution.Bucket bucket : buckets) + total += ((double)bucket.getFrequency() * (double)bucket.getMin()); + + return (new Double(total)); + } + + private long getZeroBucketValue() { + for (Distribution.Bucket b : this) { + if (b.getMin() == 0) { + return b.getFrequency(); + } + } + return 0; + } + + /** + * Compares the {@code double} values of {@link #getValue()} for overall + * magnitude, and if those are equal, compares frequencies at zero if the + * distrubions includea bucket whose range has a minimum of zero. + */ + public int compareTo(LogLinearDistribution d) { + Number v1 = getValue(); + Number v2 = getValue(); + double d1 = v1.doubleValue(); + double d2 = v2.doubleValue(); + int cmp = (d1 < d2 ? -1 : (d1 > d2 ? 1 : 0)); + + if (cmp == 0) { + long z1 = getZeroBucketValue(); + long z2 = d.getZeroBucketValue(); + cmp = (z1 < z2 ? -1 : (z1 > z2 ? 1 : 0)); + } + return (cmp); + } + + public long getBase() { + return base; + } + + public long getEncValue() { + return encValue; + } + + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + try { + initialize(); + } catch (Exception e) { + InvalidObjectException x = new InvalidObjectException( + e.getMessage()); + x.initCause(e); + throw x; + } + } +} |
