diff options
author | Bryan Cantrill <bryan@joyent.com> | 2011-02-08 01:46:16 -0800 |
---|---|---|
committer | Bryan Cantrill <bryan@joyent.com> | 2011-02-08 01:46:16 -0800 |
commit | 2b6389efff8da018d426952e20428e7e60d568a3 (patch) | |
tree | 28fd0bdf18da96241a64b179e3af7e944d76eea3 /usr/src/lib/libdtrace/common/dt_aggregate.c | |
parent | afab0816ecb604f0099a09ad8ee398f0d7b77b1c (diff) | |
download | illumos-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.c | 89 |
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: |