dovecot-2.2: Don't write "keyword reset" records to transaction ...

dovecot at dovecot.org dovecot at dovecot.org
Tue May 22 17:05:03 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/2e7d718609fd
changeset: 14580:2e7d718609fd
user:      Timo Sirainen <tss at iki.fi>
date:      Tue May 22 17:03:20 2012 +0300
description:
Don't write "keyword reset" records to transaction log anymore.
These are a bit problematic for dsync's keyword merging to handle.

diffstat:

 src/lib-index/mail-index-sync.c                     |   22 ----
 src/lib-index/mail-index-transaction-export.c       |    6 -
 src/lib-index/mail-index-transaction-finish.c       |    1 -
 src/lib-index/mail-index-transaction-private.h      |    1 -
 src/lib-index/mail-index-transaction-sort-appends.c |   30 ++---
 src/lib-index/mail-index-transaction-update.c       |  107 +++++++++++--------
 src/lib-index/mail-index-transaction-view.c         |    6 -
 src/lib-index/mail-index.h                          |    3 +-
 src/lib-index/test-mail-index-transaction-update.c  |    8 +
 src/lib-storage/index/cydir/cydir-sync.c            |    1 -
 src/lib-storage/index/imapc/imapc-sync.c            |   23 ----
 src/lib-storage/index/index-sync-changes.c          |    2 -
 src/lib-storage/index/index-sync.c                  |    3 +-
 src/plugins/virtual/virtual-sync.c                  |    9 -
 14 files changed, 84 insertions(+), 138 deletions(-)

diffs (truncated from 467 to 300 lines):

diff -r fead3400c379 -r 2e7d718609fd src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c	Tue May 22 16:54:55 2012 +0300
+++ b/src/lib-index/mail-index-sync.c	Tue May 22 17:03:20 2012 +0300
@@ -242,12 +242,6 @@
 		synclist->array = (void *)&sync_trans->updates;
 	}
 
-	/* we must return resets before keyword additions or they get lost */
-	if (array_is_created(&sync_trans->keyword_resets)) {
-		synclist = array_append_space(&ctx->sync_list);
-		synclist->array = (void *)&sync_trans->keyword_resets;
-	}
-
 	keyword_updates = keyword_count == 0 ? NULL :
 		array_idx(&sync_trans->keyword_updates, 0);
 	for (i = 0; i < keyword_count; i++) {
@@ -655,14 +649,6 @@
 	rec->keyword_idx = sync_list->keyword_idx;
 }
 
-static void mail_index_sync_get_keyword_reset(struct mail_index_sync_rec *rec,
-					       const struct uid_range *range)
-{
-	rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
-	rec->uid1 = range->uid1;
-	rec->uid2 = range->uid2;
-}
-
 bool mail_index_sync_next(struct mail_index_sync_ctx *ctx,
 			  struct mail_index_sync_rec *sync_rec)
 {
@@ -720,8 +706,6 @@
 	} else if (sync_list[i].array == (void *)&sync_trans->updates) {
 		mail_index_sync_get_update(sync_rec,
 			(const struct mail_transaction_flag_update *)uid_range);
-	} else if (sync_list[i].array == (void *)&sync_trans->keyword_resets) {
-		mail_index_sync_get_keyword_reset(sync_rec, uid_range);
 	} else {
 		mail_index_sync_get_keyword_update(sync_rec, uid_range,
 						   &sync_list[i]);
@@ -921,12 +905,6 @@
 			}
 		}
 		return FALSE;
-	case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
-		if (array_count(keywords) == 0)
-			return FALSE;
-
-		array_clear(keywords);
-		return TRUE;
 	default:
 		i_unreached();
 		return FALSE;
diff -r fead3400c379 -r 2e7d718609fd src/lib-index/mail-index-transaction-export.c
--- a/src/lib-index/mail-index-transaction-export.c	Tue May 22 16:54:55 2012 +0300
+++ b/src/lib-index/mail-index-transaction-export.c	Tue May 22 17:03:20 2012 +0300
@@ -386,12 +386,6 @@
 				    MAIL_TRANSACTION_EXT_ATOMIC_INC);
 	}
 
-	/* keyword resets before updates */
-	if (array_is_created(&t->keyword_resets)) {
-		change_mask |= MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
-		log_append_buffer(&ctx, t->keyword_resets.arr.buffer,
-				  MAIL_TRANSACTION_KEYWORD_RESET);
-	}
 	if (array_is_created(&t->keyword_updates))
 		change_mask |= log_append_keyword_updates(&ctx);
 	/* keep modseq updates almost last */
