3 * Author: Mingqiang Zhuang
5 * Created on March 25, 2009
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
17 #define array_size(x) (sizeof(x) / sizeof((x)[0]))
19 static int ms_local_log2(uint64_t value
);
20 static uint64_t ms_get_events(ms_stat_t
*stat
);
24 * get the index of local log2 array
28 * @return return the index of local log2 array
30 static int ms_local_log2(uint64_t value
)
34 while (result
<= 63 && ((uint64_t)1 << result
) < value
)
44 * initialize statistic structure
46 * @param stat, pointer of the statistic structure
47 * @param name, name of the statistic
49 void ms_init_stats(ms_stat_t
*stat
, const char *name
)
51 memset(stat
, 0, sizeof(*stat
));
53 stat
->name
= (char *)name
;
54 stat
->min_time
= (uint64_t)-1;
56 stat
->period_min_time
= (uint64_t)-1;
57 stat
->period_max_time
= 0;
60 stat
->pre_total_time
= 0;
64 stat
->pre_log_product
= 0;
66 stat
->pre_get_miss
= 0;
73 * @param stat, pointer of the statistic structure
74 * @param total_time, response time of the command
75 * @param get_miss, whether it gets miss
77 void ms_record_event(ms_stat_t
*stat
, uint64_t total_time
, int get_miss
)
79 stat
->total_time
+= total_time
;
81 if (total_time
< stat
->min_time
)
83 stat
->min_time
= total_time
;
86 if (total_time
> stat
->max_time
)
88 stat
->max_time
= total_time
;
91 if (total_time
< stat
->period_min_time
)
93 stat
->period_min_time
= total_time
;
96 if (total_time
> stat
->period_max_time
)
98 stat
->period_max_time
= total_time
;
106 stat
->dist
[ms_local_log2(total_time
)]++;
107 stat
->squares
+= (double)(total_time
* total_time
);
111 stat
->log_product
+= log((double)total_time
);
113 } /* ms_record_event */
117 * get the events count
119 * @param stat, pointer of the statistic structure
121 * @return total events recorded
123 static uint64_t ms_get_events(ms_stat_t
*stat
)
127 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++)
129 events
+= stat
->dist
[i
];
133 } /* ms_get_events */
137 * dump the statistics
139 * @param stat, pointer of the statistic structure
141 void ms_dump_stats(ms_stat_t
*stat
)
148 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++)
150 events
+= stat
->dist
[i
];
151 if (stat
->dist
[i
] != 0)
153 max_non_zero
= (int)i
;
161 average
= (double)(stat
->total_time
/ events
);
163 printf("%s Statistics (%lld events)\n", stat
->name
, (long long)events
);
164 printf(" Min: %8lld\n", (long long)stat
->min_time
);
165 printf(" Max: %8lld\n", (long long)stat
->max_time
);
166 printf(" Avg: %8lld\n", (long long)(stat
->total_time
/ events
));
167 printf(" Geo: %8.2lf\n", exp(stat
->log_product
/ (double)events
));
171 printf(" Std: %8.2lf\n",
172 sqrt((stat
->squares
- (double)events
* average
173 * average
) / ((double)events
- 1)));
175 printf(" Log2 Dist:");
177 for (int i
= 0; i
<= max_non_zero
- 4; i
+= 4)
179 if ((stat
->dist
[i
+ 0] != 0)
180 || (stat
->dist
[i
+ 1] != 0)
181 || (stat
->dist
[i
+ 2] != 0)
182 || (stat
->dist
[i
+ 3] != 0))
189 for (int i
= min_non_zero
; i
<= max_non_zero
; i
++)
193 printf("\n %2d:", (int)i
);
195 printf(" %6" PRIu64
, stat
->dist
[i
]);
199 } /* ms_dump_stats */
203 * dump the format statistics
205 * @param stat, pointer of the statistic structure
206 * @param run_time, the total run time
207 * @param freq, statistic frequency
208 * @param obj_size, average object size
210 void ms_dump_format_stats(ms_stat_t
*stat
,
216 double global_average
= 0;
217 uint64_t global_tps
= 0;
218 double global_rate
= 0;
219 double global_std
= 0;
220 double global_log
= 0;
222 uint64_t diff_time
= 0;
223 uint64_t diff_events
= 0;
224 double diff_squares
= 0;
225 double diff_log_product
= 0;
226 double period_average
= 0;
227 uint64_t period_tps
= 0;
228 double period_rate
= 0;
229 double period_std
= 0;
230 double period_log
= 0;
232 if ((events
= ms_get_events(stat
)) == 0)
237 global_average
= (double)(stat
->total_time
/ events
);
238 global_tps
= events
/ (uint64_t)run_time
;
239 global_rate
= (double)events
* obj_size
/ 1024 / 1024 / run_time
;
240 global_std
= sqrt((stat
->squares
- (double)events
* global_average
241 * global_average
) / (double)(events
- 1));
242 global_log
= exp(stat
->log_product
/ (double)events
);
244 diff_time
= stat
->total_time
- stat
->pre_total_time
;
245 diff_events
= events
- stat
->pre_events
;
246 if (diff_events
>= 1)
248 period_average
= (double)(diff_time
/ diff_events
);
249 period_tps
= diff_events
/ (uint64_t)freq
;
250 period_rate
= (double)diff_events
* obj_size
/ 1024 / 1024 / freq
;
251 diff_squares
= (double)stat
->squares
- (double)stat
->pre_squares
;
252 period_std
= sqrt((diff_squares
- (double)diff_events
* period_average
253 * period_average
) / (double)(diff_events
- 1));
254 diff_log_product
= stat
->log_product
- stat
->pre_log_product
;
255 period_log
= exp(diff_log_product
/ (double)diff_events
);
258 printf("%s Statistics\n", stat
->name
);
259 printf("%-8s %-8s %-12s %-12s %-10s %-10s %-8s %-10s %-10s %-10s %-10s\n",
273 "%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n",
276 (long long)diff_events
,
277 (long long)period_tps
,
279 (long long)(stat
->get_miss
- stat
->pre_get_miss
),
280 (long long)stat
->period_min_time
,
281 (long long)stat
->period_max_time
,
282 (long long)period_average
,
287 "%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n\n",
291 (long long)global_tps
,
293 (long long)stat
->get_miss
,
294 (long long)stat
->min_time
,
295 (long long)stat
->max_time
,
296 (long long)global_average
,
300 stat
->pre_events
= events
;
301 stat
->pre_squares
= (uint64_t)stat
->squares
;
302 stat
->pre_total_time
= stat
->total_time
;
303 stat
->pre_log_product
= stat
->log_product
;
304 stat
->period_min_time
= (uint64_t)-1;
305 stat
->period_max_time
= 0;
306 stat
->pre_get_miss
= stat
->get_miss
;
307 } /* ms_dump_format_stats */