dovecot-2.0: mdbox: Removed mdbox_max_open_files setting.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Mar 8 20:28:22 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/863eafcf8428
changeset: 10868:863eafcf8428
user: Timo Sirainen <tss at iki.fi>
date: Mon Mar 08 20:28:08 2010 +0200
description:
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.
diffstat:
src/lib-storage/index/dbox-multi/mdbox-file.c | 77 +++++++++++++++++++------
src/lib-storage/index/dbox-multi/mdbox-file.h | 1 +
src/lib-storage/index/dbox-multi/mdbox-settings.c | 25 +-------
src/lib-storage/index/dbox-multi/mdbox-settings.h | 1 -
src/lib-storage/index/dbox-multi/mdbox-storage.c | 6 +-
src/lib-storage/index/dbox-multi/mdbox-storage.h | 3 +
6 files changed, 68 insertions(+), 45 deletions(-)
diffs (250 lines):
diff -r c56358283605 -r 863eafcf8428 src/lib-storage/index/dbox-multi/mdbox-file.c
--- 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 */
diff -r c56358283605 -r 863eafcf8428 src/lib-storage/index/dbox-multi/mdbox-file.h
--- 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 *
diff -r c56358283605 -r 863eafcf8428 src/lib-storage/index/dbox-multi/mdbox-settings.c
--- 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;
diff -r c56358283605 -r 863eafcf8428 src/lib-storage/index/dbox-multi/mdbox-settings.h
--- 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);
diff -r c56358283605 -r 863eafcf8428 src/lib-storage/index/dbox-multi/mdbox-storage.c
--- 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);
}
diff -r c56358283605 -r 863eafcf8428 src/lib-storage/index/dbox-multi/mdbox-storage.h
--- 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 {
More information about the dovecot-cvs
mailing list