changeset 3821:c8b2ed2c9961 HEAD

We assumed that keyword index arrays were always sorted. This isn't always the case. Caused unneeded keyword updates.
author Timo Sirainen <tss@iki.fi>
date Fri, 06 Jan 2006 16:50:34 +0200
parents ec0119de5aa2
children 5ba04396479d
files src/lib-index/mail-index.h src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/mbox/mbox-sync.c
diffstat 5 files changed, 35 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index.h	Fri Jan 06 16:40:36 2006 +0200
+++ b/src/lib-index/mail-index.h	Fri Jan 06 16:50:34 2006 +0200
@@ -264,6 +264,7 @@
 int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
 			   struct mail_index_map **map_r,
 			   const struct mail_index_record **rec_r);
+/* Note that returned keyword indexes aren't sorted. */
 int mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
 			       array_t *keyword_idx);
 /* Returns the UID for given message. May be slightly faster than
--- a/src/lib-storage/index/index-storage.h	Fri Jan 06 16:40:36 2006 +0200
+++ b/src/lib-storage/index/index-storage.h	Fri Jan 06 16:50:34 2006 +0200
@@ -179,4 +179,6 @@
 int index_transaction_commit(struct mailbox_transaction_context *t);
 void index_transaction_rollback(struct mailbox_transaction_context *t);
 
+int index_keyword_array_cmp(const array_t *k1, const array_t *k2);
+
 #endif
--- a/src/lib-storage/index/index-sync.c	Fri Jan 06 16:40:36 2006 +0200
+++ b/src/lib-storage/index/index-sync.c	Fri Jan 06 16:50:34 2006 +0200
@@ -267,3 +267,32 @@
 	i_free(ctx);
 	return ret;
 }
+
+int index_keyword_array_cmp(const array_t *k1, const array_t *k2)
+{
+	ARRAY_SET_TYPE(k1, unsigned int);
+	ARRAY_SET_TYPE(k2, unsigned int);
+	const unsigned int *idx1, *idx2;
+	unsigned int i, j, count1, count2;
+
+	/* The arrays may not be sorted, but they usually are. Optimize for
+	   the assumption that they are */
+	idx1 = array_get(k1, &count1);
+	idx2 = array_get(k2, &count2);
+
+	if (count1 != count2)
+		return FALSE;
+
+	for (i = 0; i < count1; i++) {
+		if (idx1[i] != idx2[i]) {
+			/* not found / unsorted array. check. */
+			for (j = 0; j < count1; j++) {
+				if (idx1[i] == idx2[j])
+					break;
+			}
+			if (j == count1)
+				return FALSE;
+		}
+	}
+	return TRUE;
+}
--- a/src/lib-storage/index/maildir/maildir-sync.c	Fri Jan 06 16:40:36 2006 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Fri Jan 06 16:50:34 2006 +0200
@@ -1044,12 +1044,11 @@
 		}
 
 		/* update keywords if they have changed */
-		array_clear(&idx_keywords);
 		if (mail_index_lookup_keywords(view, seq, &idx_keywords) < 0) {
 			ret = -1;
 			break;
 		}
-		if (!array_cmp(&keywords, &idx_keywords)) {
+		if (!index_keyword_array_cmp(&keywords, &idx_keywords)) {
 			struct mail_keywords *kw;
 
 			kw = mail_index_keywords_create_from_indexes(
--- a/src/lib-storage/index/mbox/mbox-sync.c	Fri Jan 06 16:40:36 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Fri Jan 06 16:50:34 2006 +0200
@@ -517,7 +517,8 @@
 		}
 
 		if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) == 0 &&
-		    !array_cmp(&idx_mail.keywords, &mail_ctx->mail.keywords))
+		    !index_keyword_array_cmp(&idx_mail.keywords,
+					     &mail_ctx->mail.keywords))
 			mbox_sync_update_index_keywords(mail_ctx);
 		t_pop();