dovecot-1.2: Modseqs are no longer calculated from transaction l...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jun 11 14:40:26 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/d10cb44ab446
changeset: 7812:d10cb44ab446
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jun 11 14:35:15 2008 +0300
description:
Modseqs are no longer calculated from transaction log sequence + offset.
Now they begin from 1 and each "visible" transaction increases it by one.

diffstat:

11 files changed, 506 insertions(+), 136 deletions(-)
src/lib-index/mail-index-modseq.c            |  127 ++++++----
src/lib-index/mail-index-modseq.h            |   10 
src/lib-index/mail-index-private.h           |    4 
src/lib-index/mail-index-sync-update.c       |    8 
src/lib-index/mail-index-view-sync.c         |   13 -
src/lib-index/mail-transaction-log-file.c    |  311 ++++++++++++++++++++++++--
src/lib-index/mail-transaction-log-private.h |   20 +
src/lib-index/mail-transaction-log-view.c    |   68 +++--
src/lib-index/mail-transaction-log.h         |   17 +
src/lib-storage/index/index-fetch.c          |   23 -
src/util/logview.c                           |   41 ++-

diffs (truncated from 1101 to 300 lines):

diff -r 85191a8cd7df -r d10cb44ab446 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Wed Jun 11 14:28:54 2008 +0300
+++ b/src/lib-index/mail-index-modseq.c	Wed Jun 11 14:35:15 2008 +0300
@@ -2,9 +2,10 @@
 
 #include "lib.h"
 #include "array.h"
+#include "mail-transaction-log-private.h"
 #include "mail-index-private.h"
+#include "mail-index-sync-private.h"
 #include "mail-index-modseq.h"
-#include "mail-index-sync-private.h"
 
 #define MAIL_INDEX_MODSEQ_EXT_NAME "modseq"
 
@@ -37,8 +38,6 @@ struct mail_index_modseq_sync {
 	struct mail_index_map_modseq *mmap;
 
 	uint64_t highest_modseq;
-	uint32_t log_seq;
-	uoff_t log_offset;
 };
 
 void mail_index_modseq_init(struct mail_index *index)
@@ -49,10 +48,10 @@ void mail_index_modseq_init(struct mail_
 					sizeof(uint64_t), sizeof(uint64_t));
 }
 
-static uint64_t mail_index_modseq_get_head(struct mail_index_map *map)
-{
-	return map->hdr.log_file_head_offset |
-		((uint64_t)(map->hdr.indexid + map->hdr.log_file_seq) << 32);
+static uint64_t mail_index_modseq_get_head(struct mail_index *index)
+{
+	return index->log->head == NULL ? 1 :
+		index->log->head->sync_highest_modseq;
 }
 
 void mail_index_modseq_enable(struct mail_index *index)
@@ -73,7 +72,7 @@ void mail_index_modseq_enable(struct mai
 		trans = mail_index_transaction_begin(view, 0);
 
 		memset(&hdr, 0, sizeof(hdr));
-		hdr.highest_modseq = mail_index_modseq_get_head(index->map);
+		hdr.highest_modseq = mail_index_modseq_get_head(index);
 		mail_index_update_header_ext(trans, index->modseq_ext_id,
 					     0, &hdr, sizeof(hdr));
 
@@ -93,21 +92,38 @@ void mail_index_modseq_enable(struct mai
 	index->modseqs_enabled = TRUE;
 }
 
+const struct mail_index_modseq_header *
+mail_index_map_get_modseq_header(struct mail_index_map *map)
+{
+	const struct mail_index_ext *ext;
+	uint32_t idx;
+
+	if (!mail_index_map_get_ext_idx(map, map->index->modseq_ext_id, &idx))
+		return NULL;
+
+	ext = array_idx(&map->extensions, idx);
+	if (ext->hdr_size != sizeof(struct mail_index_modseq_header))
+		return NULL;
+
+	return CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
+}
+
+uint64_t mail_index_map_modseq_get_highest(struct mail_index_map *map)
+{
+	const struct mail_index_modseq_header *modseq_hdr;
+
+	modseq_hdr = mail_index_map_get_modseq_header(map);
+	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);
+	}
+}
+
 uint64_t mail_index_modseq_get_highest(struct mail_index_view *view)
 {
-	const struct mail_index_modseq_header *modseq_hdr;
-	const void *data;
-	size_t size;
-
-	mail_index_get_header_ext(view, view->index->modseq_ext_id,
-				  &data, &size);
-	if (size == sizeof(*modseq_hdr)) {
-		modseq_hdr = data;
-		if (modseq_hdr->highest_modseq != 0)
-			return modseq_hdr->highest_modseq;
-	}
-	/* fallback to returning the log head */
-	return mail_index_modseq_get_head(view->map);
+	return mail_index_map_modseq_get_highest(view->map);
 }
 
 static struct mail_index_map_modseq *
