dovecot-1.2: Keep modseqs as 1 until the first modseq ext intro ...

dovecot at dovecot.org dovecot at dovecot.org
Sat Jun 21 15:06:52 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/502cfdcc5650
changeset: 7931:502cfdcc5650
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Jun 21 15:06:46 2008 +0300
description:
Keep modseqs as 1 until the first modseq ext intro record enables them.
Performance should be better again when modseqs are disabled.

diffstat:

7 files changed, 139 insertions(+), 80 deletions(-)
src/lib-index/mail-index-modseq.c            |    4 
src/lib-index/mail-index-modseq.h            |    2 
src/lib-index/mail-transaction-log-append.c  |   43 +++++--
src/lib-index/mail-transaction-log-file.c    |  142 +++++++++++++++++---------
src/lib-index/mail-transaction-log-private.h |    4 
src/lib-index/mail-transaction-log-view.c    |    8 -
src/util/logview.c                           |   16 +-

diffs (truncated from 464 to 300 lines):

diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-index-modseq.c	Sat Jun 21 15:06:46 2008 +0300
@@ -6,8 +6,6 @@
 #include "mail-index-private.h"
 #include "mail-index-sync-private.h"
 #include "mail-index-modseq.h"
-
-#define MAIL_INDEX_MODSEQ_EXT_NAME "modseq"
 
 ARRAY_DEFINE_TYPE(modseqs, uint64_t);
 
@@ -51,7 +49,7 @@ static uint64_t mail_index_modseq_get_he
 static uint64_t mail_index_modseq_get_head(struct mail_index *index)
 {
 	return index->log->head == NULL ? 1 :
-		index->log->head->sync_highest_modseq;
+		I_MAX(index->log->head->sync_highest_modseq, 1);
 }
 
 void mail_index_modseq_enable(struct mail_index *index)
diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-index-modseq.h
--- a/src/lib-index/mail-index-modseq.h	Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-index-modseq.h	Sat Jun 21 15:06:46 2008 +0300
@@ -1,5 +1,7 @@
 #ifndef MAIL_INDEX_MODSEQ_H
 #define MAIL_INDEX_MODSEQ_H
+
+#define MAIL_INDEX_MODSEQ_EXT_NAME "modseq"
 
 enum mail_flags;
 struct mail_keywords;
diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-transaction-log-append.c
--- a/src/lib-index/mail-transaction-log-append.c	Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-transaction-log-append.c	Sat Jun 21 15:06:46 2008 +0300
@@ -6,6 +6,7 @@
 #include "write-full.h"
 #include "mail-index-private.h"
 #include "mail-index-view-private.h"
+#include "mail-index-modseq.h"
 #include "mail-index-transaction-private.h"
 #include "mail-transaction-log-private.h"
 
@@ -14,7 +15,7 @@ struct log_append_context {
 	struct mail_index_transaction *trans;
 	buffer_t *output;
 
-	unsigned int modseq_change_count;
+	uint64_t modseq;
 	uint32_t first_append_size;
 	bool sync_includes_this;
 };
