dce5ed8bec49ad94f58d185528a873a7f15e6888
2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
16 #include "mem_config.h"
21 #define array_size(x) (sizeof(x) / sizeof((x)[0]))
23 static int ms_local_log2(uint64_t value
);
24 static uint64_t ms_get_events(ms_stat_t
*stat
);
27 * get the index of local log2 array
31 * @return return the index of local log2 array
33 static int ms_local_log2(uint64_t value
) {
36 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
) {
50 memset(stat
, 0, sizeof(*stat
));
52 stat
->name
= (char *) name
;
53 stat
->min_time
= (uint64_t) -1;
55 stat
->period_min_time
= (uint64_t) -1;
56 stat
->period_max_time
= 0;
57 stat
->log_product
= 0;
59 stat
->pre_total_time
= 0;
61 stat
->pre_squares
= 0;
63 stat
->pre_log_product
= 0;
65 stat
->pre_get_miss
= 0;
71 * @param stat, pointer of the statistic structure
72 * @param total_time, response time of the command
73 * @param get_miss, whether it gets miss
75 void ms_record_event(ms_stat_t
*stat
, uint64_t total_time
, int get_miss
) {
76 stat
->total_time
+= total_time
;
78 if (total_time
< stat
->min_time
) {
79 stat
->min_time
= total_time
;
82 if (total_time
> stat
->max_time
) {
83 stat
->max_time
= total_time
;
86 if (total_time
< stat
->period_min_time
) {
87 stat
->period_min_time
= total_time
;
90 if (total_time
> stat
->period_max_time
) {
91 stat
->period_max_time
= total_time
;
98 stat
->dist
[ms_local_log2(total_time
)]++;
99 stat
->squares
+= (double) (total_time
* total_time
);
102 stat
->log_product
+= log((double) total_time
);
104 } /* ms_record_event */
107 * get the events count
109 * @param stat, pointer of the statistic structure
111 * @return total events recorded
113 static uint64_t ms_get_events(ms_stat_t
*stat
) {
116 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++) {
117 events
+= stat
->dist
[i
];
121 } /* ms_get_events */
124 * dump the statistics
126 * @param stat, pointer of the statistic structure
128 void ms_dump_stats(ms_stat_t
*stat
) {
130 int max_non_zero
= 0;
131 int min_non_zero
= 0;
134 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++) {
135 events
+= stat
->dist
[i
];
137 max_non_zero
= (int) i
;
144 average
= (double) (stat
->total_time
/ events
);
146 printf("%s Statistics (%lld events)\n", stat
->name
, (long long) events
);
147 printf(" Min: %8lld\n", (long long) stat
->min_time
);
148 printf(" Max: %8lld\n", (long long) stat
->max_time
);
149 printf(" Avg: %8lld\n", (long long) (stat
->total_time
/ events
));
150 printf(" Geo: %8.2lf\n", exp(stat
->log_product
/ (double) events
));
153 printf(" Std: %8.2lf\n",
154 sqrt((stat
->squares
- (double) events
* average
* average
) / ((double) events
- 1)));
156 printf(" Log2 Dist:");
158 for (int i
= 0; i
<= max_non_zero
- 4; i
+= 4) {
159 if ((stat
->dist
[i
+ 0]) || (stat
->dist
[i
+ 1]) || (stat
->dist
[i
+ 2])
160 || (stat
->dist
[i
+ 3]))
167 for (int i
= min_non_zero
; i
<= max_non_zero
; i
++) {
169 printf("\n %2d:", (int) i
);
171 printf(" %6" PRIu64
, stat
->dist
[i
]);
175 } /* ms_dump_stats */
178 * dump the format statistics
180 * @param stat, pointer of the statistic structure
181 * @param run_time, the total run time
182 * @param freq, statistic frequency
183 * @param obj_size, average object size
185 void ms_dump_format_stats(ms_stat_t
*stat
, int run_time
, int freq
, int obj_size
) {
187 double global_average
= 0;
188 uint64_t global_tps
= 0;
189 double global_rate
= 0;
190 double global_std
= 0;
191 double global_log
= 0;
193 double period_average
= 0;
194 uint64_t period_tps
= 0;
195 double period_rate
= 0;
196 double period_std
= 0;
197 double period_log
= 0;
199 if ((events
= ms_get_events(stat
)) == 0) {
203 global_average
= (double) (stat
->total_time
/ events
);
204 global_tps
= events
/ (uint64_t) run_time
;
205 global_rate
= (double) events
* obj_size
/ 1024 / 1024 / run_time
;
206 global_std
= sqrt((stat
->squares
- (double) events
* global_average
* global_average
)
207 / (double) (events
- 1));
208 global_log
= exp(stat
->log_product
/ (double) events
);
210 uint64_t diff_time
= stat
->total_time
- stat
->pre_total_time
;
211 uint64_t diff_events
= events
- stat
->pre_events
;
212 if (diff_events
>= 1) {
213 period_average
= (double) (diff_time
/ diff_events
);
214 period_tps
= diff_events
/ (uint64_t) freq
;
215 period_rate
= (double) diff_events
* obj_size
/ 1024 / 1024 / freq
;
216 double diff_squares
= (double) stat
->squares
- (double) stat
->pre_squares
;
217 period_std
= sqrt((diff_squares
- (double) diff_events
* period_average
* period_average
)
218 / (double) (diff_events
- 1));
219 double diff_log_product
= stat
->log_product
- stat
->pre_log_product
;
220 period_log
= exp(diff_log_product
/ (double) diff_events
);
223 printf("%s Statistics\n", stat
->name
);
224 printf("%-8s %-8s %-12s %-12s %-10s %-10s %-8s %-10s %-10s %-10s %-10s\n", "Type", "Time(s)",
225 "Ops", "TPS(ops/s)", "Net(M/s)", "Get_miss", "Min(us)", "Max(us)", "Avg(us)", "Std_dev",
228 printf("%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n",
229 "Period", freq
, (long long) diff_events
, (long long) period_tps
, global_rate
,
230 (long long) (stat
->get_miss
- stat
->pre_get_miss
), (long long) stat
->period_min_time
,
231 (long long) stat
->period_max_time
, (long long) period_average
, period_std
, period_log
);
233 printf("%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n\n",
234 "Global", run_time
, (long long) events
, (long long) global_tps
, period_rate
,
235 (long long) stat
->get_miss
, (long long) stat
->min_time
, (long long) stat
->max_time
,
236 (long long) global_average
, global_std
, global_log
);
238 stat
->pre_events
= events
;
239 stat
->pre_squares
= (uint64_t) stat
->squares
;
240 stat
->pre_total_time
= stat
->total_time
;
241 stat
->pre_log_product
= stat
->log_product
;
242 stat
->period_min_time
= (uint64_t) -1;
243 stat
->period_max_time
= 0;
244 stat
->pre_get_miss
= stat
->get_miss
;
245 } /* ms_dump_format_stats */