changeset 7624:271131a1e060 HEAD

View sync returns now also hidden records, but they're marked as such. Mailbox syncing returns hidden records as modseq changes.
author Timo Sirainen <tss@iki.fi>
date Sat, 15 Mar 2008 08:45:04 +0200
parents 1285aedb353c
children 98a03cf8ad5d
files src/lib-index/mail-index-view-sync.c src/lib-index/mail-index.h src/lib-storage/index/index-sync.c
diffstat 3 files changed, 72 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-view-sync.c	Sat Mar 15 08:27:38 2008 +0200
+++ b/src/lib-index/mail-index-view-sync.c	Sat Mar 15 08:45:04 2008 +0200
@@ -27,6 +27,7 @@
 	unsigned int sync_map_update:1;
 	unsigned int skipped_expunges:1;
 	unsigned int last_read:1;
+	unsigned int hidden:1;
 };
 
 static int
@@ -447,7 +448,7 @@
 	int ret;
 	bool synced_to_map;
 
-	for (;;) {
+	do {
 		/* Get the next transaction from log. */
 		ret = mail_transaction_log_view_next(log_view, &ctx->hdr,
 						     &ctx->data);
@@ -461,43 +462,34 @@
 		}
 
 		hdr = ctx->hdr;
-		if (!mail_index_view_sync_want(ctx, hdr)) {
-			/* This is a visible record that we don't want to
-			   sync. */
-			continue;
-		}
+		/* skip records we've already synced */
+	} while (!mail_index_view_sync_want(ctx, hdr));
 
-		mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
+	mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
 
-		/* If we started from a map that we didn't create ourself,
-		   some of the transactions may already be synced. at the end
-		   of this view sync we'll update file_seq=0 so that this check
-		   always becomes FALSE for subsequent syncs. */
-		synced_to_map = view->map->hdr.log_file_seq != 0 &&
-			LOG_IS_BEFORE(seq, offset,
-				      view->map->hdr.log_file_seq,
-				      view->map->hdr.log_file_head_offset);
+	/* If we started from a map that we didn't create ourself,
+	   some of the transactions may already be synced. at the end
+	   of this view sync we'll update file_seq=0 so that this check
+	   always becomes FALSE for subsequent syncs. */
+	synced_to_map = view->map->hdr.log_file_seq != 0 &&
+		LOG_IS_BEFORE(seq, offset, view->map->hdr.log_file_seq,
+			      view->map->hdr.log_file_head_offset);
 
-		/* Apply transaction to view's mapping if needed (meaning we
-		   didn't just re-map the view to head mapping). */
-		if (ctx->sync_map_update && !synced_to_map) {
-			i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0 ||
-				 (hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0);
+	/* Apply transaction to view's mapping if needed (meaning we
+	   didn't just re-map the view to head mapping). */
+	if (ctx->sync_map_update && !synced_to_map) {
+		i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0 ||
+			 (hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0);
 
-			T_BEGIN {
-				ret = mail_index_sync_record(&ctx->sync_map_ctx,
-							     hdr, ctx->data);
-			} T_END;
-			if (ret < 0)
-				return -1;
-		}
+		T_BEGIN {
+			ret = mail_index_sync_record(&ctx->sync_map_ctx,
+						     hdr, ctx->data);
+		} T_END;
+		if (ret < 0)
+			return -1;
+	}
 
-		/* skip changes committed by hidden transactions (eg. in IMAP
-		   store +flags.silent command) */
-		if (view_sync_is_hidden(view, seq, offset))
-			continue;
-		break;
-	}
+	ctx->hidden = view_sync_is_hidden(view, seq, offset);
 	return 1;
 }
 
@@ -597,6 +589,8 @@
 		ctx->hdr = NULL;
 		return FALSE;
 	}
+
+	rec->hidden = ctx->hidden;
 	return TRUE;
 }
 
--- a/src/lib-index/mail-index.h	Sat Mar 15 08:27:38 2008 +0200
+++ b/src/lib-index/mail-index.h	Sat Mar 15 08:45:04 2008 +0200
@@ -103,8 +103,8 @@
 };
 
 enum mail_index_transaction_flags {
-	/* If transaction is marked as hidden, the changes won't be listed
-	   when the view is synchronized. */
+	/* If transaction is marked as hidden, the changes are marked with
+	   hidden=TRUE when the view is synchronized. */
 	MAIL_INDEX_TRANSACTION_FLAG_HIDE		= 0x01,
 	/* External transactions describe changes to mailbox that have already
 	   happened. */
@@ -162,6 +162,9 @@
 	/* keyword appends and removes are packed into one and same
 	   MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD */
 	enum mail_index_sync_type type;
+
+	/* TRUE if this was a hidden transaction. */
+	unsigned int hidden:1;
 };
 
 struct mail_index;
