t/genzipf update
[fio.git] / t / genzipf.c
CommitLineData
6ff38856
JA
1/*
2 * Generate/analyze pareto/zipf distributions to better understand
3 * what an access pattern would look like.
4 *
5 * For instance, the following would generate a zipf distribution
6 * with theta 1.2, using 100,000 values and split the reporting into
7 * 20 buckets:
8 *
9 * t/genzipf zipf 1.2 100000 20
10 *
11 */
12#include <stdio.h>
13#include <stdlib.h>
14#include <fcntl.h>
15#include <string.h>
16
17#include "../lib/zipf.h"
18
19static int val_cmp(const void *p1, const void *p2)
20{
21 const unsigned long *v1 = p1;
22 const unsigned long *v2 = p2;
23
24 return *v1 - *v2;
25}
26
27int main(int argc, char *argv[])
28{
29 unsigned long nranges, output_nranges;
30 unsigned long *vals;
0779dfc8 31 unsigned long i, j, nr_vals, cur_vals, max_val, interval;
6ff38856
JA
32 double *output;
33 struct zipf_state zs;
34 int use_zipf;
35 double val;
36
37 if (argc < 4) {
38 printf("%s: {zipf,pareto} val values [output ranges]\n", argv[0]);
39 return 1;
40 }
41
42 if (!strcmp(argv[1], "zipf"))
43 use_zipf = 1;
44 else if (!strcmp(argv[1], "pareto"))
45 use_zipf = 0;
46 else {
47 printf("Bad distribution type <%s>\n", argv[1]);
48 return 1;
49 }
50
51 val = atof(argv[2]);
52 nranges = strtoul(argv[3], NULL, 10);
53 if (argc == 5)
54 output_nranges = strtoul(argv[4], NULL, 10);
55 else
56 output_nranges = nranges;
57
58 printf("Generating %s distribution with %f input and %lu ranges\n", use_zipf ? "zipf" : "pareto", val, nranges);
59 getchar();
60
61 if (use_zipf)
62 zipf_init(&zs, nranges, val);
63 else
64 pareto_init(&zs, nranges, val);
65
66 vals = malloc(nranges * sizeof(unsigned long));
67
0779dfc8 68 max_val = nr_vals = 0;
6ff38856
JA
69 for (i = 0; i < nranges; i++) {
70 if (use_zipf)
71 vals[nr_vals] = zipf_next(&zs);
72 else
73 vals[nr_vals] = pareto_next(&zs);
74
75 if (vals[nr_vals] > max_val)
76 max_val = vals[nr_vals];
77 nr_vals++;
78 }
79
80 qsort(vals, nr_vals, sizeof(unsigned long), val_cmp);
81
82 interval = (max_val + output_nranges - 1) / output_nranges;
83
84 output = malloc(output_nranges * sizeof(double));
85
0779dfc8 86 for (i = j = 0, cur_vals = 0; i < nr_vals; i++) {
6ff38856 87 if (vals[i] > interval) {
0779dfc8 88 output[j] = (double) (cur_vals + 1) / (double) nr_vals;
6ff38856
JA
89 output[j] *= 100.0;
90 j++;
0779dfc8 91 cur_vals = 0;
6ff38856
JA
92 interval += (max_val + output_nranges - 1) / output_nranges;
93 continue;
94 }
95 cur_vals++;
96 }
97
0779dfc8
JA
98 if (cur_vals) {
99 output[j] = (double) (cur_vals + 1) / (double) nr_vals;
100 output[j] *= 100.0;
101 j++;
102 }
6ff38856
JA
103
104 for (i = 0; i < j; i++)
105 printf("%.2f%%\n", output[i]);
106
107 free(output);
108 free(vals);
109 return 0;
110}