Commit | Line | Data |
---|---|---|
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 | * | |
f880b1f6 JA |
11 | * Only the distribution type (zipf or pareto) and spread input need |
12 | * to be given, if not given defaults are used. | |
13 | * | |
6ff38856 JA |
14 | */ |
15 | #include <stdio.h> | |
16 | #include <stdlib.h> | |
17 | #include <fcntl.h> | |
18 | #include <string.h> | |
19 | ||
20 | #include "../lib/zipf.h" | |
21 | ||
f880b1f6 JA |
22 | #define DEF_NR 1000000 |
23 | #define DEF_NR_OUTPUT 23 | |
24 | ||
6ff38856 JA |
25 | static int val_cmp(const void *p1, const void *p2) |
26 | { | |
27 | const unsigned long *v1 = p1; | |
28 | const unsigned long *v2 = p2; | |
29 | ||
30 | return *v1 - *v2; | |
31 | } | |
32 | ||
33 | int main(int argc, char *argv[]) | |
34 | { | |
35 | unsigned long nranges, output_nranges; | |
36 | unsigned long *vals; | |
0779dfc8 | 37 | unsigned long i, j, nr_vals, cur_vals, max_val, interval; |
f880b1f6 | 38 | double *output, perc, perc_i; |
6ff38856 JA |
39 | struct zipf_state zs; |
40 | int use_zipf; | |
41 | double val; | |
42 | ||
f880b1f6 | 43 | if (argc < 3) { |
6ff38856 JA |
44 | printf("%s: {zipf,pareto} val values [output ranges]\n", argv[0]); |
45 | return 1; | |
46 | } | |
47 | ||
48 | if (!strcmp(argv[1], "zipf")) | |
49 | use_zipf = 1; | |
50 | else if (!strcmp(argv[1], "pareto")) | |
51 | use_zipf = 0; | |
52 | else { | |
53 | printf("Bad distribution type <%s>\n", argv[1]); | |
54 | return 1; | |
55 | } | |
56 | ||
57 | val = atof(argv[2]); | |
f880b1f6 JA |
58 | |
59 | nranges = DEF_NR; | |
60 | output_nranges = DEF_NR_OUTPUT; | |
61 | ||
62 | if (argc >= 4) | |
63 | nranges = strtoul(argv[3], NULL, 10); | |
64 | if (argc >= 5) | |
6ff38856 | 65 | output_nranges = strtoul(argv[4], NULL, 10); |
6ff38856 | 66 | |
f880b1f6 | 67 | printf("Generating %s distribution with %f input and %lu ranges.\n", use_zipf ? "zipf" : "pareto", val, nranges); |
6ff38856 JA |
68 | |
69 | if (use_zipf) | |
70 | zipf_init(&zs, nranges, val); | |
71 | else | |
72 | pareto_init(&zs, nranges, val); | |
73 | ||
74 | vals = malloc(nranges * sizeof(unsigned long)); | |
75 | ||
0779dfc8 | 76 | max_val = nr_vals = 0; |
6ff38856 JA |
77 | for (i = 0; i < nranges; i++) { |
78 | if (use_zipf) | |
79 | vals[nr_vals] = zipf_next(&zs); | |
80 | else | |
81 | vals[nr_vals] = pareto_next(&zs); | |
82 | ||
83 | if (vals[nr_vals] > max_val) | |
84 | max_val = vals[nr_vals]; | |
85 | nr_vals++; | |
86 | } | |
87 | ||
88 | qsort(vals, nr_vals, sizeof(unsigned long), val_cmp); | |
89 | ||
90 | interval = (max_val + output_nranges - 1) / output_nranges; | |
91 | ||
92 | output = malloc(output_nranges * sizeof(double)); | |
93 | ||
0779dfc8 | 94 | for (i = j = 0, cur_vals = 0; i < nr_vals; i++) { |
6ff38856 | 95 | if (vals[i] > interval) { |
0779dfc8 | 96 | output[j] = (double) (cur_vals + 1) / (double) nr_vals; |
6ff38856 JA |
97 | output[j] *= 100.0; |
98 | j++; | |
0779dfc8 | 99 | cur_vals = 0; |
6ff38856 JA |
100 | interval += (max_val + output_nranges - 1) / output_nranges; |
101 | continue; | |
102 | } | |
103 | cur_vals++; | |
104 | } | |
105 | ||
0779dfc8 JA |
106 | if (cur_vals) { |
107 | output[j] = (double) (cur_vals + 1) / (double) nr_vals; | |
108 | output[j] *= 100.0; | |
109 | j++; | |
110 | } | |
6ff38856 | 111 | |
f880b1f6 JA |
112 | perc_i = 100.0 / (double) output_nranges; |
113 | perc = 0.0; | |
114 | for (i = 0; i < j; i++) { | |
115 | printf("%6.2f%% -> %6.2f%%:\t%6.2f%%\n", perc, perc + perc_i, output[i]); | |
116 | perc += perc_i; | |
117 | } | |
6ff38856 JA |
118 | |
119 | free(output); | |
120 | free(vals); | |
121 | return 0; | |
122 | } |