changeset 22315:445b89dc8246

lib-storage: Try to avoid opening mailbox list index on mailbox access Perform the STATUS (and other relevant) updates only if syncing or transaction commits changed anything. This could be optimized further to check even more strongly whether the seen changes could cause changes to the list index, but it's probably not worth the effort.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 10 Jul 2017 14:37:04 +0300
parents 76a93ccad769
children 884f3c20ff34
files src/lib-storage/list/mailbox-list-index-status.c src/lib-storage/list/mailbox-list-index-storage.h
diffstat 2 files changed, 31 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-index-status.c	Mon Jul 10 14:20:50 2017 +0300
+++ b/src/lib-storage/list/mailbox-list-index-status.c	Mon Jul 10 14:37:04 2017 +0300
@@ -738,16 +738,40 @@
 	mail_index_view_close(&list_view);
 }
 
+static struct mailbox_sync_context *
+index_list_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
+{
+	struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
+	const struct mail_index_header *hdr;
+
+	hdr = mail_index_get_header(box->view);
+	ibox->pre_sync_log_file_seq = hdr->log_file_seq;
+	ibox->pre_sync_log_file_head_offset = hdr->log_file_head_offset;
+
+	return ibox->module_ctx.super.sync_init(box, flags);
+}
+
 static int index_list_sync_deinit(struct mailbox_sync_context *ctx,
 				  struct mailbox_sync_status *status_r)
 {
 	struct mailbox *box = ctx->box;
 	struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
+	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list);
+	const struct mail_index_header *hdr;
 
 	if (ibox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
 		return -1;
 	ctx = NULL;
 
+	hdr = mail_index_get_header(box->view);
+	if (!ilist->opened &&
+	    ibox->pre_sync_log_file_head_offset == hdr->log_file_head_offset &&
+	    ibox->pre_sync_log_file_seq == hdr->log_file_seq) {
+		/* List index isn't open and sync changed nothing.
+		   Don't bother opening the list index. */
+		return 0;
+	}
+
 	/* it probably doesn't matter much here if we push/pop the error,
 	   but might as well do it. */
 	mail_storage_last_error_push(mailbox_get_storage(box));
@@ -767,6 +791,9 @@
 		return -1;
 	t = NULL;
 
+	if (!changes_r->changed)
+		return 0;
+
 	/* this transaction commit may have been done in error handling path
 	   and the caller still wants to access the current error. make sure
 	   that whatever we do here won't change the error. */
@@ -819,6 +846,7 @@
 	v->exists = index_list_exists;
 	v->get_status = index_list_get_status;
 	v->get_metadata = index_list_get_metadata;
+	v->sync_init = index_list_sync_init;
 	v->sync_deinit = index_list_sync_deinit;
 	v->transaction_commit = index_list_transaction_commit;
 }
--- a/src/lib-storage/list/mailbox-list-index-storage.h	Mon Jul 10 14:20:50 2017 +0300
+++ b/src/lib-storage/list/mailbox-list-index-storage.h	Mon Jul 10 14:37:04 2017 +0300
@@ -8,6 +8,9 @@
 
 struct index_list_mailbox {
 	union mailbox_module_context module_ctx;
+
+	uint32_t pre_sync_log_file_seq;
+	uoff_t pre_sync_log_file_head_offset;
 };
 
 extern MODULE_CONTEXT_DEFINE(index_list_storage_module,