Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8982:947fab5a8992 HEAD
Search: Perform all lookups from cache before attempting any uncached lookups.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 28 Apr 2009 17:21:14 -0400 |
parents | 5611bba3548b |
children | fdaf0bda70d5 |
files | src/lib-storage/index/index-search.c |
diffstat | 1 files changed, 46 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/index-search.c Tue Apr 28 17:20:19 2009 -0400 +++ b/src/lib-storage/index/index-search.c Tue Apr 28 17:21:14 2009 -0400 @@ -559,29 +559,35 @@ ARG_SET_RESULT(arg, ret > 0); } -static bool search_arg_match_text(struct mail_search_arg *args, - struct index_search_context *ctx) +static int search_arg_match_text(struct mail_search_arg *args, + struct index_search_context *ctx) { struct istream *input; struct mailbox_header_lookup_ctx *headers_ctx; + struct mail_search_arg *arg; const char *const *headers; bool have_headers, have_body; + int ret; /* first check what we need to use */ headers = mail_search_args_analyze(args, &have_headers, &have_body); if (!have_headers && !have_body) - return TRUE; + return 1; if (have_headers) { struct search_header_context hdr_ctx; - if (have_body) + if (have_body && + ctx->mail->lookup_abort == MAIL_LOOKUP_ABORT_NEVER) { + /* just open the mail bypassing any caching, since + we're going to read through the body anyway */ headers = NULL; + } if (headers == NULL) { headers_ctx = NULL; if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0) - return FALSE; + return -1; } else { /* FIXME: do this once in init */ i_assert(*headers != NULL); @@ -591,7 +597,7 @@ if (mail_get_header_stream(ctx->mail, headers_ctx, &input) < 0) { mailbox_header_lookup_unref(&headers_ctx); - return FALSE; + return -1; } } @@ -612,7 +618,7 @@ struct message_size hdr_size; if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0) - return FALSE; + return -1; i_stream_seek(input, hdr_size.physical_size); } @@ -625,9 +631,21 @@ body_ctx.input = input; (void)mail_get_parts(ctx->mail, &body_ctx.part); - mail_search_args_foreach(args, search_body, &body_ctx); + ret = mail_search_args_foreach(args, search_body, &body_ctx); + } else { + /* see if we have a decision */ + ret = 1; + arg = ctx->mail_ctx.args->args; + for (; arg != NULL; arg = arg->next) { + if (arg->result == 0) { + ret = 0; + break; + } + if (arg->result < 0) + ret = -1; + } } - return TRUE; + return ret; } static bool search_msgset_fix_limits(const struct mail_index_header *hdr, @@ -1043,25 +1061,28 @@ static bool search_match_next(struct index_search_context *ctx) { - struct mail_search_arg *arg; - int ret; - - /* next search only from cached arguments */ - ret = mail_search_args_foreach(ctx->mail_ctx.args->args, - search_cached_arg, ctx); - if (ret >= 0) - return ret > 0; + static enum mail_lookup_abort cache_lookups[] = { + MAIL_LOOKUP_ABORT_NOT_IN_CACHE, + MAIL_LOOKUP_ABORT_READ_MAIL, + MAIL_LOOKUP_ABORT_NEVER + }; + unsigned int i; + int ret = -1; - /* open the mail file and check the rest */ - if (!search_arg_match_text(ctx->mail_ctx.args->args, ctx)) - return FALSE; + /* try to avoid doing extra work for as long as possible */ + for (i = 0; i < N_ELEMENTS(cache_lookups) && ret < 0; i++) { + ctx->mail->lookup_abort = cache_lookups[i]; + ret = mail_search_args_foreach(ctx->mail_ctx.args->args, + search_cached_arg, ctx); + if (ret >= 0) + break; - for (arg = ctx->mail_ctx.args->args; arg != NULL; arg = arg->next) { - if (arg->result != 1) - return FALSE; + ret = search_arg_match_text(ctx->mail_ctx.args->args, ctx); + if (ret >= 0) + break; } - - return TRUE; + ctx->mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER; + return ret > 0; } static void index_storage_search_notify(struct mailbox *box,