summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdtrace_jni/java
diff options
context:
space:
mode:
authorRichard Lowe <richlowe@richlowe.net>2011-04-20 01:14:34 -0400
committerRichard Lowe <richlowe@richlowe.net>2011-04-20 01:14:34 -0400
commitae94d716ff8759d2dc2de680b5b85a291219a4c1 (patch)
tree0f523727dd30fc8501cdfb265effcf07b3d7380e /usr/src/lib/libdtrace_jni/java
parent49048e7cecf159f9670295fa125e062ebd39bd57 (diff)
downloadillumos-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/Makefile3
-rw-r--r--usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LogLinearDistribution.java241
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;
+ }
+ }
+}