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