struct histogram {
unsigned *data;
+ unsigned out_below, out_above;
unsigned allocated;
unsigned resolution;
};
size_t mem;
h->allocated = max_value/resolution + 1;
h->resolution = resolution;
+ h->out_below = h->out_above = 0;
mem = h->allocated*sizeof(*h->data);
h->data = malloc(mem);
if (h->data) {
return -1;
}
-void histogram_add(struct histogram *h, unsigned value)
+void histogram_add(struct histogram *h, int value)
{
+ if (value < 0) {
+ h->out_below++;
+ return;
+ }
unsigned index = value / h->resolution;
- if (index >= h->allocated)
+ if (index >= h->allocated) {
+ h->out_above++;
index = h->allocated - 1;
+ }
h->data[index]++;
}
{
unsigned long long sum = 0, cum;
unsigned i;
+
+ if (!f)
+ return;
+
for (i = 0; i < h->allocated; i++)
sum += h->data[i];
cum = sum;
}
+struct histogram_stats {
+ unsigned count;
+ unsigned long long sum;
+ unsigned avg;
+ unsigned below, above; /* Count of data out of histogram range */
+ unsigned percentile[101];
+};
+
+void histogram_stats(struct histogram *h, struct histogram_stats *s)
+{
+ unsigned long long sum;
+ unsigned i, j;
+
+ if (!s)
+ return;
+
+ memset(s, 0, sizeof(*s));
+
+ for (i = 0; i < h->allocated; i++) {
+ s->count += h->data[i];
+ s->sum += h->data[i] * i * h->resolution;
+ }
+ if (s->count == 0)
+ return;
+
+ s->avg = s->sum / s->count;
+
+ for (i = 0, j = 0, sum = 0; i < 100; i++) {
+ while (sum <= i * s->count / 100)
+ sum += h->data[j++];
+
+ s->percentile[i] = (j-1) * h->resolution;
+ }
+ while (sum < i * s->count / 100)
+ sum += h->data[j++];
+ s->percentile[100] = (j-1) * h->resolution;
+
+ s->below = h->out_below;
+ s->above = h->out_above;
+}
#endif