diff -r fead3400c379 -r 2e7d718609fd src/lib-index/mail-index-transaction-finish.c
--- a/src/lib-index/mail-index-transaction-finish.c	Tue May 22 16:54:55 2012 +0300
+++ b/src/lib-index/mail-index-transaction-finish.c	Tue May 22 17:03:20 2012 +0300
@@ -313,7 +313,6 @@
 	expunges_convert_to_uids(t);
 	mail_index_convert_to_uids(t, (void *)&t->modseq_updates);
 	mail_index_convert_to_uid_ranges(t, (void *)&t->updates);
-	mail_index_convert_to_uid_ranges(t, &t->keyword_resets);
 }
 
 void mail_index_transaction_finish(struct mail_index_transaction *t)
diff -r fead3400c379 -r 2e7d718609fd src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h	Tue May 22 16:54:55 2012 +0300
+++ b/src/lib-index/mail-index-transaction-private.h	Tue May 22 17:03:20 2012 +0300
@@ -66,7 +66,6 @@
 
 	ARRAY_DEFINE(keyword_updates,
 		     struct mail_index_transaction_keyword_update);
-	ARRAY_TYPE(seq_range) keyword_resets;
 
 	uint64_t min_highest_modseq;
 	uint64_t max_modseq;
diff -r fead3400c379 -r 2e7d718609fd src/lib-index/mail-index-transaction-sort-appends.c
--- a/src/lib-index/mail-index-transaction-sort-appends.c	Tue May 22 16:54:55 2012 +0300
+++ b/src/lib-index/mail-index-transaction-sort-appends.c	Tue May 22 17:03:20 2012 +0300
@@ -106,24 +106,20 @@
 {
 	struct mail_index_transaction_keyword_update *update;
 
-	if (array_is_created(&t->keyword_updates)) {
-		array_foreach_modifiable(&t->keyword_updates, update) {
-			if (array_is_created(&update->add_seq)) {
-				sort_appends_seq_range(&update->add_seq,
-						       t->first_new_seq,
-						       old_to_newseq_map);
-			}
-			if (array_is_created(&update->remove_seq)) {
-				sort_appends_seq_range(&update->remove_seq,
-						       t->first_new_seq,
-						       old_to_newseq_map);
-			}
+	if (!array_is_created(&t->keyword_updates))
+		return;
+
+	array_foreach_modifiable(&t->keyword_updates, update) {
+		if (array_is_created(&update->add_seq)) {
+			sort_appends_seq_range(&update->add_seq,
+					       t->first_new_seq,
+					       old_to_newseq_map);
 		}
-	}
-
-	if (array_is_created(&t->keyword_resets)) {
-		sort_appends_seq_range(&t->keyword_resets, t->first_new_seq,
-				       old_to_newseq_map);
+		if (array_is_created(&update->remove_seq)) {
+			sort_appends_seq_range(&update->remove_seq,
+					       t->first_new_seq,
+					       old_to_newseq_map);
+		}
 	}
 }
 
diff -r fead3400c379 -r 2e7d718609fd src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c	Tue May 22 16:54:55 2012 +0300
+++ b/src/lib-index/mail-index-transaction-update.c	Tue May 22 17:03:20 2012 +0300
@@ -59,8 +59,6 @@
 		}
 		array_free(&t->keyword_updates);
 	}
-	if (array_is_created(&t->keyword_resets))
-		array_free(&t->keyword_resets);
 
 	if (array_is_created(&t->appends))
 		array_free(&t->appends);
@@ -107,7 +105,6 @@
 	t->log_updates = array_is_created(&t->appends) ||
 		array_is_created(&t->modseq_updates) ||
 		array_is_created(&t->expunges) ||
-		array_is_created(&t->keyword_resets) ||
 		array_is_created(&t->keyword_updates) ||
 		t->pre_hdr_changed || t->post_hdr_changed ||
 		t->min_highest_modseq != 0;
@@ -304,8 +301,6 @@
 	t->log_ext_updates = mail_index_transaction_has_ext_changes(t);
 
 	/* remove keywords */
