[dovecot-cvs] dovecot/src/lib-storage/index index-storage.h, 1.100, 1.101 index-search.c, 1.110, 1.111

cras at dovecot.org cras at dovecot.org
Fri Apr 14 15:30:24 EEST 2006


Update of /var/lib/cvs/dovecot/src/lib-storage/index
In directory talvi:/tmp/cvs-serv15869/index

Modified Files:
	index-storage.h index-search.c 
Log Message:
Optimized searching a bit for cases where we can restrict search range by
simply looking at sequence sets. Also optimized some deleted/seen flag
searches where no results would be found. Added search_next_update_seq()
virtual method which allows plugins to restrict the search range (eg.
allowing indexed text search plugins).



Index: index-storage.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -d -r1.100 -r1.101
--- index-storage.h	9 Apr 2006 15:50:25 -0000	1.100
+++ index-storage.h	14 Apr 2006 12:30:21 -0000	1.101
@@ -177,6 +177,7 @@
 int index_storage_search_deinit(struct mail_search_context *ctx);
 int index_storage_search_next(struct mail_search_context *ctx,
 			      struct mail *mail);
+int index_storage_search_next_update_seq(struct mail_search_context *ctx);
 
 void index_transaction_init(struct index_transaction_context *t,
 			    struct index_mailbox *ibox,

Index: index-search.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -d -r1.110 -r1.111
--- index-search.c	25 Feb 2006 08:24:18 -0000	1.110
+++ index-search.c	14 Apr 2006 12:30:21 -0000	1.111
@@ -34,6 +34,7 @@
 	const char *error;
 
 	unsigned int failed:1;
+	unsigned int have_seqsets:1;
 };
 
 struct search_header_context {
@@ -89,9 +90,6 @@
 	const char *const *keywords;
 
 	switch (type) {
-	case SEARCH_ALL:
-		return 1;
-
 	/* flags */
 	case SEARCH_ANSWERED:
 		return rec->flags & MAIL_ANSWERED;
@@ -121,17 +119,38 @@
 	}
 }
 
-static void search_index_arg(struct mail_search_arg *arg, void *context)
+static void search_init_seqset_arg(struct mail_search_arg *arg, void *context)
+{
+	struct index_search_context *ctx = context;
+
+	switch (arg->type) {
+	case SEARCH_SEQSET:
+		ctx->have_seqsets = TRUE;
+		break;
+	case SEARCH_ALL:
+		if (!arg->not)
+			arg->match_always = TRUE;
+		break;
+	default:
+		break;
+	}
+}
+
+static void search_seqset_arg(struct mail_search_arg *arg, void *context)
 {
 	struct index_search_context *ctx = context;
 
 	if (arg->type == SEARCH_SEQSET) {
-		if (seqset_contains(arg->value.seqset, ctx->mail->seq))
+		if (seqset_contains(arg->value.seqset, ctx->mail_ctx.seq))
 			ARG_SET_RESULT(arg, 1);
 		else
 			ARG_SET_RESULT(arg, 0);
-		return;
 	}
+}
+
+static void search_index_arg(struct mail_search_arg *arg, void *context)
+{
+	struct index_search_context *ctx = context;
 
 	if (ctx->imail->data.rec == NULL) {
 		/* expunged message */
@@ -654,7 +673,8 @@
 				 uint32_t *seq1, uint32_t *seq2)
 {
 	for (; args != NULL; args = args->next) {
-		if (args->type == SEARCH_SEEN) {
+		switch (args->type) {
+		case SEARCH_SEEN:
 			/* SEEN with 0 seen? */
 			if (!args->not && hdr->seen_messages_count == 0)
 				return 0;
@@ -673,9 +693,8 @@
 						seq1) < 0)
 					return -1;
 			}
-		}
-
-		if (args->type == SEARCH_DELETED) {
+			break;
+		case SEARCH_DELETED:
 			/* DELETED with 0 deleted? */
 			if (!args->not && hdr->deleted_messages_count == 0)
 				return 0;
@@ -695,6 +714,13 @@
 						seq1) < 0)
 					return -1;
 			}
