Mercurial > dovecot > core-2.2
changeset 20875:6ea20f3d4912
lib-fs: Lazily initialize timings to save memory.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 17 Oct 2016 09:13:39 +0300 |
parents | bd50f85d0442 |
children | 1cd9d3679d04 |
files | src/lib-fs/fs-api.c |
diffstat | 1 files changed, 34 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-fs/fs-api.c Fri Oct 14 17:13:23 2016 +0300 +++ b/src/lib-fs/fs-api.c Mon Oct 17 09:13:39 2016 +0300 @@ -134,7 +134,6 @@ { const struct fs *fs_class; const char *temp_file_prefix; - unsigned int i; fs_class = fs_class_find(driver); if (fs_class == NULL) { @@ -150,9 +149,6 @@ if (fs_alloc(fs_class, args, set, fs_r, error_r) < 0) return -1; - for (i = 0; i < FS_OP_COUNT; i++) - (*fs_r)->stats.timings[i] = timing_init(); - temp_file_prefix = set->temp_file_prefix != NULL ? set->temp_file_prefix : ".temp.dovecot"; (*fs_r)->temp_path_prefix = i_strconcat(set->temp_dir, "/", @@ -195,8 +191,10 @@ i_free(fs->username); i_free(fs->session_id); i_free(fs->temp_path_prefix); - for (i = 0; i < FS_OP_COUNT; i++) - timing_deinit(&fs->stats.timings[i]); + for (i = 0; i < FS_OP_COUNT; i++) { + if (fs->stats.timings[i] != NULL) + timing_deinit(&fs->stats.timings[i]); + } T_BEGIN { fs->v.deinit(fs); } T_END; @@ -347,7 +345,7 @@ } static void -fs_timing_end(struct timing *timing, const struct timeval *start_tv) +fs_timing_end(struct timing **timing, const struct timeval *start_tv) { struct timeval now; long long diff; @@ -356,8 +354,11 @@ i_fatal("gettimeofday() failed: %m"); diff = timeval_diff_usecs(&now, start_tv); - if (diff > 0) - timing_add_usecs(timing, diff); + if (diff > 0) { + if (*timing == NULL) + *timing = timing_init(); + timing_add_usecs(*timing, diff); + } } void fs_file_timing_end(struct fs_file *file, enum fs_op op) @@ -365,7 +366,7 @@ if (!file->fs->set.enable_timing || file->timing_start[op].tv_sec == 0) return; - fs_timing_end(file->fs->stats.timings[op], &file->timing_start[op]); + fs_timing_end(&file->fs->stats.timings[op], &file->timing_start[op]); /* don't count this again */ file->timing_start[op].tv_sec = 0; } @@ -1068,7 +1069,7 @@ /* first result returned - count this as the finish time, since we don't want to count the time caller spends on this iteration. */ - fs_timing_end(iter->fs->stats.timings[FS_OP_ITER], &iter->start_time); + fs_timing_end(&iter->fs->stats.timings[FS_OP_ITER], &iter->start_time); /* don't count this again */ iter->start_time.tv_sec = 0; } @@ -1119,20 +1120,32 @@ errno = EAGAIN; } +static uint64_t +fs_stats_count_ops(const struct fs_stats *stats, const enum fs_op ops[], + unsigned int ops_count) +{ + uint64_t ret = 0; + + for (unsigned int i = 0; i < ops_count; i++) { + if (stats->timings[ops[i]] != NULL) + ret += timing_get_sum(stats->timings[ops[i]]); + } + return ret; +} + uint64_t fs_stats_get_read_usecs(const struct fs_stats *stats) { - return timing_get_sum(stats->timings[FS_OP_METADATA]) + - timing_get_sum(stats->timings[FS_OP_PREFETCH]) + - timing_get_sum(stats->timings[FS_OP_READ]) + - timing_get_sum(stats->timings[FS_OP_EXISTS]) + - timing_get_sum(stats->timings[FS_OP_STAT]) + - timing_get_sum(stats->timings[FS_OP_ITER]); + const enum fs_op read_ops[] = { + FS_OP_METADATA, FS_OP_PREFETCH, FS_OP_READ, FS_OP_EXISTS, + FS_OP_STAT, FS_OP_ITER + }; + return fs_stats_count_ops(stats, read_ops, N_ELEMENTS(read_ops)); } uint64_t fs_stats_get_write_usecs(const struct fs_stats *stats) { - return timing_get_sum(stats->timings[FS_OP_WRITE]) + - timing_get_sum(stats->timings[FS_OP_COPY]) + - timing_get_sum(stats->timings[FS_OP_DELETE]); + const enum fs_op write_ops[] = { + FS_OP_WRITE, FS_OP_COPY, FS_OP_DELETE + }; + return fs_stats_count_ops(stats, write_ops, N_ELEMENTS(write_ops)); } -