dovecot-2.0: lib-index: Fixes to handling UID changes.

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 6 03:30:50 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/773b91d3ed13
changeset: 9724:773b91d3ed13
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Aug 05 20:01:02 2009 -0400
description:
lib-index: Fixes to handling UID changes.

diffstat:

5 files changed, 67 insertions(+), 15 deletions(-)
src/lib-index/mail-index-sync-update.c        |    4 -
src/lib-index/mail-index-transaction-export.c |   67 +++++++++++++++++++++----
src/lib-index/mail-index-transaction-update.c |    2 
src/lib-index/mail-index-transaction.c        |    8 +-
src/lib-index/mail-transaction-log-file.c     |    1 

diffs (149 lines):

diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-sync-update.c	Wed Aug 05 20:01:02 2009 -0400
@@ -301,10 +301,10 @@ static void sync_uid_update(struct mail_
 	map->hdr.next_uid = new_uid+1;
 	map->rec_map->last_appended_uid = new_uid;
 
-	rec = MAIL_INDEX_MAP_IDX(map, old_seq-1);
-
 	/* add the new record */
 	dest = sync_append_record(map);
+	rec = MAIL_INDEX_MAP_IDX(map, old_seq-1);
+	rec->uid = new_uid;
 	memcpy(dest, rec, map->hdr.record_size);
 
 	/* @UNSAFE: remove the old record */
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-transaction-export.c
--- a/src/lib-index/mail-index-transaction-export.c	Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-transaction-export.c	Wed Aug 05 20:01:02 2009 -0400
@@ -327,6 +327,61 @@ log_append_keyword_updates(struct mail_i
 	return change_mask;
 }
 
+static bool
+mail_index_transaction_export_new_uids(struct mail_index_export_context *ctx,
+				       struct mail_index_transaction *t)
+{
+	const struct mail_index_record *appends;
+	const struct mail_transaction_uid_update *updates;
+	unsigned int a, u, append_count, update_count;
+
+	if (!array_is_created(&t->uid_updates)) {
+		/* fast path */
+		if (!array_is_created(&t->appends))
+			return FALSE;
+
+		log_append_buffer(ctx, t->appends.arr.buffer,
+				  MAIL_TRANSACTION_APPEND);
+		return TRUE;
+	}
+	if (!array_is_created(&t->appends)) {
+		log_append_buffer(ctx, t->uid_updates.arr.buffer,
+				  MAIL_TRANSACTION_UID_UPDATE);
+		return TRUE;
+	}
+
+	/* we'll need to merge so that UIDs are only being appended.
+	   appends quite a lot of separate records unnecessarily,
+	   but UID updates are rare.. */
+	appends = array_get(&t->appends, &append_count);
+	updates = array_get(&t->uid_updates, &update_count);
+
+	for (a = u = 0; a < append_count && u < update_count; ) {
+		if (appends[a].uid < updates[u].new_uid) {
+			mail_transaction_log_append_add(ctx->append_ctx,
+					MAIL_TRANSACTION_APPEND,
+					&appends[a], sizeof(appends[a]));
+			a++;
+		} else {
+			mail_transaction_log_append_add(ctx->append_ctx,
+					MAIL_TRANSACTION_UID_UPDATE,
+					&updates[u], sizeof(updates[u]));
+			u++;
+		}
+	}
+	if (a < append_count) {
+		mail_transaction_log_append_add(ctx->append_ctx,
+				MAIL_TRANSACTION_APPEND, &appends[a],
+				(append_count - a) * sizeof(appends[a]));
+	}
+	if (u < update_count) {
+		mail_transaction_log_append_add(ctx->append_ctx,
+				MAIL_TRANSACTION_UID_UPDATE, &updates[u],
+				(update_count - u) * sizeof(updates[u]));
+	}
+	return TRUE;
+}
+
 void mail_index_transaction_export(struct mail_index_transaction *t,
 				   struct mail_transaction_log_append_ctx *append_ctx)
 {
@@ -345,11 +400,9 @@ void mail_index_transaction_export(struc
 		log_append_buffer(&ctx, log_get_hdr_update_buffer(t, TRUE),
 				  MAIL_TRANSACTION_HEADER_UPDATE);
 	}
-	if (array_is_created(&t->appends)) {
+	if (mail_index_transaction_export_new_uids(&ctx, t))
 		change_mask |= MAIL_INDEX_SYNC_TYPE_APPEND;
-		log_append_buffer(&ctx, t->appends.arr.buffer, 
-				  MAIL_TRANSACTION_APPEND);
-	}
+
 	if (array_is_created(&t->updates)) {
 		change_mask |= MAIL_INDEX_SYNC_TYPE_FLAGS;
 		log_append_buffer(&ctx, t->updates.arr.buffer, 
@@ -387,12 +440,6 @@ void mail_index_transaction_export(struc
 		log_append_buffer(&ctx, t->expunges.arr.buffer,
 				  MAIL_TRANSACTION_EXPUNGE_GUID);
 	}
-	/* keep uid updates last. if there are other updates to the message,
-	   they're referring to the old uid. */
-	if (array_is_created(&t->uid_updates)) {
-		log_append_buffer(&ctx, t->uid_updates.arr.buffer,
-				  MAIL_TRANSACTION_UID_UPDATE);
-	}
 
 	if (t->post_hdr_changed) {
 		log_append_buffer(&ctx, log_get_hdr_update_buffer(t, FALSE),
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c	Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-transaction-update.c	Wed Aug 05 20:01:02 2009 -0400
@@ -252,6 +252,8 @@ void mail_index_update_uid(struct mail_i
 	u = array_append_space(&t->uid_updates);
 	u->old_uid = seq;
 	u->new_uid = new_uid;
+
+	t->log_updates = TRUE;
 }
 
 void mail_index_update_modseq(struct mail_index_transaction *t, uint32_t seq,
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c	Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-transaction.c	Wed Aug 05 20:01:02 2009 -0400
@@ -67,9 +67,11 @@ uint32_t mail_index_transaction_get_next
 	next_uid = t->reset || head_hdr->uid_validity != hdr->uid_validity ?
 		1 : hdr->next_uid;
 	if (array_is_created(&t->appends) && t->highest_append_uid != 0) {
-		/* get next_uid from appends if they have UIDs */
-		i_assert(next_uid <= t->highest_append_uid);
-		next_uid = t->highest_append_uid + 1;
+		/* get next_uid from appends if they have UIDs. it's possible
+		   that some appends have too low UIDs, they'll be caught
+		   later. */
+		if (next_uid <= t->highest_append_uid)
+			next_uid = t->highest_append_uid + 1;
 	}
 
 	/* see if it's been updated in pre/post header changes */
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c	Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-transaction-log-file.c	Wed Aug 05 20:01:02 2009 -0400
@@ -808,6 +808,7 @@ void mail_transaction_update_modseq(cons
 	case MAIL_TRANSACTION_FLAG_UPDATE:
 	case MAIL_TRANSACTION_KEYWORD_UPDATE:
 	case MAIL_TRANSACTION_KEYWORD_RESET:
+	case MAIL_TRANSACTION_UID_UPDATE:
 		/* these changes increase modseq */
 		*cur_modseq += 1;
 		break;


More information about the dovecot-cvs mailing list