]> 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 <tss@dovecot.fi>
Mon, 10 Jul 2017 13:20:41 +0000 (16:20 +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 6cc950d324751854137a28f1498320d358d52d7d..a90ef2366ac43704550f034dd240f464c240e4b8 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. */
@@ -816,6 +843,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,