dovecot-2.0: mail index transactions: More code cleanups and uni...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jul 15 00:55:33 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/b45be8d8b388
changeset: 9626:b45be8d8b388
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jul 14 17:55:27 2009 -0400
description:
mail index transactions: More code cleanups and unit tests.

diffstat:

6 files changed, 382 insertions(+), 67 deletions(-)
src/lib-index/Makefile.am                          |    5 
src/lib-index/mail-index-transaction-finish.c      |   71 ------
src/lib-index/mail-index-transaction-private.h     |    5 
src/lib-index/mail-index-transaction-update.c      |   77 +++++++
src/lib-index/test-mail-index-transaction-finish.c |  213 ++++++++++++++++++++
src/lib-index/test-mail-index-transaction-update.c |   78 +++++++

diffs (truncated from 536 to 300 lines):

diff -r e8b9f78d2b3c -r b45be8d8b388 src/lib-index/Makefile.am
--- a/src/lib-index/Makefile.am	Tue Jul 14 17:54:23 2009 -0400
+++ b/src/lib-index/Makefile.am	Tue Jul 14 17:55:27 2009 -0400
@@ -61,6 +61,7 @@ headers = \
         mailbox-list-index-private.h
 
 test_programs = \
+	test-mail-index-transaction-finish \
 	test-mail-index-transaction-update \
 	test-mail-transaction-log-append \
 	test-mail-transaction-log-view
@@ -71,6 +72,10 @@ test_libs = \
 	mail-index-util.lo \
 	../lib-test/libtest.la \
 	../lib/liblib.la
+
+test_mail_index_transaction_finish_SOURCES = test-mail-index-transaction-finish.c
+test_mail_index_transaction_finish_LDADD = mail-index-transaction-finish.lo $(test_libs)
+test_mail_index_transaction_finish_DEPENDENCIES = mail-index-transaction-finish.lo $(test_libs)
 
 test_mail_index_transaction_update_SOURCES = test-mail-index-transaction-update.c
 test_mail_index_transaction_update_LDADD = mail-index-transaction-update.lo $(test_libs)
diff -r e8b9f78d2b3c -r b45be8d8b388 src/lib-index/mail-index-transaction-finish.c
--- a/src/lib-index/mail-index-transaction-finish.c	Tue Jul 14 17:54:23 2009 -0400
+++ b/src/lib-index/mail-index-transaction-finish.c	Tue Jul 14 17:55:27 2009 -0400
@@ -140,76 +140,11 @@ mail_index_transaction_finish_flag_updat
 		array_free(&t->updates);
 }
 