-	if (array_is_created(&t->keyword_resets))
-		seq_range_array_remove(&t->keyword_resets, seq);
 	if (array_is_created(&t->keyword_updates)) {
 		array_foreach_modifiable(&t->keyword_updates, kw_update) {
 			if (array_is_created(&kw_update->add_seq)) {
@@ -987,8 +982,12 @@
 		u = array_idx_modifiable(&t->keyword_updates,
 					 keywords->idx[i]);
 		if (array_is_created(&u->add_seq) ||
-		    array_is_created(&u->remove_seq))
+		    array_is_created(&u->remove_seq)) {
+			/* we've already modified this keyword in the
+			   transaction. don't bother checking it further,
+			   because we can't avoid the changes anyway. */
 			return TRUE;
+		}
 
 		found = FALSE;
 		for (j = 0; j < existing_count; j++) {
@@ -1012,11 +1011,25 @@
 	return FALSE;
 }
 
+static struct mail_keywords *
+keyword_update_remove_existing(struct mail_index_transaction *t, uint32_t seq)
+{
+	ARRAY_TYPE(keyword_indexes) keywords;
+
+	t_array_init(&keywords, 32);
+	mail_index_transaction_lookup_latest_keywords(t, seq, &keywords);
+	if (array_count(&keywords) == 0)
+		return NULL;
+	return mail_index_keywords_create_from_indexes(t->view->index,
+						       &keywords);
+}
+
 void mail_index_update_keywords(struct mail_index_transaction *t, uint32_t seq,
 				enum modify_type modify_type,
 				struct mail_keywords *keywords)
 {
 	struct mail_index_transaction_keyword_update *u;
+	struct mail_keywords *add_keywords = NULL, *remove_keywords = NULL;
 	unsigned int i;
 	bool changed;
 
@@ -1028,8 +1041,9 @@
 
 	update_minmax_flagupdate_seq(t, seq, seq);
 
-	if (!array_is_created(&t->keyword_updates) && keywords->count > 0) {
-		uint32_t max_idx = keywords->idx[keywords->count-1];
+	if (!array_is_created(&t->keyword_updates)) {
+		uint32_t max_idx = keywords->count == 0 ? 3 :
+			keywords->idx[keywords->count-1];
 
 		i_array_init(&t->keyword_updates, max_idx + 1);
 	}
@@ -1044,46 +1058,48 @@
 			return;
 	}
 
+	switch (modify_type) {
+	case MODIFY_REPLACE:
+		/* split this into add+remove. remove all existing keywords not
+		   included in the keywords list */
+		if (seq < t->first_new_seq) {
+			/* remove the ones currently in index */
+			remove_keywords = keyword_update_remove_existing(t, seq);
+		}
+		/* remove from all changes we've done in this transaction */
+		array_foreach_modifiable(&t->keyword_updates, u)
+			seq_range_array_remove(&u->add_seq, seq);
+		add_keywords = keywords;
+		break;
+	case MODIFY_ADD:
+		add_keywords = keywords;
+		break;
+	case MODIFY_REMOVE:
+		remove_keywords = keywords;
+		break;
+	}
+
 	/* Update add_seq and remove_seq arrays which describe the keyword
-	   changes. Don't bother updating remove_seq or keyword resets for
-	   newly added messages since they default to not having any
-	   keywords anyway. */
-	switch (modify_type) {
-	case MODIFY_ADD:
-		for (i = 0; i < keywords->count; i++) {
+	   changes. First do the removes, since replace removes everything
+	   first. */
+	if (remove_keywords != NULL) {
+		for (i = 0; i < remove_keywords->count; i++) {
 			u = array_idx_modifiable(&t->keyword_updates,
-						 keywords->idx[i]);
+						 remove_keywords->idx[i]);
+			seq_range_array_remove(&u->add_seq, seq);
+			/* Don't bother updating remove_seq for new messages,
+			   since their initial state is "no keyword" anyway */
+			if (seq < t->first_new_seq)
+				seq_range_array_add(&u->remove_seq, 16, seq);
+		}
+	}
+	if (add_keywords != NULL) {
+		for (i = 0; i < add_keywords->count; i++) {
+			u = array_idx_modifiable(&t->keyword_updates,
+						 add_keywords->idx[i]);
 			seq_range_array_add(&u->add_seq, 16, seq);
 			seq_range_array_remove(&u->remove_seq, seq);
 		}
-		break;
-	case MODIFY_REMOVE:
-		for (i = 0; i < keywords->count; i++) {
-			u = array_idx_modifiable(&t->keyword_updates,
-						 keywords->idx[i]);
-			seq_range_array_remove(&u->add_seq, seq);
-			if (seq < t->first_new_seq)
-				seq_range_array_add(&u->remove_seq, 16, seq);
-		}
-		break;
-	case MODIFY_REPLACE:
-		/* Remove sequence from all add/remove arrays */
-		if (array_is_created(&t->keyword_updates)) {
-			array_foreach_modifiable(&t->keyword_updates, u) {
-				seq_range_array_remove(&u->add_seq, seq);
-				seq_range_array_remove(&u->remove_seq, seq);
-			}
-		}
-		/* Add the wanted keyword back */
-		for (i = 0; i < keywords->count; i++) {
-			u = array_idx_modifiable(&t->keyword_updates,
-						 keywords->idx[i]);
-			seq_range_array_add(&u->add_seq, 16, seq);
-		}
-
-		if (seq < t->first_new_seq)
-			seq_range_array_add(&t->keyword_resets, 16, seq);
-		break;
 	}
 
 	t->log_updates = TRUE;
@@ -1144,11 +1160,10 @@
 				       uint32_t seq)
 {


More information about the dovecot-cvs mailing list