summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdtrace/common/dt_aggregate.c
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2011-02-08 01:46:16 -0800
committerBryan Cantrill <bryan@joyent.com>2011-02-08 01:46:16 -0800
commit2b6389efff8da018d426952e20428e7e60d568a3 (patch)
tree28fd0bdf18da96241a64b179e3af7e944d76eea3 /usr/src/lib/libdtrace/common/dt_aggregate.c
parentafab0816ecb604f0099a09ad8ee398f0d7b77b1c (diff)
downloadillumos-gate-2b6389efff8da018d426952e20428e7e60d568a3.tar.gz
905 want llquantize() support in DTrace
Reviewed by: Robert Mustacchi <robert.mustacchi@joyent.com> Reviewed by: David Pacheco <dap@joyent.com> Approved by: Garrett D'Amore <garrett@nexenta.com>
Diffstat (limited to 'usr/src/lib/libdtrace/common/dt_aggregate.c')
-rw-r--r--usr/src/lib/libdtrace/common/dt_aggregate.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/usr/src/lib/libdtrace/common/dt_aggregate.c b/usr/src/lib/libdtrace/common/dt_aggregate.c
index 2e66250b88..bb766f71c4 100644
--- a/usr/src/lib/libdtrace/common/dt_aggregate.c
+++ b/usr/src/lib/libdtrace/common/dt_aggregate.c
@@ -24,7 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
#include <stdlib.h>
#include <strings.h>
@@ -204,6 +206,83 @@ dt_aggregate_lquantizedcmp(int64_t *lhs, int64_t *rhs)
return (0);
}
+static void
+dt_aggregate_llquantize(int64_t *existing, int64_t *new, size_t size)
+{
+ int i;
+
+ for (i = 1; i < size / sizeof (int64_t); i++)
+ existing[i] = existing[i] + new[i];
+}
+
+static long double
+dt_aggregate_llquantizedsum(int64_t *llquanta)
+{
+ int64_t arg = *llquanta++;
+ uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(arg);
+ uint16_t low = DTRACE_LLQUANTIZE_LOW(arg);
+ uint16_t high = DTRACE_LLQUANTIZE_HIGH(arg);
+ uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
+ int bin = 0, order;
+ int64_t value = 1, next, step;
+ long double total;
+
+ assert(nsteps >= factor);
+ assert(nsteps % factor == 0);
+
+ for (order = 0; order < low; order++)
+ value *= factor;
+
+ total = (long double)llquanta[bin++] * (long double)(value - 1);
+
+ next = value * factor;
+ step = next > nsteps ? next / nsteps : 1;
+
+ while (order <= high) {
+ assert(value < next);
+ total += (long double)llquanta[bin++] * (long double)(value);
+
+ if ((value += step) != next)
+ continue;
+
+ next = value * factor;
+ step = next > nsteps ? next / nsteps : 1;
+ order++;
+ }
+
+ return (total + (long double)llquanta[bin] * (long double)value);
+}
+
+static int
+dt_aggregate_llquantizedcmp(int64_t *lhs, int64_t *rhs)
+{
+ long double lsum = dt_aggregate_llquantizedsum(lhs);
+ long double rsum = dt_aggregate_llquantizedsum(rhs);
+ int64_t lzero, rzero;
+
+ if (lsum < rsum)
+ return (DT_LESSTHAN);
+
+ if (lsum > rsum)
+ return (DT_GREATERTHAN);
+
+ /*
+ * If they're both equal, then we will compare based on the weights at
+ * zero. If the weights at zero are equal, then this will be judged a
+ * tie and will be resolved based on the key comparison.
+ */
+ lzero = lhs[1];
+ rzero = rhs[1];
+
+ if (lzero < rzero)
+ return (DT_LESSTHAN);
+
+ if (lzero > rzero)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
static int
dt_aggregate_quantizedcmp(int64_t *lhs, int64_t *rhs)
{
@@ -582,6 +661,10 @@ hashnext:
h->dtahe_aggregate = dt_aggregate_lquantize;
break;
+ case DTRACEAGG_LLQUANTIZE:
+ h->dtahe_aggregate = dt_aggregate_llquantize;
+ break;
+
case DTRACEAGG_COUNT:
case DTRACEAGG_SUM:
case DTRACEAGG_AVG:
@@ -849,6 +932,10 @@ dt_aggregate_valcmp(const void *lhs, const void *rhs)
rval = dt_aggregate_lquantizedcmp(laddr, raddr);
break;
+ case DTRACEAGG_LLQUANTIZE:
+ rval = dt_aggregate_llquantizedcmp(laddr, raddr);
+ break;
+
case DTRACEAGG_COUNT:
case DTRACEAGG_SUM:
case DTRACEAGG_MIN: