dovecot-1.2: Moved non-syncing related search result updating co...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jun 18 05:58:00 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/3ffac3f6173f
changeset: 7888:3ffac3f6173f
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jun 18 04:59:20 2008 +0300
description:
Moved non-syncing related search result updating code to a separate file and
did some other cleanups.

diffstat:

6 files changed, 243 insertions(+), 204 deletions(-)
src/lib-storage/index/Makefile.am           |    2 
src/lib-storage/index/index-search-result.c |  198 ++++++++++++++++++++++
src/lib-storage/index/index-search-result.h |   11 +
src/lib-storage/index/index-sync-private.h  |    1 
src/lib-storage/index/index-sync-search.c   |  233 +++------------------------
src/lib-storage/index/index-sync.c          |    2 

diffs (truncated from 531 to 300 lines):

diff -r 38bdfafa655c -r 3ffac3f6173f src/lib-storage/index/Makefile.am
--- a/src/lib-storage/index/Makefile.am	Wed Jun 18 04:34:46 2008 +0300
+++ b/src/lib-storage/index/Makefile.am	Wed Jun 18 04:59:20 2008 +0300
@@ -15,6 +15,7 @@ libstorage_index_a_SOURCES = \
 	index-mail-headers.c \
 	index-mailbox-check.c \
 	index-search.c \
+	index-search-result.c \
 	index-sort.c \
 	index-sort-string.c \
 	index-status.c \
@@ -29,6 +30,7 @@ libstorage_index_a_SOURCES = \
 
 headers = \
 	index-mail.h \
+	index-search-result.h \
 	index-sort.h \
 	index-sort-private.h \
 	index-storage.h \
