Mercurial > dovecot > core-2.2
changeset 10868:863eafcf8428 HEAD
mdbox: Removed mdbox_max_open_files setting.
It's now hard coded to 2, and the files are closed after 30 seconds of being
unused.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 08 Mar 2010 20:28:08 +0200 |
parents | c56358283605 |
children | bf978f2de0fd |
files | src/lib-storage/index/dbox-multi/mdbox-file.c src/lib-storage/index/dbox-multi/mdbox-file.h src/lib-storage/index/dbox-multi/mdbox-settings.c src/lib-storage/index/dbox-multi/mdbox-settings.h src/lib-storage/index/dbox-multi/mdbox-storage.c src/lib-storage/index/dbox-multi/mdbox-storage.h |
diffstat | 6 files changed, 68 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-multi/mdbox-file.c Mon Mar 08 19:57:21 2010 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-file.c Mon Mar 08 20:28:08 2010 +0200 @@ -26,18 +26,13 @@ static struct mdbox_file * mdbox_find_and_move_open_file(struct mdbox_storage *storage, uint32_t file_id) { - struct mdbox_file *const *files, *file; + struct mdbox_file *const *files; unsigned int i, count; files = array_get(&storage->open_files, &count); for (i = 0; i < count; i++) { - if (files[i]->file_id == file_id) { - /* move to last in the array */ - file = files[i]; - array_delete(&storage->open_files, i, 1); - array_append(&storage->open_files, &file, 1); - return file; - } + if (files[i]->file_id == file_id) + return files[i]; } return NULL; } @@ -127,9 +122,9 @@ } count = array_count(&storage->open_files); - if (count > storage->set->mdbox_max_open_files) { - mdbox_close_open_files(storage, count - - storage->set->mdbox_max_open_files); + if (count > MDBOX_MAX_OPEN_UNUSED_FILES) { + mdbox_close_open_files(storage, + count - MDBOX_MAX_OPEN_UNUSED_FILES); } file = i_new(struct mdbox_file, 1); @@ -187,6 +182,53 @@ return 0; } +static struct mdbox_file * +mdbox_find_oldest_unused_file(struct mdbox_storage *storage, + unsigned int *idx_r) +{ + struct mdbox_file *const *files, *oldest_file = NULL; + unsigned int i, count; + + files = array_get(&storage->open_files, &count); + *idx_r = count; + for (i = 0; i < count; i++) { + if (files[i]->file.refcount == 0) { + if (oldest_file == NULL || + files[i]->close_time < oldest_file->close_time) { + oldest_file = files[i]; + *idx_r = i; + } + } + } + return oldest_file; +} + +static void mdbox_file_close_timeout(struct mdbox_storage *storage) +{ + struct mdbox_file *oldest; + unsigned int i; + time_t close_time = ioloop_time - MDBOX_CLOSE_UNUSED_FILES_TIMEOUT_SECS; + + while ((oldest = mdbox_find_oldest_unused_file(storage, &i)) != NULL) { + if (oldest->close_time > close_time) + break; + array_delete(&storage->open_files, i, 1); + dbox_file_free(&oldest->file); + } + + if (oldest == NULL) + timeout_remove(&storage->to_close_unused_files); +} + +static void mdbox_file_close_later(struct mdbox_file *mfile) +{ + if (mfile->storage->to_close_unused_files == NULL) { + mfile->storage->to_close_unused_files = + timeout_add(MDBOX_CLOSE_UNUSED_FILES_TIMEOUT_SECS*1000, + mdbox_file_close_timeout, mfile->storage); + } +} + void mdbox_file_unrefed(struct dbox_file *file) { struct mdbox_file *mfile = (struct mdbox_file *)file; @@ -195,24 +237,23 @@ /* don't cache metadata seeks while file isn't being referenced */ file->metadata_read_offset = (uoff_t)-1; + mfile->close_time = ioloop_time; if (mfile->file_id != 0) { files = array_get(&mfile->storage->open_files, &count); - if (!file->deleted && - count <= mfile->storage->set->mdbox_max_open_files) { + if (!file->deleted && count <= MDBOX_MAX_OPEN_UNUSED_FILES) { /* we can leave this file open for now */ + mdbox_file_close_later(mfile); return; } /* close the oldest file with refcount=0 */ - for (i = 0; i < count; i++) { - if (files[i]->file.refcount == 0) - break; - } - oldest_file = files[i]; + oldest_file = mdbox_find_oldest_unused_file(mfile->storage, &i); + i_assert(oldest_file != NULL); array_delete(&mfile->storage->open_files, i, 1); if (oldest_file != mfile) { dbox_file_free(&oldest_file->file); + mdbox_file_close_later(mfile); return; } /* have to close ourself */
--- a/src/lib-storage/index/dbox-multi/mdbox-file.h Mon Mar 08 19:57:21 2010 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-file.h Mon Mar 08 20:28:08 2010 +0200 @@ -8,6 +8,7 @@ struct mdbox_storage *storage; uint32_t file_id; + time_t close_time; }; struct dbox_file *
--- a/src/lib-storage/index/dbox-multi/mdbox-settings.c Mon Mar 08 19:57:21 2010 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-settings.c Mon Mar 08 20:28:08 2010 +0200 @@ -11,14 +11,10 @@ #define DEF(type, name) \ { type, #name, offsetof(struct mdbox_settings, name), NULL } -static bool mdbox_settings_verify(void *_set, pool_t pool ATTR_UNUSED, - const char **error_r); - static const struct setting_define mdbox_setting_defines[] = { DEF(SET_SIZE, mdbox_rotate_size), DEF(SET_TIME, mdbox_rotate_interval), DEF(SET_TIME, mdbox_altmove), - DEF(SET_UINT, mdbox_max_open_files), SETTING_DEFINE_LIST_END }; @@ -26,8 +22,7 @@ static const struct mdbox_settings mdbox_default_settings = { .mdbox_rotate_size = 2*1024*1024, .mdbox_rotate_interval = 0, - .mdbox_altmove = 3600*24*7, - .mdbox_max_open_files = 64 + .mdbox_altmove = 3600*24*7 }; static const struct setting_parser_info mdbox_setting_parser_info = { @@ -39,25 +34,9 @@ .struct_size = sizeof(struct mdbox_settings), .parent_offset = (size_t)-1, - .parent = &mail_user_setting_parser_info, - - .check_func = mdbox_settings_verify + .parent = &mail_user_setting_parser_info }; -/* <settings checks> */ -static bool mdbox_settings_verify(void *_set, pool_t pool ATTR_UNUSED, - const char **error_r) -{ - const struct mdbox_settings *set = _set; - - if (set->mdbox_max_open_files < 2) { - *error_r = "mdbox_max_open_files must be at least 2"; - return FALSE; - } - return TRUE; -} -/* </settings checks> */ - const struct setting_parser_info *mdbox_get_setting_parser_info(void) { return &mdbox_setting_parser_info;
--- a/src/lib-storage/index/dbox-multi/mdbox-settings.h Mon Mar 08 19:57:21 2010 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-settings.h Mon Mar 08 20:28:08 2010 +0200 @@ -5,7 +5,6 @@ uoff_t mdbox_rotate_size; unsigned int mdbox_rotate_interval; unsigned int mdbox_altmove; - unsigned int mdbox_max_open_files; }; const struct setting_parser_info *mdbox_get_setting_parser_info(void);
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.c Mon Mar 08 19:57:21 2010 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c Mon Mar 08 20:28:08 2010 +0200 @@ -39,7 +39,6 @@ const char *dir; storage->set = mail_storage_get_driver_settings(_storage); - i_assert(storage->set->mdbox_max_open_files >= 2); if (*ns->list->set.mailbox_dir_name == '\0') { *error_r = "dbox: MAILBOXDIR must not be empty"; @@ -55,8 +54,7 @@ storage->alt_storage_dir = p_strconcat(_storage->pool, ns->list->set.alt_dir, "/"MDBOX_GLOBAL_DIR_NAME, NULL); - i_array_init(&storage->open_files, - I_MIN(storage->set->mdbox_max_open_files, 128)); + i_array_init(&storage->open_files, 64); storage->map = dbox_map_init(storage, ns->list, storage->storage_dir); return 0; @@ -73,6 +71,8 @@ mdbox_files_free(storage); dbox_map_deinit(&storage->map); + if (storage->to_close_unused_files != NULL) + timeout_remove(&storage->to_close_unused_files); array_free(&storage->open_files); }
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.h Mon Mar 08 19:57:21 2010 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.h Mon Mar 08 20:28:08 2010 +0200 @@ -11,6 +11,8 @@ #define MDBOX_GLOBAL_DIR_NAME "storage" #define MDBOX_MAIL_FILE_PREFIX "m." #define MDBOX_MAIL_FILE_FORMAT MDBOX_MAIL_FILE_PREFIX"%u" +#define MDBOX_MAX_OPEN_UNUSED_FILES 2 +#define MDBOX_CLOSE_UNUSED_FILES_TIMEOUT_SECS 30 #define MDBOX_INDEX_HEADER_MIN_SIZE (sizeof(uint32_t)) struct mdbox_index_header { @@ -28,6 +30,7 @@ struct dbox_map *map; ARRAY_DEFINE(open_files, struct mdbox_file *); + struct timeout *to_close_unused_files; }; struct mdbox_mail_index_record {