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