From: Josef 'Jeff' Sipek Date: Tue, 4 Feb 2020 17:32:59 +0000 (-0500) Subject: imap: expunge: Expunge \Deleted mails in batches of 1000 X-Git-Tag: 2.3.10~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07cacc5f2873afb99481ab935fa40b9afe23d0a6;p=thirdparty%2Fdovecot%2Fcore.git imap: expunge: Expunge \Deleted mails in batches of 1000 --- diff --git a/src/imap/imap-expunge.c b/src/imap/imap-expunge.c index 20b48b29c9..ff1a2134e8 100644 --- a/src/imap/imap-expunge.c +++ b/src/imap/imap-expunge.c @@ -3,8 +3,11 @@ #include "imap-common.h" #include "mail-storage.h" #include "mail-search-build.h" +#include "imap-search-args.h" #include "imap-expunge.h" +#define IMAP_EXPUNGE_BATCH_SIZE 1000 + /* get a seqset of all the mails with \Deleted */ static int imap_expunge_get_seqset(struct mailbox *box, struct mail_search_arg *next_search_arg, @@ -46,17 +49,19 @@ static int imap_expunge_get_seqset(struct mailbox *box, int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg, unsigned int *expunged_count) { - struct mail_search_context *ctx; - struct mailbox_transaction_context *t; - struct mail *mail; + struct imap_search_seqset_iter *seqset_iter; struct mail_search_args *search_args; + struct mailbox_status status; bool expunges = FALSE; + int ret; if (mailbox_is_readonly(box)) { /* silently ignore */ return 0; } + mailbox_get_open_status(box, STATUS_MESSAGES, &status); + search_args = mail_search_build_init(); search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); search_args->args->type = SEARCH_SEQSET; @@ -68,23 +73,39 @@ int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg, return -1; } - t = mailbox_transaction_begin(box, 0, "EXPUNGE"); - ctx = mailbox_search_init(t, search_args, NULL, 0, NULL); + seqset_iter = imap_search_seqset_iter_init(search_args, status.messages, + IMAP_EXPUNGE_BATCH_SIZE); + + do { + struct mailbox_transaction_context *t; + struct mail_search_context *ctx; + struct mail *mail; + + t = mailbox_transaction_begin(box, 0, "EXPUNGE"); + ctx = mailbox_search_init(t, search_args, NULL, 0, NULL); + + while (mailbox_search_next(ctx, &mail)) { + *expunged_count += 1; + mail_expunge(mail); + expunges = TRUE; + } + + ret = mailbox_search_deinit(&ctx); + if (ret < 0) { + mailbox_transaction_rollback(&t); + break; + } else { + ret = mailbox_transaction_commit(&t); + if (ret < 0) + break; + } + } while (imap_search_seqset_iter_next(seqset_iter)); + + imap_search_seqset_iter_deinit(&seqset_iter); mail_search_args_unref(&search_args); - while (mailbox_search_next(ctx, &mail)) { - *expunged_count += 1; - mail_expunge(mail); - expunges = TRUE; - } - - if (mailbox_search_deinit(&ctx) < 0) { - mailbox_transaction_rollback(&t); - return -1; - } else { - if (mailbox_transaction_commit(&t) < 0) - return -1; - } + if (ret < 0) + return ret; return expunges ? 1 : 0; }