diff -r 38bdfafa655c -r 3ffac3f6173f src/lib-storage/index/index-search-result.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/index-search-result.c	Wed Jun 18 04:59:20 2008 +0300
@@ -0,0 +1,198 @@
+/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "seq-range-array.h"
+#include "mail-search.h"
+#include "mailbox-search-result-private.h"
+#include "index-storage.h"
+#include "index-search-result.h"
+
+static void
+search_result_range_remove(struct mail_search_result *result,
+			   const ARRAY_TYPE(seq_range) *search_seqs_range,
+			   unsigned int *pos,
+			   uint32_t *next_seq, uint32_t last_seq)
+{
+	struct index_mailbox *ibox = (struct index_mailbox *)result->box;
+	const struct seq_range *seqs;
+	unsigned int i, count;
+	uint32_t seq, uid;
+
+	seq = *next_seq;
+	seqs = array_get(search_seqs_range, &count);
+	for (i = *pos; seqs[i].seq2 < last_seq;) {
+		i_assert(seqs[i].seq1 <= seq);
+		for (; seq <= seqs[i].seq2; seq++) {
+			mail_index_lookup_uid(ibox->view, seq, &uid);
+			mailbox_search_result_remove(result, uid);
+		}
+		i++;
+		i_assert(i < count);
+		seq = seqs[i].seq1;
+	}
+
+	i_assert(seqs[i].seq1 <= seq && seqs[i].seq2 >= last_seq);
+	for (; seq <= last_seq; seq++) {
+		mail_index_lookup_uid(ibox->view, seq, &uid);
+		mailbox_search_result_remove(result, uid);
+	}
+	if (seq > seqs[i].seq2) {
+		/* finished this range */
+		if (++i < count)
+			seq = seqs[i].seq1;
+		else {
+			/* this was the last searched message */
+			seq = 0;
+		}
+	}
+
+	*next_seq = seq;
+	*pos = i;
+}
+
+static int
+search_result_update_search(struct mail_search_result *result,
+			    const ARRAY_TYPE(seq_range) *search_seqs_range)
+{
+	struct mailbox_transaction_context *t;
+	struct mail_search_context *search_ctx;
+	struct mail *mail;
+	const struct seq_range *search_seqs;
+	unsigned int seqcount, seqpos;
+	uint32_t next_seq;
+	int ret;
+
+	search_seqs = array_get(search_seqs_range, &seqcount);
+	i_assert(seqcount > 0);
+	next_seq = search_seqs[0].seq1;
+	seqpos = 0;
+
+	t = mailbox_transaction_begin(result->box, 0);
+	search_ctx = mailbox_search_init(t, result->search_args, NULL);
+	/* tell search that we're updating an existing search result,
+	   so it can do some optimizations based on it */
+	search_ctx->update_result = result;
+
+	mail = mail_alloc(t, 0, NULL);
+	while (mailbox_search_next(search_ctx, mail) > 0) {
+		i_assert(next_seq != 0);
+
+		if (next_seq != mail->seq) {
+			/* some messages in search_seqs didn't match.
+			   make sure they don't exist in the search result. */
+			search_result_range_remove(result, search_seqs_range,
+						   &seqpos, &next_seq,
+						   mail->seq-1);
+			i_assert(next_seq == mail->seq);
+		}
+		if (search_seqs[seqpos].seq2 > next_seq) {
+			next_seq++;
+		} else if (++seqpos < seqcount) {
+			next_seq = search_seqs[seqpos].seq1;
+		} else {
+			/* this was the last searched message */
+			next_seq = 0;
+		}
+		/* match - make sure it exists in search result */
+		mailbox_search_result_add(result, mail->uid);
+	}
+	mail_free(&mail);
+	ret = mailbox_search_deinit(&search_ctx);
+
+	if (next_seq != 0 && ret == 0) {
+		/* last message(s) didn't match. make sure they don't exist
+		   in the search result. */
+		search_result_range_remove(result, search_seqs_range, &seqpos,
+					   &next_seq,
+					   search_seqs[seqcount-1].seq2);
+	}
+
+	if (mailbox_transaction_commit(&t) < 0)
+		ret = -1;
+	return ret;
+}
+
+int index_search_result_update_flags(struct mail_search_result *result,
+				     const ARRAY_TYPE(seq_range) *changes)
+{
+	struct mail_search_arg search_arg;
+	int ret;
+
+	/* add a temporary search parameter to limit the search only to
+	   the changed messages */
+	memset(&search_arg, 0, sizeof(search_arg));
+	search_arg.type = SEARCH_SEQSET;
+	search_arg.value.seqset = *changes;
+	search_arg.next = result->search_args->args;
+	result->search_args->args = &search_arg;
+	ret = search_result_update_search(result, changes);
+	i_assert(result->search_args->args == &search_arg);
+	result->search_args->args = search_arg.next;
+	return ret;
+}
+
+int index_search_result_update_appends(struct mail_search_result *result,
+				       unsigned int old_messages_count)
+{
+	struct index_mailbox *ibox = (struct index_mailbox *)result->box;
+	struct mailbox_transaction_context *t;
+	struct mail_search_context *search_ctx;
+	struct mail *mail;
+	struct mail_search_arg search_arg;
+	uint32_t message_count;
+	int ret;
+
+	message_count = mail_index_view_get_messages_count(ibox->view);
+	if (old_messages_count == message_count) {
+		/* no new messages */
+		return 0;
+	}
+
+	/* add a temporary search parameter to limit the search only to
+	   the new messages */
+	memset(&search_arg, 0, sizeof(search_arg));
+	search_arg.type = SEARCH_SEQSET;
+	t_array_init(&search_arg.value.seqset, 1);
+	seq_range_array_add_range(&search_arg.value.seqset,
+				  old_messages_count + 1, message_count);
+	search_arg.next = result->search_args->args;
+	result->search_args->args = &search_arg;
+
+	/* add all messages matching the search to search result */
+	t = mailbox_transaction_begin(result->box, 0);
+	search_ctx = mailbox_search_init(t, result->search_args, NULL);
+
+	mail = mail_alloc(t, 0, NULL);
+	while (mailbox_search_next(search_ctx, mail) > 0)
+		mailbox_search_result_add(result, mail->uid);
+	mail_free(&mail);
+
+	ret = mailbox_search_deinit(&search_ctx);
+	if (mailbox_transaction_commit(&t) < 0)
+		ret = -1;
+
+	i_assert(result->search_args->args == &search_arg);
+	result->search_args->args = search_arg.next;
+	return ret;
+}
+
+void index_search_results_update_expunges(struct mailbox *box,
+					  const ARRAY_TYPE(seq_range) *expunges)
+{
+	struct index_mailbox *ibox = (struct index_mailbox *)box;
+	const struct seq_range *seqs;
+	unsigned int i, count;
+	uint32_t seq, uid;
+
+	if (array_count(&box->search_results) == 0)
+		return;
+
+	seqs = array_get(expunges, &count);
+	for (i = 0; i < count; i++) {
+		for (seq = seqs[i].seq1; seq <= seqs[i].seq2; seq++) {
+			mail_index_lookup_uid(ibox->view, seq, &uid);
+			mailbox_search_results_remove(box, uid);
+		}
+	}
+}
diff -r 38bdfafa655c -r 3ffac3f6173f src/lib-storage/index/index-search-result.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/index-search-result.h	Wed Jun 18 04:59:20 2008 +0300
@@ -0,0 +1,11 @@
+#ifndef INDEX_SEARCH_RESULT_H
+#define INDEX_SEARCH_RESULT_H
+
+int index_search_result_update_flags(struct mail_search_result *result,
+				     const ARRAY_TYPE(seq_range) *changes);
+int index_search_result_update_appends(struct mail_search_result *result,
+				       unsigned int old_messages_count);
+void index_search_results_update_expunges(struct mailbox *box,
+					  const ARRAY_TYPE(seq_range) *expunges);
+
+#endif
diff -r 38bdfafa655c -r 3ffac3f6173f src/lib-storage/index/index-sync-private.h
--- a/src/lib-storage/index/index-sync-private.h	Wed Jun 18 04:34:46 2008 +0300
+++ b/src/lib-storage/index/index-sync-private.h	Wed Jun 18 04:59:20 2008 +0300
@@ -11,6 +11,7 @@ struct index_mailbox_sync_context {
 
 	ARRAY_TYPE(seq_range) flag_updates;
 	ARRAY_TYPE(seq_range) hidden_updates;
+	ARRAY_TYPE(seq_range) *all_flag_updates, all_flag_updates_merge;
 	const ARRAY_TYPE(seq_range) *expunges;
 	unsigned int flag_update_idx, hidden_update_idx, expunge_pos;
 
diff -r 38bdfafa655c -r 3ffac3f6173f src/lib-storage/index/index-sync-search.c
--- a/src/lib-storage/index/index-sync-search.c	Wed Jun 18 04:34:46 2008 +0300
+++ b/src/lib-storage/index/index-sync-search.c	Wed Jun 18 04:59:20 2008 +0300
@@ -5,119 +5,13 @@
 #include "seq-range-array.h"
 #include "mail-search.h"
 #include "mailbox-search-result-private.h"
+#include "index-search-result.h"
 #include "index-sync-private.h"
-
-static void
-search_result_range_remove(struct mail_search_result *result,
-			   const ARRAY_TYPE(seq_range) *search_seqs_range,
-			   unsigned int *pos,
-			   uint32_t *next_seq, uint32_t last_seq)
-{
-	struct index_mailbox *ibox = (struct index_mailbox *)result->box;
-	const struct seq_range *seqs;
-	unsigned int i, count;
-	uint32_t seq, uid;
-
-	seq = *next_seq;
-	seqs = array_get(search_seqs_range, &count);
-	for (i = *pos; seqs[i].seq2 < last_seq;) {
-		i_assert(seqs[i].seq1 <= seq);
-		for (; seq <= seqs[i].seq2; seq++) {
-			mail_index_lookup_uid(ibox->view, seq, &uid);
-			mailbox_search_result_remove(result, uid);
-		}
-		i++;
-		i_assert(i < count);
-		seq = seqs[i].seq1;
-	}
-
-	i_assert(seqs[i].seq1 <= seq && seqs[i].seq2 >= last_seq);
-	for (; seq <= last_seq; seq++) {
-		mail_index_lookup_uid(ibox->view, seq, &uid);
-		mailbox_search_result_remove(result, uid);
-	}
-	if (seq > seqs[i].seq2) {
-		/* finished this range */
-		if (++i < count)
-			seq = seqs[i].seq1;
-		else {
-			/* this was the last searched message */
-			seq = 0;
-		}
-	}
-
-	*next_seq = seq;
-	*pos = i;
-}
-


More information about the dovecot-cvs mailing list