dovecot: Added MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES and

dovecot at dovecot.org dovecot at dovecot.org
Thu Jul 19 02:56:47 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/c8d7b9fd500e
changeset: 6091:c8d7b9fd500e
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jul 19 02:51:54 2007 +0300
description:
Added MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES and
MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES flags to make
mail_index_update_flags() not do anything if the flags in view already are
those.

diffstat:

3 files changed, 45 insertions(+), 9 deletions(-)
src/lib-index/mail-index-sync.c        |    7 ++++--
src/lib-index/mail-index-transaction.c |   37 +++++++++++++++++++++++++++-----
src/lib-index/mail-index.h             |   10 ++++++--

diffs (133 lines):

diff -r 56f8a4dd819d -r c8d7b9fd500e src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c	Thu Jul 19 02:36:37 2007 +0300
+++ b/src/lib-index/mail-index-sync.c	Thu Jul 19 02:51:54 2007 +0300
@@ -309,6 +309,7 @@ int mail_index_sync_begin(struct mail_in
 	const struct mail_index_header *hdr;
 	struct mail_index_sync_ctx *ctx;
 	struct mail_index_view *sync_view;
+	enum mail_index_transaction_flags trans_flags;
 	uint32_t seq;
 	uoff_t offset;
 	int ret;
@@ -395,8 +396,10 @@ int mail_index_sync_begin(struct mail_in
 
 	/* create the transaction after the view has been updated with
 	   external transactions and marked as sync view */
-	ctx->ext_trans = mail_index_transaction_begin(ctx->view,
-					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
+	trans_flags = MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
+	if ((ctx->flags & MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) != 0)
+		trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES;
+	ctx->ext_trans = mail_index_transaction_begin(ctx->view, trans_flags);
 
 	*ctx_r = ctx;
 	*view_r = ctx->view;
diff -r 56f8a4dd819d -r c8d7b9fd500e src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c	Thu Jul 19 02:36:37 2007 +0300
+++ b/src/lib-index/mail-index-transaction.c	Thu Jul 19 02:51:54 2007 +0300
@@ -596,6 +596,28 @@ void mail_index_expunge(struct mail_inde
 
 	/* expunges is a sorted array of {seq1, seq2, ..}, .. */
 	seq_range_array_add(&t->expunges, 128, seq);
+}
+
+static bool
+mail_transaction_update_want_add(struct mail_index_transaction *t,
+				 const struct mail_transaction_flag_update *u)
+{
+	const struct mail_index_record *rec;
+	uint32_t seq;
+	
+	if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES) == 0)
+		return TRUE;
+
+	for (seq = u->uid1; seq <= u->uid2; seq++) {
+		if (mail_index_lookup(t->view, seq, &rec) < 0)
+			return TRUE;
+
+		if ((rec->flags & u->add_flags) != u->add_flags ||
+		    (rec->flags & u->remove_flags) != 0)
+			return TRUE;
+	}
+
+	return FALSE;
 }
 
 static void
@@ -651,7 +673,8 @@ mail_index_insert_flag_update(struct mai
 			i_assert(tmp_update.uid1 <= tmp_update.uid2);
 			i_assert(updates[idx].uid1 <= updates[idx].uid2);
 
-			array_insert(&t->updates, idx, &tmp_update, 1);
+			if (mail_transaction_update_want_add(t, &tmp_update))
+				array_insert(&t->updates, idx, &tmp_update, 1);
 			updates = array_get_modifiable(&t->updates, &count);
 			idx += move;
 		} else if (u.uid1 < updates[idx].uid1) {
@@ -669,7 +692,8 @@ mail_index_insert_flag_update(struct mai
 			i_assert(tmp_update.uid1 <= tmp_update.uid2);
 			i_assert(updates[idx].uid1 <= updates[idx].uid2);
 
-			array_insert(&t->updates, idx, &tmp_update, 1);
+			if (mail_transaction_update_want_add(t, &tmp_update))
+				array_insert(&t->updates, idx, &tmp_update, 1);
 			updates = array_get_modifiable(&t->updates, &count);
 		}
 
@@ -700,7 +724,8 @@ mail_index_insert_flag_update(struct mai
 	if (u.uid1 <= u.uid2) {
 		i_assert(idx == 0 || updates[idx-1].uid2 < u.uid1);
 		i_assert(idx == count || updates[idx].uid1 > u.uid2);
-		array_insert(&t->updates, idx, &u, 1);
+		if (mail_transaction_update_want_add(t, &u))
+			array_insert(&t->updates, idx, &u, 1);
 	}
 	t->last_update_idx = idx;
 }
@@ -770,7 +795,8 @@ void mail_index_update_flags_range(struc
 
 	if (!array_is_created(&t->updates)) {
 		i_array_init(&t->updates, 256);
-		array_append(&t->updates, &u, 1);
+		if (mail_transaction_update_want_add(t, &u))
+			array_append(&t->updates, &u, 1);
 		return;
 	}
 
@@ -796,7 +822,8 @@ void mail_index_update_flags_range(struc
 	}
 
 	if (t->last_update_idx == count) {
-		array_append(&t->updates, &u, 1);
+		if (mail_transaction_update_want_add(t, &u))
+			array_append(&t->updates, &u, 1);
 		return;
 	}
 
diff -r 56f8a4dd819d -r c8d7b9fd500e src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h	Thu Jul 19 02:36:37 2007 +0300
+++ b/src/lib-index/mail-index.h	Thu Jul 19 02:51:54 2007 +0300
@@ -106,7 +106,11 @@ enum mail_index_transaction_flags {
 	MAIL_INDEX_TRANSACTION_FLAG_HIDE		= 0x01,
 	/* External transactions describe changes to mailbox that have already
 	   happened. */
-	MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL		= 0x02
+	MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL		= 0x02,
+	/* Don't add flag updates unless they actually change something.
+	   This is reliable only when syncing, otherwise someone else might
+	   have already committed a transaction that had changed the flags. */
+	MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES	= 0x04
 };
 
 enum mail_index_sync_type {
@@ -122,7 +126,9 @@ enum mail_index_sync_flags {
 	/* Resync all dirty messages' flags. */
 	MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY	= 0x01,
 	/* Drop recent flags from all messages */
-	MAIL_INDEX_SYNC_FLAG_DROP_RECENT	= 0x02
+	MAIL_INDEX_SYNC_FLAG_DROP_RECENT	= 0x02,
+	/* Create the transaction with AVOID_FLAG_UPDATES flag */
+	MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES	= 0x04,
 };
 
 enum mail_index_view_sync_flags {


More information about the dovecot-cvs mailing list