changeset 17222:26b468dc7f11

lib-storage: mailbox_alloc_guid() shouldn't refresh GUID cache on every nonexistent GUID. Refresh it only if we know it has had some changes (made by our process) or timestamp has changed. This should handle the cases that are currently important (=single dsync run).
author Timo Sirainen <tss@iki.fi>
date Tue, 15 Apr 2014 23:44:54 +0200
parents e75851b65900
children c2755572d31e
files src/lib-storage/mail-storage.c src/lib-storage/mailbox-guid-cache.c src/lib-storage/mailbox-list-private.h
diffstat 3 files changed, 25 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/mail-storage.c	Tue Apr 15 23:41:50 2014 +0200
+++ b/src/lib-storage/mail-storage.c	Tue Apr 15 23:44:54 2014 +0200
@@ -1239,18 +1239,25 @@
 	box->creating = TRUE;
 	ret = box->v.create_box(box, update, directory);
 	box->creating = FALSE;
+	if (ret == 0)
+		box->list->guid_cache_invalidated = TRUE;
 	return ret;
 }
 
 int mailbox_update(struct mailbox *box, const struct mailbox_update *update)
 {
+	int ret;
+
 	i_assert(update->min_next_uid == 0 ||
 		 update->min_first_recent_uid == 0 ||
 		 update->min_first_recent_uid <= update->min_next_uid);
 
 	if (mailbox_verify_existing_name(box) < 0)
 		return -1;
-	return box->v.update_box(box, update);
+	ret = box->v.update_box(box, update);
+	if (!guid_128_is_empty(update->mailbox_guid))
+		box->list->guid_cache_invalidated = TRUE;
+	return ret;
 }
 
 int mailbox_mark_index_deleted(struct mailbox *box, bool del)
@@ -1425,7 +1432,11 @@
 		return -1;
 	}
 
-	return src->v.rename_box(src, dest);
+	if (src->v.rename_box(src, dest) < 0)
+		return -1;
+	src->list->guid_cache_invalidated = TRUE;
+	dest->list->guid_cache_invalidated = TRUE;
+	return 0;
 }
 
 int mailbox_set_subscribed(struct mailbox *box, bool set)
--- a/src/lib-storage/mailbox-guid-cache.c	Tue Apr 15 23:41:50 2014 +0200
+++ b/src/lib-storage/mailbox-guid-cache.c	Tue Apr 15 23:44:54 2014 +0200
@@ -1,6 +1,7 @@
 /* Copyright (c) 2005-2014 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "hash.h"
 #include "mail-storage.h"
 #include "mailbox-list-private.h"
@@ -11,6 +12,12 @@
 	const char *vname;
 };
 
+static bool mailbox_guid_cache_want_refresh(struct mailbox_list *list)
+{
+	return list->guid_cache_invalidated ||
+		list->guid_cache_last_update < ioloop_time;
+}
+
 int mailbox_guid_cache_find(struct mailbox_list *list,
 			    const guid_128_t guid, const char **vname_r)
 {
@@ -22,7 +29,7 @@
 		rec = hash_table_lookup(list->guid_cache, guid_p);
 	} else {
 		rec = hash_table_lookup(list->guid_cache, guid_p);
-		if (rec == NULL) {
+		if (rec == NULL && mailbox_guid_cache_want_refresh(list)) {
 			mailbox_guid_cache_refresh(list);
 			rec = hash_table_lookup(list->guid_cache, guid_p);
 		}
@@ -53,6 +60,8 @@
 		hash_table_clear(list->guid_cache, TRUE);
 		p_clear(list->guid_cache_pool);
 	}
+	list->guid_cache_last_update = ioloop_time;
+	list->guid_cache_invalidated = FALSE;
 	list->guid_cache_errors = FALSE;
 
 	ctx = mailbox_list_iter_init(list, "*",
--- a/src/lib-storage/mailbox-list-private.h	Tue Apr 15 23:41:50 2014 +0200
+++ b/src/lib-storage/mailbox-list-private.h	Tue Apr 15 23:44:54 2014 +0200
@@ -122,6 +122,7 @@
 	struct mailbox_log *changelog;
 	time_t changelog_timestamp;
 
+	time_t guid_cache_last_update;
 	pool_t guid_cache_pool;
 	HASH_TABLE(uint8_t *, struct mailbox_guid_cache_rec *) guid_cache;
 	bool guid_cache_errors;
@@ -133,6 +134,7 @@
 	ARRAY(union mailbox_list_module_context *) module_contexts;
 
 	unsigned int index_root_dir_created:1;
+	unsigned int guid_cache_invalidated:1;
 };
 
 union mailbox_list_iterate_module_context {