-static bool
-mail_index_update_cancel_array(ARRAY_TYPE(seq_range) *array, uint32_t seq)
-{
-	if (array_is_created(array)) {
-		if (seq_range_array_remove(array, seq)) {
-			if (array_count(array) == 0)
-				array_free(array);
-			return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-static bool
-mail_index_update_cancel(struct mail_index_transaction *t, uint32_t seq)
-{
-	struct mail_index_transaction_keyword_update *kw;
-	struct mail_transaction_flag_update *updates, tmp_update;
-	unsigned int i, count;
-	bool ret, have_kw_changes = FALSE;
-
-	ret = mail_index_update_cancel_array(&t->keyword_resets, seq);
-	if (array_is_created(&t->keyword_updates)) {
-		kw = array_get_modifiable(&t->keyword_updates, &count);
-		for (i = 0; i < count; i++) {
-			if (mail_index_update_cancel_array(&kw[i].add_seq, seq))
-				ret = TRUE;
-			if (mail_index_update_cancel_array(&kw[i].remove_seq,
-							   seq))
-				ret = TRUE;
-			if (array_is_created(&kw[i].add_seq) ||
-			    array_is_created(&kw[i].remove_seq))
-				have_kw_changes = TRUE;
-		}
-		if (!have_kw_changes)
-			array_free(&t->keyword_updates);
-	}
-
-	if (!array_is_created(&t->updates))
-		return ret;
-
-	updates = array_get_modifiable(&t->updates, &count);
-	i = mail_index_transaction_get_flag_update_pos(t, 0, count, seq);
-	if (i < count && updates[i].uid1 <= seq && updates[i].uid2 >= seq) {
-		/* exists */
-		ret = TRUE;
-		if (updates[i].uid1 == seq && updates[i].uid2 == seq) {
-			if (count > 1)
-				array_delete(&t->updates, i, 1);
-			else
-				array_free(&t->updates);
-		} else if (updates[i].uid1 == seq)
-			updates[i].uid1++;
-		else if (updates[i].uid2 == seq)
-			updates[i].uid2--;
-		else {
-			/* need to split it in two */
-			tmp_update = updates[i];
-			tmp_update.uid1 = seq+1;
-			updates[i].uid2 = seq-1;
-			array_insert(&t->updates, i + 1, &tmp_update, 1);
-		}
-	}
-	return ret;
-}
-
 static void
 mail_index_transaction_check_conflicts(struct mail_index_transaction *t)
 {
 	uint32_t seq;
+	bool ret1, ret2;
 
 	i_assert(t->max_modseq != 0);
 	i_assert(t->conflict_seqs != NULL);
@@ -225,7 +160,9 @@ mail_index_transaction_check_conflicts(s
 
 	for (seq = t->min_flagupdate_seq; seq <= t->max_flagupdate_seq; seq++) {
 		if (mail_index_modseq_lookup(t->view, seq) > t->max_modseq) {
-			if (mail_index_update_cancel(t, seq))
+			ret1 = mail_index_cancel_flag_updates(t, seq);
+			ret2 = mail_index_cancel_keyword_updates(t, seq);
+			if (ret1 || ret2)
 				seq_range_array_add(t->conflict_seqs, 0, seq);
 		}
 	}
diff -r e8b9f78d2b3c -r b45be8d8b388 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h	Tue Jul 14 17:54:23 2009 -0400
+++ b/src/lib-index/mail-index-transaction-private.h	Tue Jul 14 17:55:27 2009 -0400
@@ -116,6 +116,11 @@ mail_index_transaction_get_flag_update_p
 					   unsigned int right_idx,
 					   uint32_t seq);
 
+bool mail_index_cancel_flag_updates(struct mail_index_transaction *t,
+				    uint32_t seq);
+bool mail_index_cancel_keyword_updates(struct mail_index_transaction *t,
+				       uint32_t seq);
+
 int mail_index_transaction_finish(struct mail_index_transaction *t);
 void mail_index_transaction_export(struct mail_index_transaction *t,
 				   struct mail_transaction_log_append_ctx *append_ctx);
diff -r e8b9f78d2b3c -r b45be8d8b388 src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c	Tue Jul 14 17:54:23 2009 -0400
+++ b/src/lib-index/mail-index-transaction-update.c	Tue Jul 14 17:55:27 2009 -0400
@@ -1013,6 +1013,83 @@ void mail_index_update_keywords(struct m
 	t->log_updates = TRUE;
 }
 
+bool mail_index_cancel_flag_updates(struct mail_index_transaction *t,
+				    uint32_t seq)
+{
+	struct mail_transaction_flag_update *updates, tmp_update;
+	unsigned int i, count;
+
+	if (!array_is_created(&t->updates))
+		return FALSE;
+
+	updates = array_get_modifiable(&t->updates, &count);
+	i = mail_index_transaction_get_flag_update_pos(t, 0, count, seq);
+	if (i == count)
+		return FALSE;
+	else {
+		i_assert(seq <= updates[i].uid2);
+		if (seq < updates[i].uid1)
+			return FALSE;
+	}
+
+	/* exists */
+	if (updates[i].uid1 == seq) {
+		if (updates[i].uid2 != seq)
+			updates[i].uid1++;
+		else if (count > 1)
+			array_delete(&t->updates, i, 1);
+		else
+			array_free(&t->updates);
+	} else if (updates[i].uid2 == seq) {
+		updates[i].uid2--;
+	} else {
+		/* need to split it in two */
+		tmp_update = updates[i];
+		tmp_update.uid1 = seq+1;
+		updates[i].uid2 = seq-1;
+		array_insert(&t->updates, i + 1, &tmp_update, 1);
+	}
+	return TRUE;
+}
+
+static bool mail_index_cancel_array(ARRAY_TYPE(seq_range) *array, uint32_t seq)
+{
+	if (array_is_created(array)) {
+		if (seq_range_array_remove(array, seq)) {
+			if (array_count(array) == 0)
+				array_free(array);
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+bool mail_index_cancel_keyword_updates(struct mail_index_transaction *t,
+				       uint32_t seq)
+{
+	struct mail_index_transaction_keyword_update *kw;
+	unsigned int i, count;
+	bool ret, have_kw_changes = FALSE;
+
+	ret = mail_index_cancel_array(&t->keyword_resets, seq);
+	if (!array_is_created(&t->keyword_updates))
+		return ret;
+
+	kw = array_get_modifiable(&t->keyword_updates, &count);
+	for (i = 0; i < count; i++) {
+		if (mail_index_cancel_array(&kw[i].add_seq, seq))
+			ret = TRUE;
+		if (mail_index_cancel_array(&kw[i].remove_seq, seq))
+			ret = TRUE;
+		if (array_is_created(&kw[i].add_seq) ||
+		    array_is_created(&kw[i].remove_seq))
+			have_kw_changes = TRUE;
+	}
+	if (!have_kw_changes)
+		array_free(&t->keyword_updates);
+	return ret;
+}
+
 void mail_index_transaction_reset(struct mail_index_transaction *t)
 {
 	t->v.reset(t);
diff -r e8b9f78d2b3c -r b45be8d8b388 src/lib-index/test-mail-index-transaction-finish.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-index/test-mail-index-transaction-finish.c	Tue Jul 14 17:55:27 2009 -0400
@@ -0,0 +1,213 @@
+/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "test-common.h"
+#include "mail-index-private.h"
+#include "mail-index-modseq.h"
+#include "mail-index-transaction-private.h"
+
+#include <stdlib.h>
+
+static struct mail_index_record recs[20];
+static uint64_t modseqs[N_ELEMENTS(recs)];
+
+bool mail_index_map_get_ext_idx(struct mail_index_map *map ATTR_UNUSED,
+				uint32_t ext_id ATTR_UNUSED,
+				uint32_t *idx_r ATTR_UNUSED) { return FALSE; }
+void mail_index_ext_set_reset_id(struct mail_index_transaction *t ATTR_UNUSED,
+				 uint32_t ext_id ATTR_UNUSED,
+				 uint32_t reset_id ATTR_UNUSED) { }
+void mail_index_transaction_set_log_updates(struct mail_index_transaction *t ATTR_UNUSED) { }
+void mail_index_update_day_headers(struct mail_index_transaction *t ATTR_UNUSED) {}
+bool mail_index_cancel_flag_updates(struct mail_index_transaction *t ATTR_UNUSED,
+				    uint32_t seq ATTR_UNUSED) { return TRUE; }
+bool mail_index_cancel_keyword_updates(struct mail_index_transaction *t ATTR_UNUSED,
+				       uint32_t seq ATTR_UNUSED) { return TRUE; }
+void mail_index_transaction_sort_appends(struct mail_index_transaction *t ATTR_UNUSED) {}
+int mail_index_map(struct mail_index *index ATTR_UNUSED,
+		   enum mail_index_sync_handler_type type ATTR_UNUSED) { return 1; }
+
+const struct mail_index_record *
+mail_index_lookup(struct mail_index_view *view ATTR_UNUSED, uint32_t seq)
+{
+	i_assert(seq < N_ELEMENTS(recs));
+	return &recs[seq];
+}
+
+struct mail_index_record *
+mail_index_transaction_lookup(struct mail_index_transaction *t ATTR_UNUSED,
+			      uint32_t seq)
+{
+	i_assert(seq < N_ELEMENTS(recs));
+	return &recs[seq];
+}
+
+uint64_t mail_index_modseq_lookup(struct mail_index_view *view ATTR_UNUSED,
+				  uint32_t seq)
+{
+	i_assert(seq < N_ELEMENTS(modseqs));
+	return modseqs[seq];
+}
+
+uint64_t mail_index_modseq_get_highest(struct mail_index_view *view ATTR_UNUSED)
+{
+	return modseqs[0];
+}
+
+static void test_mail_index_transaction_finish_flag_updates(void)
+{
+	struct mail_index_transaction *t;
+	const struct mail_transaction_flag_update *updates;
+	struct mail_transaction_flag_update u;
+	unsigned int count;
+
+	t = t_new(struct mail_index_transaction, 1);
+	t->drop_unnecessary_flag_updates = TRUE;
+
+	memset(&u, 0, sizeof(u));
+	u.add_flags = MAIL_SEEN; u.remove_flags = MAIL_DRAFT;
+
+	test_begin("mail index transaction finish flag updates");
+
+	/* test fast path: all changed */
+	t_array_init(&t->updates, 10);
+	u.uid1 = 1; u.uid2 = 2;
+	array_append(&t->updates, &u, 1);
+	u.uid1 = 4; u.uid2 = 5;
+	array_append(&t->updates, &u, 1);
+	mail_index_transaction_finish(t);
+


More information about the dovecot-cvs mailing list