From: Timo Sirainen Date: Wed, 14 Jan 2015 22:10:56 +0000 (+0200) Subject: lib-storage: Added "oldestonly" search arg to stop searching after the first non... X-Git-Tag: 2.2.16.rc1~159 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce763c83d556eea9b74fc63e5d41f3b71a7e72de;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Added "oldestonly" search arg to stop searching after the first non-match. 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. --- diff --git a/src/lib-storage/index/index-search.c b/src/lib-storage/index/index-search.c index a2d1f85f26..dc39edd9f8 100644 --- a/src/lib-storage/index/index-search.c +++ b/src/lib-storage/index/index-search.c @@ -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; } diff --git a/src/lib-storage/mail-search-build.c b/src/lib-storage/mail-search-build.c index 369ec00c8e..0106277ccb 100644 --- a/src/lib-storage/mail-search-build.c +++ b/src/lib-storage/mail-search-build.c @@ -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; diff --git a/src/lib-storage/mail-search-build.h b/src/lib-storage/mail-search-build.h index fe4967e1e0..d9f86e6080 100644 --- a/src/lib-storage/mail-search-build.h +++ b/src/lib-storage/mail-search-build.h @@ -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; diff --git a/src/lib-storage/mail-search-register-human.c b/src/lib-storage/mail-search-register-human.c index fd5bae62ac..c548acdcb6 100644 --- a/src/lib-storage/mail-search-register-human.c +++ b/src/lib-storage/mail-search-register-human.c @@ -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 * diff --git a/src/lib-storage/mail-search.h b/src/lib-storage/mail-search.h index 954a98e3a3..3f30864d16 100644 --- a/src/lib-storage/mail-search.h +++ b/src/lib-storage/mail-search.h @@ -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) \