#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,
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;
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;
}