+			break;
+		case SEARCH_ALL:
+			if (args->not)
+				return 0;
+			break;
+		default:
+			break;
 		}
 	}
 
@@ -705,6 +731,7 @@
 			     struct mail_search_arg *args)
 {
         const struct mail_index_header *hdr;
+	int ret;
 
 	hdr = mail_index_get_header(ctx->view);
 	if (hdr->messages_count == 0) {
@@ -728,9 +755,14 @@
 	i_assert(ctx->seq1 <= ctx->seq2);
 
 	/* UNSEEN and DELETED in root search level may limit the range */
-	if (search_limit_by_flags(ctx, hdr, args,
-				  &ctx->seq1, &ctx->seq2) < 0)
+	ret = search_limit_by_flags(ctx, hdr, args, &ctx->seq1, &ctx->seq2);
+	if (ret < 0)
 		return -1;
+	if (ret == 0) {
+		/* no matches */
+		ctx->seq1 = 1;
+		ctx->seq2 = 0;
+	}
 	return 0;
 }
 
@@ -769,6 +801,11 @@
 		ctx->failed = TRUE;
 		ctx->seq1 = 1;
 		ctx->seq2 = 0;
+	} else {
+		(void)mail_search_args_foreach(args, search_init_seqset_arg,
+					       ctx);
+		/* Need to reset results for match_always cases */
+		mail_search_args_reset(ctx->args, FALSE);
 	}
 	return &ctx->mail_ctx;
 }
@@ -799,7 +836,6 @@
 	int ret;
 
 	/* check the index matches first */
-	mail_search_args_reset(ctx->args, FALSE);
 	ret = mail_search_args_foreach(ctx->args, search_index_arg, ctx);
 	if (ret >= 0)
 		return ret > 0;
@@ -831,29 +867,62 @@
 			      struct mail *mail)
 {
         struct index_search_context *ctx = (struct index_search_context *)_ctx;
+	struct mailbox *box = _ctx->transaction->box;
 	int ret;
 
 	ctx->mail = mail;
 	ctx->imail = (struct index_mail *)mail;
 
-	ret = 0;
-	while (ctx->seq1 <= ctx->seq2) {
-		if (mail_set_seq(mail, ctx->seq1++) < 0) {
-			ctx->failed = TRUE;
+	while ((ret = box->v.search_next_update_seq(_ctx)) > 0) {
+		if (mail_set_seq(mail, _ctx->seq) < 0) {
+			ret = -1;
 			break;
 		}
 
 		t_push();
-		ret = search_match_next(ctx);
+		ret = search_match_next(ctx) ? 1 : 0;
 		t_pop();
 
+		mail_search_args_reset(ctx->args, FALSE);
+
 		if (ctx->error != NULL)
 			ret = -1;
 		if (ret != 0)
 			break;
 	}
+	if (ret < 0)
+		ctx->failed = TRUE;
 	ctx->mail = NULL;
 	ctx->imail = NULL;
 
 	return ret;
 }
+
+int index_storage_search_next_update_seq(struct mail_search_context *_ctx)
+{
+        struct index_search_context *ctx = (struct index_search_context *)_ctx;
+	int ret;
+
+	if (_ctx->seq == 0) {
+		/* first time */
+		_ctx->seq = ctx->seq1;
+	} else {
+		_ctx->seq++;
+	}
+
+	if (!ctx->have_seqsets)
+		return _ctx->seq <= ctx->seq2 ? 1 : 0;
+
+	ret = 0;
+	while (_ctx->seq <= ctx->seq2) {
+		/* check if the sequence matches */
+		ret = mail_search_args_foreach(ctx->args,
+					       search_seqset_arg, ctx);
+		if (ret != 0)
+			break;
+
+		/* doesn't, try next one */
+		_ctx->seq++;
+	}
+	return ret == 0 ? 0 : 1;
+}



More information about the dovecot-cvs mailing list