]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Try to avoid opening mailbox list index on mailbox access
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 10 Jul 2017 11:37:04 +0000 (14:37 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 12 Jul 2017 21:21:49 +0000 (00:21 +0300)
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.

src/lib-storage/list/mailbox-list-index-status.c
src/lib-storage/list/mailbox-list-index-storage.h

index f8eb6dfe605a789c55f67749524ffeea699eeef2..0f4b356a6b07aa375f47e0de715f10839323de6d 100644 (file)
@@ -738,16 +738,40 @@ void mailbox_list_index_update_mailbox_index(struct mailbox *box,
        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 @@ index_list_transaction_commit(struct mailbox_transaction_context *t,
                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 @@ void mailbox_list_index_status_init_mailbox(struct mailbox_vfuncs *v)
        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;
 }
index 7ee92a84c9ce2c7fa3af6b894fac9c186dba9e36..99943e74033bbc9677e8e0d39d5b45614dcbaa3b 100644 (file)
@@ -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,