[dovecot-cvs] dovecot/src/lib-storage/index index-search.c, 1.124, 1.125

tss at dovecot.org tss at dovecot.org
Tue Apr 3 17:51:30 EEST 2007


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

Modified Files:
	index-search.c 
Log Message:
Message body search API changed to init/search/deinit. Searching now builds
the init structure only once instead of for every message.



Index: index-search.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -d -r1.124 -r1.125
--- index-search.c	21 Dec 2006 15:20:31 -0000	1.124
+++ index-search.c	3 Apr 2007 14:51:26 -0000	1.125
@@ -34,7 +34,7 @@
 	struct mail *mail;
 	struct index_mail *imail;
 
-	pool_t hdr_pool;
+	pool_t search_pool;
 	const char *error;
 
 	struct timeval search_start_time, last_notify;
@@ -61,6 +61,11 @@
 	const struct message_part *part;
 };
 
+struct search_arg_context {
+	struct header_search_context *hdr_search_ctx;
+	struct message_body_search_context *body_search_ctx;
+};
+
 static int search_parse_msgset_args(struct index_mailbox *ibox,
 				    const struct mail_index_header *hdr,
 				    struct mail_search_arg *args,
@@ -310,31 +315,72 @@
 	}
 }
 
+static struct search_arg_context *
+search_arg_context(struct index_search_context *ctx,
+		   struct mail_search_arg *arg)
+{
+	struct search_arg_context *arg_ctx = arg->context;
+
+	if (arg_ctx != NULL)
+		return arg_ctx;
+
+	if (ctx->search_pool == NULL)
+		ctx->search_pool = pool_alloconly_create("search pool", 8192);
+
+	arg_ctx = p_new(ctx->search_pool, struct search_arg_context, 1);
+	arg->context = arg_ctx;
+	return arg_ctx;
+}
+
 static struct header_search_context *
 search_header_context(struct index_search_context *ctx,
 		      struct mail_search_arg *arg)
 {
+	struct search_arg_context *arg_ctx;
 	bool unknown_charset;
 
-	if (arg->context != NULL) {
-                message_header_search_reset(arg->context);
-		return arg->context;
-	}
-
-	if (ctx->hdr_pool == NULL) {
-		ctx->hdr_pool =
-			pool_alloconly_create("message_header_search", 8192);
+	arg_ctx = search_arg_context(ctx, arg);
+	if (arg_ctx->hdr_search_ctx != NULL) {
+                message_header_search_reset(arg_ctx->hdr_search_ctx);
+		return arg_ctx->hdr_search_ctx;
 	}
 
-	arg->context = message_header_search_init(ctx->hdr_pool, arg->value.str,
-						  ctx->mail_ctx.charset,
-						  &unknown_charset);
-	if (arg->context == NULL) {
+	arg_ctx->hdr_search_ctx =
+		message_header_search_init(ctx->search_pool, arg->value.str,
+					   ctx->mail_ctx.charset,
+					   &unknown_charset);
+	if (arg_ctx->hdr_search_ctx == NULL) {
 		ctx->error = unknown_charset ?
 			TXT_UNKNOWN_CHARSET : TXT_INVALID_SEARCH_KEY;
 	}
 
-	return arg->context;
+	return arg_ctx->hdr_search_ctx;
+}
+
+static struct message_body_search_context *
+search_body_context(struct index_search_context *ctx,
+		    struct mail_search_arg *arg)
+{
+	struct search_arg_context *arg_ctx;
+	int ret;
+
+	arg_ctx = search_arg_context(ctx, arg);
+	if (arg_ctx->body_search_ctx != NULL)
+		return arg_ctx->body_search_ctx;
+
+	ret = message_body_search_init(ctx->search_pool, arg->value.str,
+				       ctx->mail_ctx.charset,
+				       arg->type == SEARCH_TEXT ||
+				       arg->type == SEARCH_TEXT_FAST,
+				       &arg_ctx->body_search_ctx);
+	if (ret > 0)
+		return arg_ctx->body_search_ctx;
+
+	if (ret == 0)
+		ctx->error = TXT_UNKNOWN_CHARSET;
+	else
+		ctx->error = TXT_INVALID_SEARCH_KEY;
+	return NULL;
 }
 
 static void search_header_arg(struct mail_search_arg *arg,
@@ -465,9 +511,8 @@
 static void search_body(struct mail_search_arg *arg,
 			struct search_body_context *ctx)
 {
-        enum message_body_search_error error;
+	struct message_body_search_context *body_search_ctx;
 	int ret;
-	bool retry = FALSE;
 
 	if (ctx->index_ctx->error != NULL)
 		return;
@@ -482,36 +527,28 @@
 		return;
 	}
 
-__retry:
-	i_stream_seek(ctx->input, 0);
-	ret = message_body_search(arg->value.str,
-				  ctx->index_ctx->mail_ctx.charset,
-				  ctx->input, ctx->part,
-				  arg->type == SEARCH_TEXT, &error);
+	body_search_ctx = search_body_context(ctx->index_ctx, arg);
+	if (body_search_ctx == NULL) {
+		ARG_SET_RESULT(arg, 0);
+		return;
+	}
 
+	i_stream_seek(ctx->input, 0);
+	ret = message_body_search(body_search_ctx, ctx->input, ctx->part);
 	if (ret < 0) {
-		switch (error) {
-		case MESSAGE_BODY_SEARCH_ERROR_UNKNOWN_CHARSET:
-			ctx->index_ctx->error = TXT_UNKNOWN_CHARSET;
-			break;
-		case MESSAGE_BODY_SEARCH_ERROR_INVALID_KEY:
-			ctx->index_ctx->error = TXT_INVALID_SEARCH_KEY;
-			break;
-		case MESSAGE_BODY_SEARCH_ERROR_MESSAGE_PART_BROKEN:
-			if (retry)
-				i_panic("Couldn't fix broken body structure");
-
-			mail_cache_set_corrupted(ctx->index_ctx->ibox->cache,
-				"Broken message structure for mail UID %u",
-				ctx->index_ctx->mail->uid);
+		mail_cache_set_corrupted(ctx->index_ctx->ibox->cache,
+			"Broken message structure for mail UID %u",
+			ctx->index_ctx->mail->uid);
 
-			/* get the body parts, and try again */
-			ctx->index_ctx->imail->data.parts = NULL;
-			ctx->part = mail_get_parts(ctx->index_ctx->mail);
+		/* get the body parts, and try again */
+		ctx->index_ctx->imail->data.parts = NULL;
+		ctx->part = mail_get_parts(ctx->index_ctx->mail);
 
-			retry = TRUE;
-			goto __retry;
-		}
+		i_stream_seek(ctx->input, 0);
+		ret = message_body_search(body_search_ctx,
+					  ctx->input, ctx->part);
+		if (ret < 0)
+			i_panic("Couldn't fix broken body structure");
 	}
 
 	ARG_SET_RESULT(arg, ret > 0);
@@ -919,8 +956,8 @@
 				       "%s", ctx->error);
 	}
 
-	if (ctx->hdr_pool != NULL)
-		pool_unref(ctx->hdr_pool);
+	if (ctx->search_pool != NULL)
+		pool_unref(ctx->search_pool);
 
 	if (ctx->mail_ctx.sort_program != NULL)
 		index_sort_program_deinit(&ctx->mail_ctx.sort_program);



More information about the dovecot-cvs mailing list