]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib/timing - helper for arbitrary percentiles
authorPhil Carmody <phil@dovecot.fi>
Tue, 12 Dec 2017 13:21:17 +0000 (15:21 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 25 Dec 2017 20:27:38 +0000 (22:27 +0200)
Replace fixed 95th %-ile helper with request for arbitrary
percentiles, or even arbitrary fractions of the range.

Signed-off-by: Phil Carmody <phil@dovecot.fi>
src/lib/timing.c
src/lib/timing.h

index 60794cbe33106433a819f0ca9deac3fa6c099e4b..59b4fb06763189aff33ab190c13e5ae69c9d5e85 100644 (file)
@@ -121,7 +121,29 @@ uint64_t timing_get_median(const struct timing *timing)
        return (timing->samples[idx1] + timing->samples[idx2]) / 2;
 }
 
-uint64_t timing_get_95th(const struct timing *timing)
+/* This is independent of the timing framework, useful for any selection task */
+static unsigned int timing_get_index(unsigned int range, double fraction)
+{
+       /* With out of range fractions, we can give the caller what
+          they probably want rather than just crashing. */
+       if (fraction >= 1.)
+               return range - 1;
+       if (fraction <= 0.)
+               return 0;
+
+       double idx_float = range * fraction;
+       unsigned int idx = idx_float; /* C defaults to rounding down */
+       idx_float -= idx;
+       /* Exact boundaries belong to the open range below them.
+          As FP isn't exact, and ratios may be specified inexactly,
+          include a small amount of fuzz around the exact boundary. */
+       if (idx_float < 1e-8*range)
+               idx--;
+
+       return idx;
+}
+
+uint64_t timing_get_percentile(const struct timing *timing, double fraction)
 {
        if (timing->count == 0)
                return 0;
@@ -130,6 +152,6 @@ uint64_t timing_get_95th(const struct timing *timing)
        unsigned int count = (timing->count < timing->sample_count)
                ? timing->count
                : timing->sample_count;
-       unsigned int idx = count - count/20 - 1;
+       unsigned int idx = timing_get_index(count, fraction);
        return timing->samples[idx];
 }
index 0d016b5b0ee7391bc3e8dbee2de437b3a72a9507..065c9b41b1853c594379b42cfb4b3b8612079bf0 100644 (file)
@@ -24,7 +24,13 @@ uint64_t timing_get_max(const struct timing *timing);
 uint64_t timing_get_avg(const struct timing *timing);
 /* Returns events' approximate (through random subsampling) median. */
 uint64_t timing_get_median(const struct timing *timing);
+/* Returns events' approximate (through random subsampling) percentile.
+   fraction parameter is in the range (0., 1.], so 95th %-ile is 0.95. */
+uint64_t timing_get_percentile(const struct timing *timing, double fraction);
 /* Returns events' approximate (through random subsampling) 95th percentile. */
-uint64_t timing_get_95th(const struct timing *timing);
+static inline uint64_t timing_get_95th(const struct timing *timing)
+{
+       return timing_get_percentile(timing, 0.95);
+}
 
 #endif