latester: Add statistics about data out of histogram range
[can-benchmark.git] / latester / histogram.h
1 #ifndef HISTOGRAM_H
2 #define HISTOGRAM_H
3
4 struct histogram {
5         unsigned *data;
6         unsigned out_below, out_above;
7         unsigned allocated;
8         unsigned resolution;
9 };
10
11 int histogram_init(struct histogram *h,
12                    unsigned max_value,
13                    unsigned resolution)
14 {
15         size_t mem;
16         h->allocated = max_value/resolution + 1;
17         h->resolution = resolution;
18         h->out_below = h->out_above = 0;
19         mem = h->allocated*sizeof(*h->data);
20         h->data = malloc(mem);
21         if (h->data) {
22                 memset(h->data, 0, mem);
23                 return 0;
24         } else
25                 return -1;
26 }
27
28 void histogram_add(struct histogram *h, int value)
29 {
30         if (value < 0) {
31                 h->out_below++;
32                 return;
33         }
34         unsigned index = value / h->resolution;
35         if (index >= h->allocated) {
36                 h->out_above++;
37                 index = h->allocated - 1;
38         }
39         h->data[index]++;
40 }
41
42 void histogram_fprint(struct histogram *h, FILE *f)
43 {
44         unsigned long long sum = 0, cum;
45         unsigned i;
46
47         if (!f)
48                 return;
49
50         for (i = 0; i < h->allocated; i++)
51                 sum += h->data[i];
52         cum = sum;
53         for (i = 0; i < h->allocated; i++) {
54                 if (h->data[i] != 0) {
55                         fprintf(f, "%g %lld\n", 1e-3*(i*h->resolution), cum);
56                 }
57                 cum -= h->data[i];
58         }
59 }
60
61
62 struct histogram_stats {
63         unsigned count;
64         unsigned long long sum;
65         unsigned avg;
66         unsigned below, above;  /* Count of data out of histogram range */
67         unsigned percentile[101];
68 };
69
70 void histogram_stats(struct histogram *h, struct histogram_stats *s)
71 {
72         unsigned long long sum;
73         unsigned i, j;
74
75         if (!s)
76                 return;
77
78         memset(s, 0, sizeof(*s));
79
80         for (i = 0; i < h->allocated; i++) {
81                 s->count += h->data[i];
82                 s->sum += h->data[i] * i * h->resolution;
83         }
84         if (s->count == 0)
85                 return;
86
87         s->avg = s->sum / s->count;
88
89         for (i = 0, j = 0, sum = 0; i < 100; i++) {
90                 while (sum <= i * s->count / 100)
91                         sum += h->data[j++];
92
93                 s->percentile[i] = (j-1) * h->resolution;
94         }
95         while (sum < i * s->count / 100)
96                 sum += h->data[j++];
97         s->percentile[100] = (j-1) * h->resolution;
98
99         s->below = h->out_below;
100         s->above = h->out_above;
101 }
102
103 #endif