--- a/src/lib-storage/index/index-sync.c	Sat Mar 15 08:27:38 2008 +0200
+++ b/src/lib-storage/index/index-sync.c	Sat Mar 15 08:45:04 2008 +0200
@@ -14,8 +14,9 @@
 	uint32_t messages_count;
 
 	ARRAY_TYPE(seq_range) flag_updates;
+	ARRAY_TYPE(seq_range) modseq_updates;
 	const ARRAY_TYPE(seq_range) *expunges;
-	unsigned int flag_update_pos, expunge_pos;
+	unsigned int flag_update_idx, modseq_update_idx, expunge_pos;
 
 	bool failed;
 };
@@ -113,6 +114,8 @@
 	uint32_t seq1, seq2;
 
 	i_array_init(&ctx->flag_updates, 128);
+	if ((ctx->ibox->box.enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0)
+		i_array_init(&ctx->modseq_updates, 32);
 	while (mail_index_view_sync_next(ctx->sync_ctx, &sync)) {
 		switch (sync.type) {
 		case MAIL_INDEX_SYNC_TYPE_APPEND:
@@ -125,20 +128,35 @@
 		case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
 		case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
 		case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
-			if (mail_index_lookup_seq_range(ctx->ibox->view,
+			if (!mail_index_lookup_seq_range(ctx->ibox->view,
 							sync.uid1, sync.uid2,
-							&seq1, &seq2)) {
+							 &seq1, &seq2))
+				break;
+
+			if (!sync.hidden) {
 				seq_range_array_add_range(&ctx->flag_updates,
 							  seq1, seq2);
+			} else if (array_is_created(&ctx->modseq_updates)) {
+				seq_range_array_add_range(&ctx->modseq_updates,
+							  seq1, seq2);
 			}
 			break;
 		}
 	}
 
-	/* remove expunged messages from flag updates */
+	/* remove expunged messages from flag/modseq updates */
 	if (ctx->expunges != NULL) {
 		seq_range_array_remove_seq_range(&ctx->flag_updates,
 						 ctx->expunges);
+		if (array_is_created(&ctx->modseq_updates)) {
+			seq_range_array_remove_seq_range(&ctx->modseq_updates,
+							 ctx->expunges);
+		}
+	}
+	/* remove flag updates from modseq updates */
+	if (array_is_created(&ctx->modseq_updates)) {
+		seq_range_array_remove_seq_range(&ctx->modseq_updates,
+						 &ctx->flag_updates);
 	}
 }
 
@@ -215,20 +233,30 @@
 {
 	struct index_mailbox_sync_context *ctx =
 		(struct index_mailbox_sync_context *)_ctx;
-	const struct seq_range *flag_updates;
+	const struct seq_range *range;
 	unsigned int count;
 
 	if (ctx->failed)
 		return FALSE;
 
-	flag_updates = array_get(&ctx->flag_updates, &count);
-	if (ctx->flag_update_pos < count) {
+	range = array_get(&ctx->flag_updates, &count);
+	if (ctx->flag_update_idx < count) {
 		sync_rec_r->type = MAILBOX_SYNC_TYPE_FLAGS;
-		sync_rec_r->seq1 = flag_updates[ctx->flag_update_pos].seq1;
-		sync_rec_r->seq2 = flag_updates[ctx->flag_update_pos].seq2;
-		ctx->flag_update_pos++;
+		sync_rec_r->seq1 = range[ctx->flag_update_idx].seq1;
+		sync_rec_r->seq2 = range[ctx->flag_update_idx].seq2;
+		ctx->flag_update_idx++;
 		return 1;
 	}
+	if (array_is_created(&ctx->modseq_updates)) {
+		range = array_get(&ctx->modseq_updates, &count);
+		if (ctx->modseq_update_idx < count) {
+			sync_rec_r->type = MAILBOX_SYNC_TYPE_MODSEQ;
+			sync_rec_r->seq1 = range[ctx->modseq_update_idx].seq1;
+			sync_rec_r->seq2 = range[ctx->modseq_update_idx].seq2;
+			ctx->modseq_update_idx++;
+			return 1;
+		}
+	}
 
 	return index_mailbox_sync_next_expunge(ctx, sync_rec_r);
 }
@@ -336,6 +364,8 @@
 
 	if (array_is_created(&ctx->flag_updates))
 		array_free(&ctx->flag_updates);
+	if (array_is_created(&ctx->modseq_updates))
+		array_free(&ctx->modseq_updates);
 	i_free(ctx);
 	return ret;
 }