]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: Optimize handling a large number of expunges.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 29 Apr 2016 12:42:48 +0000 (15:42 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 29 Apr 2016 12:52:44 +0000 (15:52 +0300)
This assumes that the mail_expunge() was called in the same order as
sync_notify(), which practically means that they were both done in
ascending uid order. This is usually true.

src/plugins/quota/quota-storage.c

index 17d56b4ad9edcf1b34056e6aaf24c2a30c745f44..52d0e2edaa4975f52eca3610ffd1bd4150412945 100644 (file)
@@ -31,6 +31,7 @@ struct quota_mailbox {
        struct quota_transaction_context *expunge_qt;
        ARRAY(uint32_t) expunge_uids;
        ARRAY(uoff_t) expunge_sizes;
+       unsigned int prev_idx;
 
        unsigned int recalculate:1;
        unsigned int sync_transaction_expunge:1;
@@ -344,10 +345,19 @@ static void quota_mailbox_sync_notify(struct mailbox *box, uint32_t uid,
                i = count = 0;
        } else {
                uids = array_get(&qbox->expunge_uids, &count);
-               for (i = 0; i < count; i++) {
+               for (i = qbox->prev_idx; i < count; i++) {
                        if (uids[i] == uid)
                                break;
                }
+               if (i >= count) {
+                       for (i = 0; i < qbox->prev_idx; i++) {
+                               if (uids[i] == uid)
+                                       break;
+                       }
+                       if (i == qbox->prev_idx)
+                               i = count;
+               }
+               qbox->prev_idx = i;
        }
 
        if (qbox->expunge_qt == NULL) {