From 893d9a104f5048aada5217b695cfcf70a6dbe39d Mon Sep 17 00:00:00 2001 From: "sergey.kitov" Date: Tue, 8 Mar 2022 13:38:39 +0200 Subject: [PATCH] lib-storage: Expunge mails in batches when deleting a mailbox. --- src/lib-storage/index/index-storage.c | 38 ++++++++++++++++++--------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 3320d97b5e..f23b5000ae 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -757,32 +757,46 @@ mailbox_delete_all_attributes(struct mailbox_transaction_context *t, static int mailbox_expunge_all_data(struct mailbox *box) { - struct mail_search_context *ctx; struct mailbox_transaction_context *t; - struct mail *mail; struct mail_search_args *search_args; + struct mailbox_status status; + struct mail_search_seqset_iter *seqset_iter; int ret; (void)mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ); - t = mailbox_transaction_begin(box, 0, __func__); + mailbox_get_open_status(box, STATUS_MESSAGES, &status); search_args = mail_search_build_init(); mail_search_build_add_all(search_args); - ctx = mailbox_search_init(t, search_args, NULL, 0, NULL); - mail_search_args_unref(&search_args); - while (mailbox_search_next(ctx, &mail)) - mail_expunge(mail); + seqset_iter = mail_search_seqset_iter_init(search_args, status.messages, + MAIL_EXPUNGE_BATCH_SIZE); - ret = mailbox_search_deinit(&ctx); - if (ret == 0) { - if (mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0 || - mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) + do { + struct mail_search_context *ctx; + struct mail *mail; + + t = mailbox_transaction_begin(box, 0, __func__); + ctx = mailbox_search_init(t, search_args, NULL, 0, NULL); + while (mailbox_search_next(ctx, &mail)) + mail_expunge(mail); + + ret = mailbox_search_deinit(&ctx); + if (mailbox_transaction_commit(&t) < 0) ret = -1; - } + } while (ret >= 0 && mail_search_seqset_iter_next(seqset_iter)); + + mail_search_seqset_iter_deinit(&seqset_iter); + mail_search_args_unref(&search_args); + + t = mailbox_transaction_begin(box, 0, __func__); + if (mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0 || + mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) + ret = -1; if (mailbox_transaction_commit(&t) < 0) ret = -1; + /* sync to actually perform the expunges */ if (mailbox_sync(box, 0) < 0) ret = -1; -- 2.47.3