]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Added "oldestonly" search arg to stop searching after the first non...
authorTimo Sirainen <tss@iki.fi>
Wed, 14 Jan 2015 22:10:56 +0000 (00:10 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 14 Jan 2015 22:10:56 +0000 (00:10 +0200)
This parameter works only for doveadm search queries. It's not fully exact
currently, because if mailbox.search_next_update_seq() skips over
non-matching messages we don't stop if the next message matches. So this
parameter is mainly useful for optimization of commands like:

doveadm expunge -u user@domain mailbox inbox savedsince 30d oldestonly

Where the timestamps should be ascending all the time anyway and there's no
point in continuing to search for more mails after the first timestamp is
too high.

src/lib-storage/index/index-search.c
src/lib-storage/mail-search-build.c
src/lib-storage/mail-search-build.h
src/lib-storage/mail-search-register-human.c
src/lib-storage/mail-search.h

index a2d1f85f2694488e37eb469c642a7030b8062695..dc39edd9f8f74850100f99ba27747898a9085762 100644 (file)
@@ -1561,6 +1561,12 @@ static int search_more_with_mail(struct index_search_context *ctx,
                        break;
                }
 
+               /* non-match */
+               if (_ctx->args->stop_on_nonmatch) {
+                       ret = -1;
+                       break;
+               }
+
                cost2 = search_get_cost(mail->transaction);
                ctx->cost += cost2 - cost1;
                cost1 = cost2;
@@ -1685,10 +1691,14 @@ static int search_more(struct index_search_context *ctx,
                if (imail->data.search_results == NULL)
                        break;
 
-               /* searching wasn't finished yet */
+               /* prefetch running - searching wasn't finished yet */
                if (search_finish_prefetch(ctx, imail))
                        break;
                /* search finished as non-match */
+               if (ctx->mail_ctx.args->stop_on_nonmatch) {
+                       ret = -1;
+                       break;
+               }
        }
        return ret;
 }
index 369ec00c8e0ecef5c3f6563d0b0a20f3c7e379da..0106277ccbe3d4c7ec7b944a1acbda4e94592455 100644 (file)
@@ -146,9 +146,8 @@ int mail_search_build(struct mail_search_register *reg,
        *args_r = NULL;
        *error_r = NULL;
 
-       args = mail_search_build_init();
-
        memset(&ctx, 0, sizeof(ctx));
+       ctx.args = args = mail_search_build_init();
        ctx.pool = args->pool;
        ctx.reg = reg;
        ctx.parser = parser;
index fe4967e1e06652a9b60ead27eb9a79b1e22de837..d9f86e60806bd678d66d2b0b0d90a9e2518b5e85 100644 (file)
@@ -8,6 +8,7 @@ struct mailbox;
 
 struct mail_search_build_context {
        pool_t pool;
+       struct mail_search_args *args;
        struct mail_search_register *reg;
        struct mail_search_parser *parser;
        const char *charset;
index fd5bae62ac67eb767a2980f28da3149e73e7c7d7..c548acdcb66b16bef773616384cb633d7a33a70b 100644 (file)
@@ -159,6 +159,13 @@ human_search_mailbox_guid(struct mail_search_build_context *ctx)
        return mail_search_build_str(ctx, SEARCH_MAILBOX_GUID);
 }
 
+static struct mail_search_arg *
+human_search_oldestonly(struct mail_search_build_context *ctx)
+{
+       ctx->args->stop_on_nonmatch = TRUE;
+       return mail_search_build_new(ctx, SEARCH_ALL);
+}
+
 static const struct mail_search_register_arg human_register_args[] = {
        { "OR", human_search_or },
 
@@ -183,7 +190,8 @@ static const struct mail_search_register_arg human_register_args[] = {
        /* Other Dovecot extensions: */
        { "GUID", human_search_guid },
        { "MAILBOX", human_search_mailbox },
-       { "MAILBOX-GUID", human_search_mailbox_guid }
+       { "MAILBOX-GUID", human_search_mailbox_guid },
+       { "OLDESTONLY", human_search_oldestonly }
 };
 
 static struct mail_search_register *
index 954a98e3a3c0dfb940eda089629d66c95b1384e4..3f30864d16518d9c6c6e1b6ce3ddda0c0e562ba4 100644 (file)
@@ -109,6 +109,9 @@ struct mail_search_args {
 
        unsigned int simplified:1;
        unsigned int have_inthreads:1;
+       /* Stop mail_search_next() when finding a non-matching mail.
+          (Could be useful when wanting to find only the oldest mails.) */
+       unsigned int stop_on_nonmatch:1;
 };
 
 #define ARG_SET_RESULT(arg, res) \