38
38
pool_t prev_pool, cur_pool;
39
39
/* id => struct top_line. */
40
struct hash_table *sessions;
41
ARRAY_DEFINE(lines, struct top_line *);
40
HASH_TABLE(char *, struct top_line *) sessions;
41
ARRAY(struct top_line *) lines;
42
42
int (*lines_sort)(struct top_line *const *, struct top_line *const *);
44
44
unsigned int last_update_idx, user_idx;
203
203
static void stats_drop_stale(struct top_context *ctx)
205
205
struct hash_iterate_context *iter;
207
struct top_line *line;
208
209
iter = hash_table_iterate_init(ctx->sessions);
209
while (hash_table_iterate(iter, &key, &value)) {
210
struct top_line *line = value;
210
while (hash_table_iterate(iter, ctx->sessions, &id, &line)) {
212
211
if (line->flip != ctx->flip)
213
hash_table_remove(ctx->sessions, key);
212
hash_table_remove(ctx->sessions, id);
215
214
hash_table_iterate_deinit(&iter);
389
388
if (str_to_uint64(line->prev_values[i], &prev_num) == 0 &&
390
389
str_to_uint64(line->cur_values[i], &cur_num) == 0) {
391
i_snprintf(numstr, sizeof(numstr), "%llu",
392
(unsigned long long)(cur_num - prev_num));
390
if (i_snprintf(numstr, sizeof(numstr), "%llu",
391
(unsigned long long)(cur_num - prev_num)) < 0)
393
393
doveadm_print(numstr);
394
394
} else if (get_double(line->prev_values[i], &prev_double) == 0 &&
395
395
get_double(line->cur_values[i], &cur_double) == 0 &&
396
396
get_double(line->prev_values[ctx->last_update_idx], &prev_time) == 0 &&
397
397
get_double(line->cur_values[ctx->last_update_idx], &cur_time) == 0) {
399
i_snprintf(numstr, sizeof(numstr), "%d",
400
(int)((cur_double - prev_double) *
401
(cur_time - prev_time) * 100));
399
if (i_snprintf(numstr, sizeof(numstr), "%d",
400
(int)((cur_double - prev_double) *
401
(cur_time - prev_time) * 100)) < 0)
402
403
doveadm_print(numstr);
404
405
doveadm_print(line->cur_values[i]);
438
439
for (i = 0; i < N_ELEMENTS(names); i++) {
439
440
if (!stats_header_find(ctx, names[i], &indexes[i]))
441
indexes[i] = UINT_MAX;
443
444
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
447
448
lines = array_get(&ctx->lines, &count);
448
449
for (i = 0, row = 1; row < maxrow && i < count; i++, row++) {
449
450
for (j = 0; j < N_ELEMENTS(names); j++) {
450
if (indexes[j] == -1U)
451
if (indexes[j] == UINT_MAX)
451
452
doveadm_print("?");
453
454
stats_top_output_diff(ctx, lines[i], indexes[j]);
475
476
ctx.prev_pool = pool_alloconly_create("stats top", 1024*16);
476
477
ctx.cur_pool = pool_alloconly_create("stats top", 1024*16);
477
478
i_array_init(&ctx.lines, 128);
479
hash_table_create(default_pool, default_pool, 0,
480
str_hash, (hash_cmp_callback_t *)strcmp);
479
hash_table_create(&ctx.sessions, default_pool, 0, str_hash, strcmp);
481
480
net_set_nonblock(ctx.fd, FALSE);
483
482
ctx.input = i_stream_create_fd(ctx.fd, (size_t)-1, TRUE);