@@ -142,13 +158,13 @@ uint64_t mail_index_modseq_lookup(struct
 	uint32_t ext_map_idx;
 
 	if (mmap == NULL)
-		return mail_index_modseq_get_head(view->map);
+		return mail_index_modseq_get_head(view->index);
 
 	rec = mail_index_lookup_full(view, seq, &map);
 	if (!mail_index_map_get_ext_idx(map, view->index->modseq_ext_id,
 					&ext_map_idx)) {
 		/* not enabled yet */
-		return mail_index_modseq_get_head(view->map);
+		return mail_index_modseq_get_head(view->index);
 	}
 
 	ext = array_idx(&map->extensions, ext_map_idx);
@@ -238,16 +254,6 @@ uint64_t mail_index_modseq_lookup_keywor
 	return highest_modseq;
 }
 
-static uint64_t get_cur_modseq(struct mail_index_modseq_sync *ctx)
-{
-	mail_transaction_log_view_get_prev_pos(ctx->log_view,
-					       &ctx->log_seq, &ctx->log_offset);
-	i_assert(ctx->log_offset <= (uint32_t)-1);
-
-	return ctx->log_offset |
-		((uint64_t)(ctx->view->map->hdr.indexid + ctx->log_seq) << 32);
-}
-
 static void
 mail_index_modseq_update(struct mail_index_modseq_sync *ctx,
 			 uint64_t modseq, bool nonzeros,
@@ -279,10 +285,13 @@ mail_index_modseq_update_highest(struct 
 mail_index_modseq_update_highest(struct mail_index_modseq_sync *ctx,
 				 uint32_t seq1, uint32_t seq2)
 {
+	uint64_t modseq;
+
 	if (ctx->mmap == NULL)
 		return FALSE;
 
-	mail_index_modseq_update(ctx, get_cur_modseq(ctx), TRUE, seq1, seq2);
+	modseq = mail_transaction_log_view_get_prev_modseq(ctx->log_view);
+	mail_index_modseq_update(ctx, modseq, TRUE, seq1, seq2);
 	return TRUE;
 }
 
@@ -401,7 +410,8 @@ static void mail_index_modseq_sync_init(
 						    &reset);
 		/* since we don't know if we skipped some changes, set all
 		   modseqs to beginning of the latest file. */
-		cur_modseq = get_cur_modseq(ctx);
+		cur_modseq = mail_transaction_log_view_get_prev_modseq(
+								ctx->log_view);
 		if (cur_modseq < hdr->highest_modseq) {
 			/* should happen only when setting initial modseqs.
 			   we may already have returned highest_modseq as
@@ -452,21 +462,25 @@ static void mail_index_modseq_update_hea
 	const struct mail_index_ext *ext;
 	const struct mail_index_modseq_header *old_modseq_hdr;
 	struct mail_index_modseq_header new_modseq_hdr;
-	uint32_t ext_map_idx;
+	uint32_t ext_map_idx, log_seq;
+	uoff_t log_offset;
 
 	if (!mail_index_map_get_ext_idx(map, ctx->view->index->modseq_ext_id,
 					&ext_map_idx))
 		return;
 
+	mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
+					       &log_seq, &log_offset);
+
 	ext = array_idx(&map->extensions, ext_map_idx);
 	old_modseq_hdr = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
 
-	if (old_modseq_hdr->log_seq < ctx->log_seq ||
-	    (old_modseq_hdr->log_seq == ctx->log_seq &&
-	     old_modseq_hdr->log_offset < ctx->log_offset)) {
+	if (old_modseq_hdr->log_seq < log_seq ||
+	    (old_modseq_hdr->log_seq == log_seq &&
+	     old_modseq_hdr->log_offset < log_offset)) {
 		new_modseq_hdr.highest_modseq = ctx->highest_modseq;
-		new_modseq_hdr.log_seq = ctx->log_seq;
-		new_modseq_hdr.log_offset = ctx->log_offset;
+		new_modseq_hdr.log_seq = log_seq;
+		new_modseq_hdr.log_offset = log_offset;
 
 		buffer_write(map->hdr_copy_buf, ext->hdr_offset,
 			     &new_modseq_hdr, sizeof(new_modseq_hdr));
@@ -517,7 +531,7 @@ void mail_index_modseq_expunge(struct ma
 			array_delete(&metadata->modseqs, seq1, seq2-seq1);
 	}
 
-	modseq = get_cur_modseq(ctx);
+	modseq = mail_transaction_log_view_get_prev_modseq(ctx->log_view);
 	if (ctx->highest_modseq < modseq)
 		ctx->highest_modseq = modseq;
 }
@@ -601,15 +615,24 @@ void mail_index_map_modseq_free(struct m
 	i_free(mmap);
 }
 
-bool mail_index_modseq_get_log_offset(struct mail_index_view *view,
-				      uint64_t modseq, uint32_t *log_seq_r,
-				      uoff_t *log_offset_r)
-{
-	if (view->map->hdr.indexid >= (modseq >> 32)) {
-		/* invalid modseq or created for an earlier index */
+bool mail_index_modseq_get_next_log_offset(struct mail_index_view *view,
+					   uint64_t modseq, uint32_t *log_seq_r,
+					   uoff_t *log_offset_r)
+{
+	struct mail_transaction_log_file *file, *prev_file = NULL;
+
+	for (file = view->index->log->files; file != NULL; file = file->next) {
+		if (modseq < file->hdr.initial_modseq)
+			break;
+		prev_file = file;
+	}
+
+	if (prev_file == NULL) {
+		/* the log file has been deleted already */
 		return FALSE;
 	}
-	*log_seq_r = (modseq >> 32) - view->map->hdr.indexid;
-	*log_offset_r = modseq & 0xffffffff;
-	return TRUE;
-}
+
+	*log_seq_r = prev_file->hdr.file_seq;
+	return mail_transaction_log_file_get_modseq_next_offset(
+					prev_file, modseq, log_offset_r) == 0;
+}
diff -r 85191a8cd7df -r d10cb44ab446 src/lib-index/mail-index-modseq.h
--- a/src/lib-index/mail-index-modseq.h	Wed Jun 11 14:28:54 2008 +0300
+++ b/src/lib-index/mail-index-modseq.h	Wed Jun 11 14:35:15 2008 +0300
@@ -4,6 +4,7 @@ enum mail_flags;
 enum mail_flags;
 struct mail_keywords;
 struct mail_index;
+struct mail_index_map;
 struct mail_index_view;
 struct mail_index_modseq;
 struct mail_index_map_modseq;
@@ -19,6 +20,9 @@ struct mail_index_modseq_header {
 
 void mail_index_modseq_init(struct mail_index *index);
 
+const struct mail_index_modseq_header *
+mail_index_map_get_modseq_header(struct mail_index_map *map);
+uint64_t mail_index_map_modseq_get_highest(struct mail_index_map *map);
 void mail_index_modseq_enable(struct mail_index *index);
 uint64_t mail_index_modseq_get_highest(struct mail_index_view *view);
 
@@ -49,8 +53,8 @@ void mail_index_modseq_reset_keywords(st
 
 void mail_index_map_modseq_free(struct mail_index_map_modseq *mmap);
 
-bool mail_index_modseq_get_log_offset(struct mail_index_view *view,
-				      uint64_t modseq, uint32_t *log_seq_r,
-				      uoff_t *log_offset_r);
+bool mail_index_modseq_get_next_log_offset(struct mail_index_view *view,
+					   uint64_t modseq, uint32_t *log_seq_r,
+					   uoff_t *log_offset_r);
 
 #endif
diff -r 85191a8cd7df -r d10cb44ab446 src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h	Wed Jun 11 14:28:54 2008 +0300
+++ b/src/lib-index/mail-index-private.h	Wed Jun 11 14:35:15 2008 +0300
@@ -31,6 +31,10 @@ struct mail_index_sync_map_ctx;
 #define MAIL_INDEX_MAP_IDX(map, idx) \
 	((struct mail_index_record *) \
 	 PTR_OFFSET((map)->rec_map->records, (idx) * (map)->hdr.record_size))
+
+#define MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u) \
+	((((u)->add_flags | (u)->remove_flags) & \
+	  MAIL_INDEX_FLAGS_MASK) == 0)
 
 typedef int mail_index_expunge_handler_t(struct mail_index_sync_map_ctx *ctx,
 					 uint32_t seq, const void *data,
diff -r 85191a8cd7df -r d10cb44ab446 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Wed Jun 11 14:28:54 2008 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Wed Jun 11 14:35:15 2008 +0300
@@ -355,9 +355,11 @@ static int sync_flag_update(const struct
 		return 1;
 
 	mail_index_sync_write_seq_update(ctx, seq1, seq2);
-	mail_index_modseq_update_flags(ctx->modseq_ctx,
-				       u->add_flags | u->remove_flags,
-				       seq1, seq2);
+	if (!MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u)) {
+		mail_index_modseq_update_flags(ctx->modseq_ctx,
+					       u->add_flags | u->remove_flags,
+					       seq1, seq2);
+	}
 
 	if ((u->add_flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0)
 		view->map->hdr.flags |= MAIL_INDEX_HDR_FLAG_HAVE_DIRTY;
diff -r 85191a8cd7df -r d10cb44ab446 src/lib-index/mail-index-view-sync.c


More information about the dovecot-cvs mailing list