changeset 7656:94ad5f7d08ac HEAD

MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES: Avoid also keyword updates. Also fixed a bug with flag updates.
author Timo Sirainen <tss@iki.fi>
date Fri, 14 Mar 2008 08:23:44 +0200
parents ba8ae35ce462
children f83c391c2428
files src/lib-index/mail-index-transaction.c
diffstat 1 files changed, 62 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-transaction.c	Tue Mar 11 06:18:45 2008 +0200
+++ b/src/lib-index/mail-index-transaction.c	Fri Mar 14 08:23:44 2008 +0200
@@ -981,7 +981,8 @@
 			    (t->last_update_idx + 1 == count ||
 			     last_update[1].uid1 > seq2)) {
 				/* we can just update the UID range */
-				last_update->uid2 = seq2;
+				if (mail_transaction_update_want_add(t, &u))
+					last_update->uid2 = seq2;
 				return;
 			}
 		} else if (seq1 > last_update->uid2) {
@@ -1326,12 +1327,60 @@
 	*keywords = NULL;
 }
 
+static bool
+keyword_update_has_changes(struct mail_index_transaction *t, uint32_t seq,
+			   enum modify_type modify_type,
+			   struct mail_keywords *keywords)
+{
+	struct mail_index_transaction_keyword_update *u;
+	ARRAY_TYPE(keyword_indexes) existing;
+	const unsigned int *existing_idx;
+	unsigned int i, j, existing_count;
+	bool found;
+
+	t_array_init(&existing, 32);
+	mail_index_lookup_keywords(t->view, seq, &existing);
+	existing_idx = array_get(&existing, &existing_count);
+
+	if (modify_type == MODIFY_REPLACE && existing_count != keywords->count)
+		return TRUE;
+
+	for (i = 0; i < keywords->count; i++) {
+		u = array_idx_modifiable(&t->keyword_updates,
+					 keywords->idx[i]);
+		if (array_is_created(&u->add_seq) ||
+		    array_is_created(&u->remove_seq))
+			return TRUE;
+
+		found = FALSE;
+		for (j = 0; j < existing_count; j++) {
+			if (existing_idx[j] == keywords->idx[i]) {
+				found = TRUE;
+				break;
+			}
+		}
+		switch (modify_type) {
+		case MODIFY_ADD:
+		case MODIFY_REPLACE:
+			if (!found)
+				return TRUE;
+			break;
+		case MODIFY_REMOVE:
+			if (found)
+				return TRUE;
+			break;
+		}
+	}
+	return FALSE;
+}
+
 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;
 	unsigned int i, ku_count;
+	bool changed;
 
 	i_assert(seq > 0 &&
 		 (seq <= mail_index_view_get_messages_count(t->view) ||
@@ -1345,6 +1394,16 @@
 		i_array_init(&t->keyword_updates, max_idx + 1);
 	}
 
+	if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES) != 0) {
+		T_BEGIN {
+			changed = keyword_update_has_changes(t, seq,
+							     modify_type,
+							     keywords);
+		} T_END;
+		if (!changed)
+			return;
+	}
+
 	/* 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
@@ -1355,8 +1414,7 @@
 			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_remove(&u->remove_seq, seq);
+			seq_range_array_remove(&u->remove_seq, seq);
 		}
 		break;
 	case MODIFY_REMOVE:
@@ -1375,10 +1433,7 @@
 						 &ku_count);
 			for (i = 0; i < ku_count; i++) {
 				seq_range_array_remove(&u[i].add_seq, seq);
-				if (seq < t->first_new_seq) {
-					seq_range_array_remove(
-						&u[i].remove_seq, seq);
-				}
+				seq_range_array_remove(&u[i].remove_seq, seq);
 			}
 		}
 		/* Add the wanted keyword back */