changeset 7932:91758686277a HEAD

View syncing: Keep track of highest modseq in views. If we lose transaction log, return all messages with higher modseq than the old highest-modseq as having changed. This works better than the previous code which compared the old modseq which may have already changed after the previous view sync. Return changes based on modseq being larger than
author Timo Sirainen <tss@iki.fi>
date Sat, 21 Jun 2008 15:24:02 +0300
parents 502cfdcc5650
children 96b8f50c9eea
files src/lib-index/mail-index-modseq.c src/lib-index/mail-index-view-private.h src/lib-index/mail-index-view-sync.c src/lib-index/mail-transaction-log-file.c src/lib-storage/index/index-status.c
diffstat 5 files changed, 17 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-modseq.c	Sat Jun 21 15:06:46 2008 +0300
+++ b/src/lib-index/mail-index-modseq.c	Sat Jun 21 15:24:02 2008 +0300
@@ -114,8 +114,10 @@
 	if (modseq_hdr != NULL && modseq_hdr->highest_modseq != 0)
 		return modseq_hdr->highest_modseq;
 	else {
-		/* fallback to returning the log head */
-		return mail_index_modseq_get_head(map->index);
+		/* fallback to returning the log head. if modseqs aren't
+		   enabled, we return 0. */
+		return map->index->log->head == NULL ? 0 :
+			map->index->log->head->sync_highest_modseq;
 	}
 }
 
--- a/src/lib-index/mail-index-view-private.h	Sat Jun 21 15:06:46 2008 +0300
+++ b/src/lib-index/mail-index-view-private.h	Sat Jun 21 15:24:02 2008 +0300
@@ -50,6 +50,7 @@
 
 	uint32_t indexid;
 	unsigned int inconsistency_id;
+	uint64_t highest_modseq;
 
 	struct mail_index_map *map;
 	/* All mappings where we have returned records. They need to be kept
--- a/src/lib-index/mail-index-view-sync.c	Sat Jun 21 15:06:46 2008 +0300
+++ b/src/lib-index/mail-index-view-sync.c	Sat Jun 21 15:24:02 2008 +0300
@@ -27,7 +27,7 @@
 	/* temporary variables while handling lost transaction logs: */
 	ARRAY_TYPE(keyword_indexes) lost_old_kw, lost_new_kw;
 	buffer_t *lost_kw_buf;
-	uint32_t lost_old_ext_idx, lost_new_ext_idx;
+	uint32_t lost_new_ext_idx;
 	/* result of lost transaction logs: */
 	ARRAY_TYPE(seq_range) lost_flags;
 	unsigned int lost_flag_idx;
@@ -332,7 +332,7 @@
 	struct mail_transaction_header thdr;
 	const struct mail_index_ext *ext;
 	const uint64_t *modseqp;
-	uint64_t old_modseq, new_modseq;
+	uint64_t new_modseq;
 	bool changed = FALSE;
 
 	old_rec = MAIL_INDEX_MAP_IDX(old_map, old_seq - 1);
@@ -383,24 +383,20 @@
 
 	if (changed) {
 		/* flags or keywords changed */
-	} else if (ctx->lost_old_ext_idx != (uint32_t)-1 &&
+	} else if (ctx->view->highest_modseq != 0 &&
 		   ctx->lost_new_ext_idx != (uint32_t)-1) {
 		/* if modseq has changed include this message in changed flags
 		   list, even if we didn't see any changes above. */
-		ext = array_idx(&old_map->extensions, ctx->lost_old_ext_idx);
-		modseqp = CONST_PTR_OFFSET(old_rec, ext->record_offset);
-		old_modseq = *modseqp;
-
 		ext = array_idx(&new_map->extensions, ctx->lost_new_ext_idx);
 		modseqp = CONST_PTR_OFFSET(new_rec, ext->record_offset);
 		new_modseq = *modseqp;
 
-		if (old_modseq != new_modseq)
+		if (new_modseq > ctx->view->highest_modseq)
 			changed = TRUE;
 	}
 
-	/* lost_flags isn't updated perfectly correctly, because by the time
-	   we're comparing old flags (or modseqs) it may have changed from what
+	/* without modseqs lost_flags isn't updated perfectly correctly, because
+	   by the time we're comparing old flags it may have changed from what
 	   we last sent to the client (because the map is shared). This could
 	   be avoided by always keeping a private copy of the map in the view,
 	   but that's a waste of memory for as rare of a problem as this. */
@@ -427,9 +423,6 @@
 	   want. get an atomic map to make sure these get removed. */
 	(void)mail_index_sync_get_atomic_map(&ctx->sync_map_ctx);
 
-	if (!mail_index_map_get_ext_idx(old_map, view->index->modseq_ext_id,
-					&ctx->lost_old_ext_idx))
-		ctx->lost_old_ext_idx = (uint32_t)-1;
 	if (!mail_index_map_get_ext_idx(new_map, view->index->modseq_ext_id,
 					&ctx->lost_new_ext_idx))
 		ctx->lost_new_ext_idx = (uint32_t)-1;
@@ -958,6 +951,7 @@
 	if (array_is_created(&ctx->lost_flags))
 		array_free(&ctx->lost_flags);
 
+	view->highest_modseq = mail_index_map_modseq_get_highest(view->map);
 	view->syncing = FALSE;
 	i_free(ctx);
 	return ret;
--- a/src/lib-index/mail-transaction-log-file.c	Sat Jun 21 15:06:46 2008 +0300
+++ b/src/lib-index/mail-transaction-log-file.c	Sat Jun 21 15:24:02 2008 +0300
@@ -196,8 +196,7 @@
 		hdr->prev_file_seq = index->map->hdr.log_file_seq;
 		hdr->prev_file_offset = index->map->hdr.log_file_head_offset;
 		hdr->file_seq = index->map->hdr.log_file_seq + 1;
-		hdr->initial_modseq = log->head == NULL ||
-			log->head->sync_highest_modseq == 0 ? 0 :
+		hdr->initial_modseq =
 			mail_index_map_modseq_get_highest(index->map);
 	} else {
 		hdr->file_seq = 1;
--- a/src/lib-storage/index/index-status.c	Sat Jun 21 15:06:46 2008 +0300
+++ b/src/lib-storage/index/index-status.c	Sat Jun 21 15:24:02 2008 +0300
@@ -30,6 +30,10 @@
 	if ((items & STATUS_HIGHESTMODSEQ) != 0) {
 		status_r->highest_modseq =
 			mail_index_modseq_get_highest(ibox->view);
+		if (status_r->highest_modseq == 0) {
+			/* modseqs not enabled yet, but we can't return 0 */
+			status_r->highest_modseq = 1;
+		}
 	}
 
 	if (items & STATUS_FIRST_UNSEEN_SEQ) {