Uncrustify
[awesomized/libmemcached] / clients / ms_stats.c
1 /*
2 * File: ms_stats.h
3 * Author: Mingqiang Zhuang
4 *
5 * Created on March 25, 2009
6 *
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
9 *
10 */
11 #include "ms_stats.h"
12
13 #define array_size(x) (sizeof(x) / sizeof((x)[0]))
14
15 static int ms_local_log2(uint64_t value);
16 static uint64_t ms_get_events(ms_stat_t *stat);
17
18
19 /**
20 * get the index of local log2 array
21 *
22 * @param value
23 *
24 * @return return the index of local log2 array
25 */
26 static int ms_local_log2(uint64_t value)
27 {
28 int result= 0;
29
30 while (result <= 63 && ((uint64_t)1 << result) < value)
31 {
32 result++;
33 }
34
35 return result;
36 } /* ms_local_log2 */
37
38
39 /**
40 * initialize statistic structure
41 *
42 * @param stat, pointer of the statistic structure
43 * @param name, name of the statistic
44 */
45 void ms_init_stats(ms_stat_t *stat, const char *name)
46 {
47 memset(stat, 0, sizeof(*stat));
48
49 stat->name= (char *)name;
50 stat->min_time= (uint64_t)-1;
51 stat->max_time= 0;
52 stat->period_min_time= (uint64_t)-1;
53 stat->period_max_time= 0;
54 stat->log_product= 0;
55 stat->total_time= 0;
56 stat->pre_total_time= 0;
57 stat->squares= 0;
58 stat->pre_squares= 0;
59 stat->pre_events= 0;
60 stat->pre_log_product= 0;
61 stat->get_miss= 0;
62 stat->pre_get_miss= 0;
63 } /* ms_init_stats */
64
65
66 /**
67 * record one event
68 *
69 * @param stat, pointer of the statistic structure
70 * @param total_time, response time of the command
71 * @param get_miss, whether it gets miss
72 */
73 void ms_record_event(ms_stat_t *stat, uint64_t total_time, int get_miss)
74 {
75 stat->total_time+= total_time;
76
77 if (total_time < stat->min_time)
78 {
79 stat->min_time= total_time;
80 }
81
82 if (total_time > stat->max_time)
83 {
84 stat->max_time= total_time;
85 }
86
87 if (total_time < stat->period_min_time)
88 {
89 stat->period_min_time= total_time;
90 }
91
92 if (total_time > stat->period_max_time)
93 {
94 stat->period_max_time= total_time;
95 }
96
97 if (get_miss)
98 {
99 stat->get_miss++;
100 }
101
102 stat->dist[ms_local_log2(total_time)]++;
103 stat->squares+= (double)(total_time * total_time);
104
105 if (total_time != 0)
106 {
107 stat->log_product+= log((double)total_time);
108 }
109 } /* ms_record_event */
110
111
112 /**
113 * get the events count
114 *
115 * @param stat, pointer of the statistic structure
116 *
117 * @return total events recorded
118 */
119 static uint64_t ms_get_events(ms_stat_t *stat)
120 {
121 uint64_t events= 0;
122
123 for (uint32_t i= 0; i < array_size(stat->dist); i++)
124 {
125 events+= stat->dist[i];
126 }
127
128 return events;
129 } /* ms_get_events */
130
131
132 /**
133 * dump the statistics
134 *
135 * @param stat, pointer of the statistic structure
136 */
137 void ms_dump_stats(ms_stat_t *stat)
138 {
139 uint64_t events= 0;
140 int max_non_zero= 0;
141 int min_non_zero= 0;
142 double average= 0;
143
144 for (uint32_t i= 0; i < array_size(stat->dist); i++)
145 {
146 events+= stat->dist[i];
147 if (stat->dist[i] != 0)
148 {
149 max_non_zero= (int)i;
150 }
151 }
152
153 if (events == 0)
154 {
155 return;
156 }
157 average= (double)(stat->total_time / events);
158
159 printf("%s Statistics (%lld events)\n", stat->name, (long long)events);
160 printf(" Min: %8lld\n", (long long)stat->min_time);
161 printf(" Max: %8lld\n", (long long)stat->max_time);
162 printf(" Avg: %8lld\n", (long long)(stat->total_time / events));
163 printf(" Geo: %8.2lf\n", exp(stat->log_product / (double)events));
164
165 if (events > 1)
166 {
167 printf(" Std: %8.2lf\n",
168 sqrt((stat->squares - (double)events * average
169 * average) / ((double)events - 1)));
170 }
171 printf(" Log2 Dist:");
172
173 for (int i= 0; i <= max_non_zero - 4; i+= 4)
174 {
175 if ((stat->dist[i + 0] != 0)
176 || (stat->dist[i + 1] != 0)
177 || (stat->dist[i + 2] != 0)
178 || (stat->dist[i + 3] != 0))
179 {
180 min_non_zero= i;
181 break;
182 }
183 }
184
185 for (int i= min_non_zero; i <= max_non_zero; i++)
186 {
187 if ((i % 4) == 0)
188 {
189 printf("\n %2d:", (int)i);
190 }
191 printf(" %6ld", stat->dist[i]);
192 }
193
194 printf("\n\n");
195 } /* ms_dump_stats */
196
197
198 /**
199 * dump the format statistics
200 *
201 * @param stat, pointer of the statistic structure
202 * @param run_time, the total run time
203 * @param freq, statistic frequency
204 * @param obj_size, average object size
205 */
206 void ms_dump_format_stats(ms_stat_t *stat,
207 int run_time,
208 int freq,
209 int obj_size)
210 {
211 uint64_t events= 0;
212 double global_average= 0;
213 uint64_t global_tps= 0;
214 double global_rate= 0;
215 double global_std= 0;
216 double global_log= 0;
217
218 uint64_t diff_time= 0;
219 uint64_t diff_events= 0;
220 double diff_squares= 0;
221 double diff_log_product= 0;
222 double period_average= 0;
223 uint64_t period_tps= 0;
224 double period_rate= 0;
225 double period_std= 0;
226 double period_log= 0;
227
228 if ((events= ms_get_events(stat)) == 0)
229 {
230 return;
231 }
232
233 global_average= (double)(stat->total_time / events);
234 global_tps= events / (uint64_t)run_time;
235 global_rate= (double)events * obj_size / 1024 / 1024 / run_time;
236 global_std= sqrt((stat->squares - (double)events * global_average
237 * global_average) / (double)(events - 1));
238 global_log= exp(stat->log_product / (double)events);
239
240 diff_time= stat->total_time - stat->pre_total_time;
241 diff_events= events - stat->pre_events;
242 if (diff_events >= 1)
243 {
244 period_average= (double)(diff_time / diff_events);
245 period_tps= diff_events / (uint64_t)freq;
246 period_rate= (double)diff_events * obj_size / 1024 / 1024 / freq;
247 diff_squares= (double)stat->squares - (double)stat->pre_squares;
248 period_std= sqrt((diff_squares - (double)diff_events * period_average
249 * period_average) / (double)(diff_events - 1));
250 diff_log_product= stat->log_product - stat->pre_log_product;
251 period_log= exp(diff_log_product / (double)diff_events);
252 }
253
254 printf("%s Statistics\n", stat->name);
255 printf("%-8s %-8s %-12s %-12s %-10s %-10s %-8s %-10s %-10s %-10s %-10s\n",
256 "Type",
257 "Time(s)",
258 "Ops",
259 "TPS(ops/s)",
260 "Net(M/s)",
261 "Get_miss",
262 "Min(us)",
263 "Max(us)",
264 "Avg(us)",
265 "Std_dev",
266 "Geo_dist");
267
268 printf(
269 "%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n",
270 "Period",
271 freq,
272 (long long)diff_events,
273 (long long)period_tps,
274 global_rate,
275 (long long)(stat->get_miss - stat->pre_get_miss),
276 (long long)stat->period_min_time,
277 (long long)stat->period_max_time,
278 (long long)period_average,
279 period_std,
280 period_log);
281
282 printf(
283 "%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n\n",
284 "Global",
285 run_time,
286 (long long)events,
287 (long long)global_tps,
288 period_rate,
289 (long long)stat->get_miss,
290 (long long)stat->min_time,
291 (long long)stat->max_time,
292 (long long)global_average,
293 global_std,
294 global_log);
295
296 stat->pre_events= events;
297 stat->pre_squares= (uint64_t)stat->squares;
298 stat->pre_total_time= stat->total_time;
299 stat->pre_log_product= stat->log_product;
300 stat->period_min_time= (uint64_t)-1;
301 stat->period_max_time= 0;
302 stat->pre_get_miss= stat->get_miss;
303 } /* ms_dump_format_stats */