dovecot-2.0: Search: Perform all lookups from cache before attem...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Apr 29 04:08:54 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/3727bfc568b9
changeset: 9162:3727bfc568b9
user: Timo Sirainen <tss at iki.fi>
date: Tue Apr 28 17:21:14 2009 -0400
description:
Search: Perform all lookups from cache before attempting any uncached lookups.
diffstat:
1 file changed, 50 insertions(+), 29 deletions(-)
src/lib-storage/index/index-search.c | 79 +++++++++++++++++++++-------------
diffs (135 lines):
diff -r 03a5f5cf6b4c -r 3727bfc568b9 src/lib-storage/index/index-search.c
--- a/src/lib-storage/index/index-search.c Tue Apr 28 21:01:53 2009 -0400
+++ b/src/lib-storage/index/index-search.c Tue Apr 28 17:21:14 2009 -0400
@@ -559,29 +559,35 @@ static void search_body(struct mail_sear
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 @@ static bool search_arg_match_text(struct
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 @@ static bool search_arg_match_text(struct
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 @@ static bool search_arg_match_text(struct
body_ctx.input = input;
(void)mail_get_parts(ctx->mail, &body_ctx.part);
- mail_search_args_foreach(args, search_body, &body_ctx);
- }
- return TRUE;
+ 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 ret;
}
static bool search_msgset_fix_limits(const struct mail_index_header *hdr,
@@ -1043,25 +1061,28 @@ int index_storage_search_deinit(struct m
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;
-
- /* open the mail file and check the rest */
- if (!search_arg_match_text(ctx->mail_ctx.args->args, ctx))
- return FALSE;
-
- for (arg = ctx->mail_ctx.args->args; arg != NULL; arg = arg->next) {
- if (arg->result != 1)
- return FALSE;
- }
-
- return TRUE;
+ 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;
+
+ /* 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;
+
+ ret = search_arg_match_text(ctx->mail_ctx.args->args, ctx);
+ if (ret >= 0)
+ break;
+ }
+ ctx->mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER;
+ return ret > 0;
}
static void index_storage_search_notify(struct mailbox *box,
More information about the dovecot-cvs
mailing list