dovecot-1.2: View syncing: Keep track of highest modseq in views...

dovecot at dovecot.org dovecot at dovecot.org
Sat Jun 21 15:24:08 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/91758686277a
changeset: 7932:91758686277a
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Jun 21 15:24:02 2008 +0300
description:
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

diffstat:

5 files changed, 17 insertions(+), 17 deletions(-)
src/lib-index/mail-index-modseq.c         |    6 ++++--
src/lib-index/mail-index-view-private.h   |    1 +
src/lib-index/mail-index-view-sync.c      |   20 +++++++-------------
src/lib-index/mail-transaction-log-file.c |    3 +--
src/lib-storage/index/index-status.c      |    4 ++++

diffs (122 lines):

diff -r 502cfdcc5650 -r 91758686277a src/lib-index/mail-index-modseq.c
--- 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 @@ uint64_t mail_index_map_modseq_get_highe
 	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;
 	}
 }
 
diff -r 502cfdcc5650 -r 91758686277a src/lib-index/mail-index-view-private.h
--- 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 @@ struct mail_index_view {
 
 	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
diff -r 502cfdcc5650 -r 91758686277a src/lib-index/mail-index-view-sync.c
--- 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 @@ struct mail_index_view_sync_ctx {
 	/* 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 @@ static int view_sync_apply_lost_changes(
 	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 @@ static int view_sync_apply_lost_changes(
 
 	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 @@ view_sync_get_log_lost_changes(struct ma
 	   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 @@ int mail_index_view_sync_commit(struct m
 	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;
diff -r 502cfdcc5650 -r 91758686277a src/lib-index/mail-transaction-log-file.c
--- 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 @@ mail_transaction_log_init_hdr(struct mai
 		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;
diff -r 502cfdcc5650 -r 91758686277a src/lib-storage/index/index-status.c
--- 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 @@ void index_storage_get_status(struct mai
 	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) {


More information about the dovecot-cvs mailing list