dovecot-2.0: lib-storage: Fixes/optimizations to SEARCH_MAILBOX*.

dovecot at dovecot.org dovecot at dovecot.org
Fri Apr 30 16:15:31 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/dedf835014a2
changeset: 11238:dedf835014a2
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Apr 30 16:14:42 2010 +0300
description:
lib-storage: Fixes/optimizations to SEARCH_MAILBOX*.

diffstat:

 src/lib-storage/index/index-search.c |  92 +++++++++++++++++++++++-------
 src/lib-storage/mail-search.c        |  14 +++-
 src/lib-storage/mail-search.h        |   1 +
 3 files changed, 83 insertions(+), 24 deletions(-)

diffs (195 lines):

diff -r 6327433bccb9 -r dedf835014a2 src/lib-storage/index/index-search.c
--- a/src/lib-storage/index/index-search.c	Fri Apr 30 15:53:23 2010 +0300
+++ b/src/lib-storage/index/index-search.c	Fri Apr 30 16:14:42 2010 +0300
@@ -58,6 +58,7 @@
 	unsigned int sorted:1;
 	unsigned int have_seqsets:1;
 	unsigned int have_index_args:1;
+	unsigned int have_mailbox_args:1;
 };
 
 struct search_header_context {
@@ -87,6 +88,9 @@
 static void search_init_arg(struct mail_search_arg *arg,
 			    struct index_search_context *ctx)
 {
+	uint8_t guid[MAIL_GUID_128_SIZE];
+	bool match;
+
 	switch (arg->type) {
 	case SEARCH_SEQSET:
 		ctx->have_seqsets = TRUE;
@@ -100,9 +104,28 @@
 			mail_index_modseq_enable(ctx->box->index);
 		ctx->have_index_args = TRUE;
 		break;
+	case SEARCH_MAILBOX_GUID:
+		if (mailbox_get_guid(ctx->box, guid) < 0) {
+			/* result will be unknown */
+			break;
+		}
+
+		match = strcmp(mail_guid_128_to_string(guid),
+			       arg->value.str) == 0;
+		if (match != arg->not)
+			arg->match_always = TRUE;
+		else
+			arg->nonmatch_always = TRUE;
+		break;
+	case SEARCH_MAILBOX:
+	case SEARCH_MAILBOX_GLOB:
+		ctx->have_mailbox_args = TRUE;
+		break;
 	case SEARCH_ALL:
 		if (!arg->not)
 			arg->match_always = TRUE;
+		else
+			arg->nonmatch_always = TRUE;
 		break;
 	default:
 		break;
@@ -150,8 +173,6 @@
 				  struct mail_search_arg *arg,
 				  const struct mail_index_record *rec)
 {
-	uint8_t guid[MAIL_GUID_128_SIZE];
-	const char *str;
 	enum mail_flags flags;
 	uint64_t modseq;
 	int ret;
@@ -186,25 +207,6 @@
 		}
 		return modseq >= arg->value.modseq->modseq;
 	}
-	case SEARCH_MAILBOX:
-		if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
-				     &str) < 0)
-			return -1;
-
-		if (strcasecmp(str, "INBOX") == 0)
-			return strcasecmp(arg->value.str, "INBOX") == 0;
-		return strcmp(str, arg->value.str) == 0;
-	case SEARCH_MAILBOX_GUID:
-		if (mailbox_get_guid(ctx->mail->box, guid) < 0)
-			return -1;
-
-		return strcmp(mail_guid_128_to_string(guid),
-			      arg->value.str) == 0;
-	case SEARCH_MAILBOX_GLOB:
-		if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
-				     &str) < 0)
-			return -1;
-		return imap_match(arg->value.mailbox_glob, str) == IMAP_MATCH_YES;
 	default:
 		return -1;
 	}
@@ -230,6 +232,47 @@
 }
 
 /* Returns >0 = matched, 0 = not matched, -1 = unknown */
+static int search_arg_match_mailbox(struct index_search_context *ctx,
+				    struct mail_search_arg *arg)
+{
+	const char *str;
+
+	switch (arg->type) {
+	case SEARCH_MAILBOX:
+		if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
+				     &str) < 0)
+			return -1;
+
+		if (strcasecmp(str, "INBOX") == 0)
+			return strcasecmp(arg->value.str, "INBOX") == 0;
+		return strcmp(str, arg->value.str) == 0;
+	case SEARCH_MAILBOX_GLOB:
+		if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
+				     &str) < 0)
+			return -1;
+		return imap_match(arg->value.mailbox_glob, str) == IMAP_MATCH_YES;
+	default:
+		return -1;
+	}
+}
+
+static void search_mailbox_arg(struct mail_search_arg *arg,
+			       struct index_search_context *ctx)
+{
+	switch (search_arg_match_mailbox(ctx, arg)) {
+	case -1:
+		/* unknown */
+		break;
+	case 0:
+		ARG_SET_RESULT(arg, 0);
+		break;
+	default:
+		ARG_SET_RESULT(arg, 1);
+		break;
+	}
+}
+
+/* Returns >0 = matched, 0 = not matched, -1 = unknown */
 static int search_arg_match_cached(struct index_search_context *ctx,
 				   struct mail_search_arg *arg)
 {
@@ -1104,6 +1147,13 @@
 	unsigned int i;
 	int ret = -1;
 
+	if (ctx->have_mailbox_args) {
+		ret = mail_search_args_foreach(ctx->mail_ctx.args->args,
+					       search_mailbox_arg, ctx);
+		if (ret >= 0)
+			return ret > 0;
+	}
+
 	/* 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];
diff -r 6327433bccb9 -r dedf835014a2 src/lib-storage/mail-search.c
--- a/src/lib-storage/mail-search.c	Fri Apr 30 15:53:23 2010 +0300
+++ b/src/lib-storage/mail-search.c	Fri Apr 30 16:14:42 2010 +0300
@@ -268,6 +268,7 @@
 	new_arg->type = arg->type;
 	new_arg->not = arg->not;
 	new_arg->match_always = arg->match_always;
+	new_arg->nonmatch_always = arg->nonmatch_always;
 	new_arg->value.search_flags = arg->value.search_flags;
 
 	switch (arg->type) {
@@ -356,15 +357,22 @@
 		if (args->type == SEARCH_OR || args->type == SEARCH_SUB)
 			mail_search_args_reset(args->value.subargs, full_reset);
 
-		if (!args->match_always)
-			args->result = -1;
-		else {
+		if (args->match_always) {
 			if (!full_reset)
 				args->result = 1;
 			else {
 				args->match_always = FALSE;
 				args->result = -1;
 			}
+		} else if (args->nonmatch_always) {
+			if (!full_reset)
+				args->result = 0;
+			else {
+				args->nonmatch_always = FALSE;
+				args->result = -1;
+			}
+		} else {
+			args->result = -1;
 		}
 
 		args = args->next;
diff -r 6327433bccb9 -r dedf835014a2 src/lib-storage/mail-search.h
--- a/src/lib-storage/mail-search.h	Fri Apr 30 15:53:23 2010 +0300
+++ b/src/lib-storage/mail-search.h	Fri Apr 30 16:14:42 2010 +0300
@@ -95,6 +95,7 @@
 	const char *hdr_field_name; /* for SEARCH_HEADER* */
 	unsigned int not:1;
 	unsigned int match_always:1; /* result = 1 always */
+	unsigned int nonmatch_always:1; /* result = 0 always */
 
 	int result; /* -1 = unknown, 0 = unmatched, 1 = matched */
 };


More information about the dovecot-cvs mailing list