@@ -25,6 +26,7 @@ static void log_append_buffer(struct log
 {
 	struct mail_transaction_header hdr;
 	uint32_t hdr_size;
+	size_t hdr_pos;
 
 	i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);
 	i_assert((buf->used % 4) == 0);
@@ -39,26 +41,31 @@ static void log_append_buffer(struct log
 		hdr.type |= MAIL_TRANSACTION_EXPUNGE_PROT;
 	if ((ctx->trans->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
 		hdr.type |= MAIL_TRANSACTION_EXTERNAL;
-
-	if (mail_transaction_header_has_modseq(&hdr))
-		ctx->modseq_change_count++;
-
-	hdr_size = mail_index_uint32_to_offset(sizeof(hdr) + buf->used +
-					       (hdr_buf == NULL ? 0 :
-						hdr_buf->used));
+	hdr.size = sizeof(hdr) + buf->used +
+		(hdr_buf == NULL ? 0 : hdr_buf->used);
+
+	hdr_pos = ctx->output->used;
+	buffer_append(ctx->output, &hdr, sizeof(hdr));
+	if (hdr_buf != NULL)
+		buffer_append(ctx->output, hdr_buf->data, hdr_buf->used);
+	buffer_append(ctx->output, buf->data, buf->used);
+
+	if (mail_transaction_header_has_modseq(buf->data,
+			CONST_PTR_OFFSET(buf->data, sizeof(hdr)), ctx->modseq))
+		ctx->modseq++;
+
+	/* update the size */
+	hdr_size = mail_index_uint32_to_offset(hdr.size);
 	if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(ctx->file) &&
 	    ctx->first_append_size == 0) {
 		/* size will be written later once everything
 		   is in disk */
 		ctx->first_append_size = hdr_size;
+		hdr.size = 0;
 	} else {
 		hdr.size = hdr_size;
 	}
-
-	buffer_append(ctx->output, &hdr, sizeof(hdr));
-	if (hdr_buf != NULL)
-		buffer_append(ctx->output, hdr_buf->data, hdr_buf->used);
-	buffer_append(ctx->output, buf->data, buf->used);
+	buffer_write(ctx->output, hdr_pos, &hdr, sizeof(hdr));
 }
 
 static int log_buffer_move_to_memory(struct log_append_context *ctx)
@@ -280,9 +287,14 @@ static void log_append_ext_intro(struct 
 		/* new extension, reset_id defaults to 0 */
 	}
 	buffer_append(buf, rext->name, intro->name_size);
-
 	if ((buf->used % 4) != 0)
 		buffer_append_zero(buf, 4 - (buf->used % 4));
+
+	if (ctx->file->sync_highest_modseq == 0 &&
+	    strcmp(rext->name, MAIL_INDEX_MODSEQ_EXT_NAME) == 0) {
+		/* modseq tracking started */
+		ctx->file->sync_highest_modseq = 1;
+	}
 
 	log_append_buffer(ctx, buf, NULL, MAIL_TRANSACTION_EXT_INTRO);
 }
@@ -601,6 +613,7 @@ mail_transaction_log_append_locked(struc
 	ctx.file = file;
 	ctx.trans = t;
 	ctx.output = buffer_create_dynamic(default_pool, 1024);
+	ctx.modseq = file->sync_highest_modseq;
 
 	/* send all extension introductions and resizes before appends
 	   to avoid resize overhead as much as possible */
@@ -674,7 +687,7 @@ mail_transaction_log_append_locked(struc
 		buffer_free(&ctx.output);
 		return -1;
 	}
-	file->sync_highest_modseq += ctx.modseq_change_count;
+	file->sync_highest_modseq = ctx.modseq;
 	buffer_free(&ctx.output);
 
 	if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_HIDE) != 0) {
diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c	Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-transaction-log-file.c	Sat Jun 21 15:06:46 2008 +0300
@@ -102,45 +102,62 @@ void mail_transaction_log_file_free(stru
 }
 
 static void
-mail_transaction_log_file_add_to_list(struct mail_transaction_log_file *file)
+mail_transaction_log_file_skip_to_head(struct mail_transaction_log_file *file)
 {
 	struct mail_transaction_log *log = file->log;
-	struct mail_transaction_log_file **p;
 	struct mail_index_map *map = log->index->map;
 	const struct mail_index_modseq_header *modseq_hdr;
-
-	if (map != NULL && file->hdr.file_seq == map->hdr.log_file_seq &&
-	    map->hdr.log_file_head_offset != 0) {
-		/* we can get a valid log offset from index file. initialize
-		   sync_offset from it so we don't have to read the whole log
-		   file from beginning. */
-		uoff_t head_offset = map->hdr.log_file_head_offset;
-
-		modseq_hdr = mail_index_map_get_modseq_header(map);
-		if (head_offset < file->hdr.hdr_size) {
-			mail_index_set_error(log->index,
-				"%s: log_file_head_offset too small",
-				log->index->filepath);
-			file->sync_offset = file->hdr.hdr_size;
-			file->sync_highest_modseq = file->hdr.initial_modseq;
-		} else if (modseq_hdr == NULL ||
-			   modseq_hdr->log_seq != file->hdr.file_seq ||
-			   modseq_hdr->log_offset != head_offset) {
-			/* highest_modseq not synced, start from beginning */
-			file->sync_offset = file->hdr.hdr_size;
-			file->sync_highest_modseq = file->hdr.initial_modseq;
-		} else {
-			file->sync_offset = head_offset;
-			file->sync_highest_modseq = modseq_hdr->highest_modseq;
-		}
-		file->saved_tail_offset = map->hdr.log_file_tail_offset;
-	} else {
+	uoff_t head_offset;
+
+	if (map == NULL || file->hdr.file_seq != map->hdr.log_file_seq ||
+	    map->hdr.log_file_head_offset == 0)
+		return;
+
+	/* we can get a valid log offset from index file. initialize
+	   sync_offset from it so we don't have to read the whole log
+	   file from beginning. */
+	head_offset = map->hdr.log_file_head_offset;
+
+	modseq_hdr = mail_index_map_get_modseq_header(map);
+	if (head_offset < file->hdr.hdr_size) {
+		mail_index_set_error(log->index,
+				     "%s: log_file_head_offset too small",
+				     log->index->filepath);
 		file->sync_offset = file->hdr.hdr_size;
 		file->sync_highest_modseq = file->hdr.initial_modseq;
-	}
+	} else if (modseq_hdr == NULL && file->hdr.initial_modseq == 0) {
+		/* modseqs not used yet */
+		file->sync_offset = head_offset;
+		file->sync_highest_modseq = 0;
+	} else if (modseq_hdr->log_seq != file->hdr.file_seq) {
+		/* highest_modseq not synced, start from beginning */
+		file->sync_offset = file->hdr.hdr_size;
+		file->sync_highest_modseq = file->hdr.initial_modseq;
+	} else if (modseq_hdr->log_offset > head_offset) {
+		mail_index_set_error(log->index,
+				     "%s: modseq_hdr.log_offset too large",
+				     log->index->filepath);
+		file->sync_offset = file->hdr.hdr_size;
+		file->sync_highest_modseq = file->hdr.initial_modseq;
+	} else {
+		/* start from where we last stopped tracking modseqs */
+		file->sync_offset = modseq_hdr->log_offset;
+		file->sync_highest_modseq = modseq_hdr->highest_modseq;
+	}
+	file->saved_tail_offset = log->index->map->hdr.log_file_tail_offset;
+}
+
+static void
+mail_transaction_log_file_add_to_list(struct mail_transaction_log_file *file)
+{
+	struct mail_transaction_log_file **p;
+
+	file->sync_offset = file->hdr.hdr_size;
+	file->sync_highest_modseq = file->hdr.initial_modseq;
+	mail_transaction_log_file_skip_to_head(file);
 
 	/* insert it to correct position */
-	for (p = &log->files; *p != NULL; p = &(*p)->next) {
+	for (p = &file->log->files; *p != NULL; p = &(*p)->next) {
 		if ((*p)->hdr.file_seq > file->hdr.file_seq)
 			break;
 		i_assert((*p)->hdr.file_seq < file->hdr.file_seq);
@@ -179,7 +196,8 @@ 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 =
+		hdr->initial_modseq = log->head == NULL ||
+			log->head->sync_highest_modseq == 0 ? 0 :
 			mail_index_map_modseq_get_highest(index->map);
 	} else {
 		hdr->file_seq = 1;
@@ -368,8 +386,6 @@ mail_transaction_log_file_read_hdr(struc
 		   shouldn't have filled */
 		memset(PTR_OFFSET(&file->hdr, file->hdr.hdr_size), 0,
 		       sizeof(file->hdr) - file->hdr.hdr_size);
-		if (file->hdr.minor_version == 0)
-			file->hdr.initial_modseq = 1;
 	}
 
 	if (file->hdr.indexid == 0) {
@@ -524,7 +540,7 @@ mail_transaction_log_file_create2(struct
 	if (reset) {
 		file->hdr.prev_file_seq = 0;
 		file->hdr.prev_file_offset = 0;
-		file->hdr.initial_modseq = 1;
+		file->hdr.initial_modseq = 0;
 	}
 
 	if (write_full(new_fd, &file->hdr, sizeof(file->hdr)) < 0) {
@@ -724,8 +740,31 @@ log_file_track_mailbox_sync_offset_hdr(s
 }
 
 bool
-mail_transaction_header_has_modseq(const struct mail_transaction_header *hdr)
-{
+mail_transaction_header_has_modseq(const struct mail_transaction_header *hdr,
+				   const void *data,
+				   uint64_t cur_modseq)
+{
+	if (cur_modseq != 0) {
+		/* tracking modseqs */
+	} else if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) ==
+		   MAIL_TRANSACTION_EXT_INTRO) {
+		/* modseqs not tracked yet. see if this is a modseq
+		   extension introduction. */
+		const struct mail_transaction_ext_intro *intro = data;
+		const unsigned int modseq_ext_len =
+			strlen(MAIL_INDEX_MODSEQ_EXT_NAME);
+
+		if (intro->name_size == modseq_ext_len &&
+		    memcmp(intro + 1, MAIL_INDEX_MODSEQ_EXT_NAME,
+			   modseq_ext_len) == 0) {
+			/* modseq tracking started */
+			return TRUE;
+		}
+	} else {
+		/* not tracking modseqs */
+		return FALSE;
+	}
+
 	switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
 	case MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_EXPUNGE_PROT:
 		if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
@@ -882,7 +921,8 @@ int mail_transaction_log_file_get_highes
 	while (cur_offset < offset) {
 		if (log_get_synced_record(file, &cur_offset, &hdr) < 0)
 			return- 1;


More information about the dovecot-cvs mailing list