changeset 4922:a3955deadc1d HEAD

Optimize also 1:n seqset searches. Fixed also a case where we failed too early when trying to find a Message-ID for a crc32.
author Timo Sirainen <tss@iki.fi>
date Wed, 20 Dec 2006 06:35:45 +0200
parents 050355eeff5d
children c1965cbf5c87
files src/imap/imap-thread.c
diffstat 1 files changed, 42 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/imap-thread.c	Wed Dec 20 05:38:40 2006 +0200
+++ b/src/imap/imap-thread.c	Wed Dec 20 06:35:45 2006 +0200
@@ -263,7 +263,8 @@
 
 	while ((msgid = message_id_get_next(&msgids)) != NULL) {
 		if (crc32_str_nonzero(msgid) == msgid_crc32) {
-			if (found_msgid != NULL) {
+			if (found_msgid != NULL &&
+			    strcmp(found_msgid, msgid) != 0) {
 				/* hash collisions, we can't figure this out */
 				return -1;
 			}
@@ -288,8 +289,14 @@
 			return NULL;
 		idx = child_rec->next_idx;
 
-		if (child_rec->rec.uid == 0)
-			continue;
+		if (child_rec->rec.uid == 0) {
+			if (idx != 0)
+				continue;
+
+			/* only dummies in this level. go deeper. */
+			return mail_thread_children_get_parent_msgid(ctx,
+								     child_rec);
+		}
 
 		/* each non-dummy child must have a valid In-Reply-To or
 		   References header pointing to the parent, otherwise it
@@ -381,17 +388,32 @@
 	struct mailbox_status status;
 	const struct mail_hash_header *hdr;
 	unsigned int count;
+	uint32_t last_seq = 0, last_uid = 0;
 
 	if (mailbox_get_status(client->mailbox,
 			       STATUS_MESSAGES | STATUS_UIDNEXT, &status) < 0)
 		return -1;
 
-	if (search_args->type != SEARCH_ALL ||
-	    search_args->next != NULL) {
-		/* each search condition requires their own separate thread
-		   index. for now we don't bother to support anything else than
-		   "search all" threading, since that's what pretty much all
-		   the clients do anyway. */
+	last_seq = status.messages;
+	last_uid = status.uidnext - 1;
+
+	/* Each search condition requires their own separate thread index.
+	   Pretty much all the clients use only "search all" threading, so
+	   we don't need to worry about anything else. */
+	if (search_args->next != NULL) {
+		/* too difficult to figure out if we could optimize this.
+		   we most likely couldn't. */
+		ctx->msgid_hash = NULL;
+	} else if (search_args->type == SEARCH_ALL) {
+		/* optimize */
+	} else if (search_args->type == SEARCH_SEQSET &&
+		   search_args->value.seqset->seq1 == 1) {
+		/* If we're searching 1..n, we might be able to optimize
+		   this. This is at least useful for testing incremental
+		   index updates if nothing else. :) */
+		last_seq = search_args->value.seqset->seq2;
+		last_uid = 0;
+	} else {
 		ctx->msgid_hash = NULL;
 	}
 
@@ -404,8 +426,8 @@
 		mail_hash_get_header(ctx->msgid_hash);
 	if (hdr == NULL) {
 		/* we want to build it in memory */
-	} else if (hdr->message_count > status.messages) {
-		if (hdr->last_uid > status.uidnext-1) {
+	} else if (hdr->message_count > last_seq) {
+		if (hdr->last_uid > last_uid) {
 			/* view is a bit out of date, can't optimize */
 			mail_hash_unlock(ctx->msgid_hash);
 			ctx->msgid_hash = NULL;
@@ -432,11 +454,18 @@
 			   can actually optimize. */
 			ctx->tmp_search_arg.type = SEARCH_SEQSET;
 			ctx->tmp_search_arg.value.seqset = &ctx->seqset;
-			ctx->tmp_search_arg.not = TRUE;
+			if (ctx->seqset.seq2 == last_seq) {
+				/* search nothing */
+				ctx->tmp_search_arg.not = TRUE;
+			} else {
+				/* search next+1..n */
+				ctx->seqset.seq1 = ctx->seqset.seq2 + 1;
+				ctx->seqset.seq2 = last_seq;
+			}
 			search_args = &ctx->tmp_search_arg;
 
 			if (mail_hash_resize_if_needed(ctx->msgid_hash,
-						       status.messages -
+						       last_seq -
 						       hdr->message_count) < 0)
 				ctx->msgid_hash = NULL;
 		}