dovecot-2.0: Added ability to specify message's minimum modseq v...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jul 29 01:59:07 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/b09d9350a2d9
changeset: 9691:b09d9350a2d9
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jul 28 18:58:31 2009 -0400
description:
Added ability to specify message's minimum modseq value.

diffstat:

36 files changed, 337 insertions(+), 59 deletions(-)
src/lib-index/mail-index-modseq.c                  |   65 +++++++++++++++-----
src/lib-index/mail-index-modseq.h                  |    4 +
src/lib-index/mail-index-sync-update.c             |   36 +++++++++++
src/lib-index/mail-index-transaction-export.c      |    5 +
src/lib-index/mail-index-transaction-finish.c      |    1 
src/lib-index/mail-index-transaction-private.h     |    1 
src/lib-index/mail-index-transaction-update.c      |   17 +++++
src/lib-index/mail-index.h                         |    3 
src/lib-index/mail-transaction-log-append.c        |    4 -
src/lib-index/mail-transaction-log-file.c          |   58 ++++++++++-------
src/lib-index/mail-transaction-log-private.h       |    6 -
src/lib-index/mail-transaction-log-view.c          |    4 -
src/lib-index/mail-transaction-log.h               |    9 ++
src/lib-index/test-mail-index-transaction-finish.c |   46 ++++++++++++++
src/lib-index/test-mail-index-transaction-update.c |   34 ++++++++++
src/lib-index/test-mail-transaction-log-append.c   |    9 +-
src/lib-index/test-mail-transaction-log-view.c     |   10 +--
src/lib-storage/index/cydir/cydir-mail.c           |    1 
src/lib-storage/index/cydir/cydir-save.c           |    4 +
src/lib-storage/index/dbox/dbox-mail.c             |    1 
src/lib-storage/index/dbox/dbox-save.c             |    4 +
src/lib-storage/index/index-mail.c                 |    7 ++
src/lib-storage/index/index-mail.h                 |    1 
src/lib-storage/index/maildir/maildir-mail.c       |    1 
src/lib-storage/index/maildir/maildir-save.c       |    4 +
src/lib-storage/index/mbox/mbox-mail.c             |    1 
src/lib-storage/index/mbox/mbox-save.c             |    4 +
src/lib-storage/index/raw/raw-mail.c               |    1 
src/lib-storage/mail-storage-private.h             |    2 
src/lib-storage/mail-storage.c                     |    6 +
src/lib-storage/mail-storage.h                     |    5 +
src/lib-storage/mail.c                             |    7 ++
src/lib-storage/test-mail.c                        |    6 +
src/plugins/virtual/virtual-mail.c                 |    1 
src/plugins/virtual/virtual-save.c                 |    1 
src/util/logview.c                                 |   27 ++++++++

diffs (truncated from 956 to 300 lines):

diff -r d303e3319720 -r b09d9350a2d9 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Tue Jul 28 13:57:24 2009 -0400
+++ b/src/lib-index/mail-index-modseq.c	Tue Jul 28 18:58:31 2009 -0400
@@ -181,6 +181,30 @@ uint64_t mail_index_modseq_lookup(struct
 		return mail_index_modseq_get_highest(view);
 	}
 	return *modseqp;
+}
+
+int mail_index_modseq_set(struct mail_index_view *view,
+			  uint32_t seq, uint64_t min_modseq)
+{
+	struct mail_index_map_modseq *mmap = mail_index_map_modseq(view);
+	const struct mail_index_ext *ext;
+	struct mail_index_record *rec;
+	uint64_t *modseqp;
+	uint32_t ext_map_idx;
+
+	if (mmap == NULL)
+		return -1;
+
+	rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
+	if (!mail_index_map_get_ext_idx(view->map, view->index->modseq_ext_id,
+					&ext_map_idx))
+		return -1;
+
+	ext = array_idx(&view->map->extensions, ext_map_idx);
+	modseqp = PTR_OFFSET(rec, ext->record_offset);
+	if (*modseqp < min_modseq)
+		*modseqp = min_modseq;
+	return 0;
 }
 
 static uint64_t
@@ -280,8 +304,8 @@ mail_index_modseq_update(struct mail_ind
 }
 
 static bool
-mail_index_modseq_update_highest(struct mail_index_modseq_sync *ctx,
-				 uint32_t seq1, uint32_t seq2)
+mail_index_modseq_update_to_highest(struct mail_index_modseq_sync *ctx,
+				    uint32_t seq1, uint32_t seq2)
 {
 	uint64_t modseq;
 
@@ -312,8 +336,8 @@ mail_index_modseq_update_old_rec(struct 
 		for (i = 0; i < count; i++) {
 			if (mail_index_lookup_seq(ctx->view,
 						  appends[i].uid, &seq1)) {
-				mail_index_modseq_update_highest(ctx, seq1,
-								 seq1);
+				mail_index_modseq_update_to_highest(ctx, seq1,
+								    seq1);
 			}
 		}
 		return;
@@ -353,7 +377,7 @@ mail_index_modseq_update_old_rec(struct 
 		rec = array_idx(&uids, i);
 		if (mail_index_lookup_seq_range(ctx->view, rec->seq1, rec->seq2,
 						&seq1, &seq2))
-			mail_index_modseq_update_highest(ctx, seq1, seq2);
+			mail_index_modseq_update_to_highest(ctx, seq1, seq2);
 	}
 }
 
@@ -452,20 +476,21 @@ mail_index_modseq_sync_begin(struct mail
 	return ctx;
 }
 
-static void mail_index_modseq_update_header(struct mail_index_modseq_sync *ctx)
-{
-	struct mail_index_map *map = ctx->view->map;
+static void mail_index_modseq_update_header(struct mail_index_view *view,
+					    uint64_t highest_modseq)
+{
+	struct mail_index_map *map = view->map;
 	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, log_seq;
 	uoff_t log_offset;
 
-	if (!mail_index_map_get_ext_idx(map, ctx->view->index->modseq_ext_id,
+	if (!mail_index_map_get_ext_idx(map, view->index->modseq_ext_id,
 					&ext_map_idx))
 		return;
 
-	mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
+	mail_transaction_log_view_get_prev_pos(view->log_view,
 					       &log_seq, &log_offset);
 
 	ext = array_idx(&map->extensions, ext_map_idx);
@@ -474,7 +499,8 @@ static void mail_index_modseq_update_hea
 	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;
+		memset(&new_modseq_hdr, 0, sizeof(new_modseq_hdr));
+		new_modseq_hdr.highest_modseq = highest_modseq;
 		new_modseq_hdr.log_seq = log_seq;
 		new_modseq_hdr.log_offset = log_offset;
 
@@ -492,7 +518,7 @@ void mail_index_modseq_sync_end(struct m
 	*_ctx = NULL;
 	if (ctx->mmap != NULL) {
 		i_assert(ctx->mmap == ctx->view->map->rec_map->modseq);
-		mail_index_modseq_update_header(ctx);
+		mail_index_modseq_update_header(ctx->view, ctx->highest_modseq);
 	}
 	i_free(ctx);
 }
@@ -514,7 +540,7 @@ void mail_index_modseq_hdr_update(struct
 
 void mail_index_modseq_append(struct mail_index_modseq_sync *ctx, uint32_t seq)
 {
-	mail_index_modseq_update_highest(ctx, seq, seq);
+	mail_index_modseq_update_to_highest(ctx, seq, seq);
 }
 
 void mail_index_modseq_expunge(struct mail_index_modseq_sync *ctx,
@@ -571,7 +597,7 @@ void mail_index_modseq_update_flags(stru
 {
 	unsigned int i;
 
-	if (!mail_index_modseq_update_highest(ctx, seq1, seq2))
+	if (!mail_index_modseq_update_to_highest(ctx, seq1, seq2))
 		return;
 
 	for (i = 0; i < METADATA_MODSEQ_IDX_KEYWORD_START; i++) {
@@ -584,7 +610,7 @@ void mail_index_modseq_update_keyword(st
 				      unsigned int keyword_idx,
 				      uint32_t seq1, uint32_t seq2)
 {
-	if (!mail_index_modseq_update_highest(ctx, seq1, seq2))
+	if (!mail_index_modseq_update_to_highest(ctx, seq1, seq2))
 		return;
 
 	modseqs_idx_update(ctx, METADATA_MODSEQ_IDX_KEYWORD_START + keyword_idx,
@@ -596,12 +622,19 @@ void mail_index_modseq_reset_keywords(st
 {
 	unsigned int i, count;
 
-	if (!mail_index_modseq_update_highest(ctx, seq1, seq2))
+	if (!mail_index_modseq_update_to_highest(ctx, seq1, seq2))
 		return;
 
 	count = array_count(&ctx->mmap->metadata_modseqs);
 	for (i = METADATA_MODSEQ_IDX_KEYWORD_START; i < count; i++)
 		modseqs_idx_update(ctx, i, seq1, seq2);
+}
+
+void mail_index_modseq_update_highest(struct mail_index_modseq_sync *ctx,
+				      uint64_t highest_modseq)
+{
+	if (ctx->highest_modseq < highest_modseq)
+		ctx->highest_modseq = highest_modseq;
 }
 
 struct mail_index_map_modseq *
diff -r d303e3319720 -r b09d9350a2d9 src/lib-index/mail-index-modseq.h
--- a/src/lib-index/mail-index-modseq.h	Tue Jul 28 13:57:24 2009 -0400
+++ b/src/lib-index/mail-index-modseq.h	Tue Jul 28 18:58:31 2009 -0400
@@ -35,6 +35,8 @@ uint64_t mail_index_modseq_lookup_keywor
 uint64_t mail_index_modseq_lookup_keywords(struct mail_index_view *view,
 					   const struct mail_keywords *keywords,
 					   uint32_t seq);
+int mail_index_modseq_set(struct mail_index_view *view,
+			  uint32_t seq, uint64_t min_modseq);
 
 struct mail_index_modseq_sync *
 mail_index_modseq_sync_begin(struct mail_index_sync_map_ctx *sync_map_ctx);
@@ -53,6 +55,8 @@ void mail_index_modseq_update_keyword(st
 				      uint32_t seq1, uint32_t seq2);
 void mail_index_modseq_reset_keywords(struct mail_index_modseq_sync *ctx,
 				      uint32_t seq1, uint32_t seq2);
+void mail_index_modseq_update_highest(struct mail_index_modseq_sync *ctx,
+				      uint64_t highest_modseq);
 
 struct mail_index_map_modseq *
 mail_index_map_modseq_clone(const struct mail_index_map_modseq *mmap);
diff -r d303e3319720 -r b09d9350a2d9 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Tue Jul 28 13:57:24 2009 -0400
+++ b/src/lib-index/mail-index-sync-update.c	Tue Jul 28 18:58:31 2009 -0400
@@ -311,6 +311,36 @@ static void sync_uid_update(struct mail_
 	memmove(rec, PTR_OFFSET(rec, map->hdr.record_size),
 		(map->rec_map->records_count + 1 - old_seq) *
 		map->hdr.record_size);
+}
+
+static int
+sync_modseq_update(struct mail_index_sync_map_ctx *ctx,
+		   const struct mail_transaction_modseq_update *u,
+		   unsigned int size)
+{
+	struct mail_index_view *view = ctx->view;
+	const struct mail_transaction_modseq_update *end;
+	uint32_t seq;
+	uint64_t min_modseq, highest_modseq = 0;
+
+	end = CONST_PTR_OFFSET(u, size);
+	for (; u < end; u++) {
+		if (!mail_index_lookup_seq(view, u->uid, &seq))
+			continue;
+
+		min_modseq = ((uint64_t)u->modseq_high32 >> 32) |
+			u->modseq_low32;
+		if (highest_modseq < min_modseq)
+			highest_modseq = min_modseq;
+		if (mail_index_modseq_set(view, seq, min_modseq) < 0) {
+			mail_index_sync_set_corrupted(ctx,
+				"modseqs updated before they were enabled");
+			return -1;
+		}
+	}
+
+	mail_index_modseq_update_highest(ctx->modseq_ctx, highest_modseq);
+	return 1;
 }
 
 void mail_index_sync_write_seq_update(struct mail_index_sync_map_ctx *ctx,
@@ -720,6 +750,12 @@ int mail_index_sync_record(struct mail_i
 			sync_uid_update(ctx, rec->old_uid, rec->new_uid);
 		break;
 	}
+	case MAIL_TRANSACTION_MODSEQ_UPDATE: {
+		const struct mail_transaction_modseq_update *rec = data;
+
+		ret = sync_modseq_update(ctx, rec, hdr->size);
+		break;
+	}
 	default:
 		mail_index_sync_set_corrupted(ctx,
 			"Unknown transaction record type 0x%x",
diff -r d303e3319720 -r b09d9350a2d9 src/lib-index/mail-index-transaction-export.c
--- a/src/lib-index/mail-index-transaction-export.c	Tue Jul 28 13:57:24 2009 -0400
+++ b/src/lib-index/mail-index-transaction-export.c	Tue Jul 28 18:58:31 2009 -0400
@@ -373,6 +373,11 @@ void mail_index_transaction_export(struc
 	}
 	if (array_is_created(&t->keyword_updates))
 		change_mask |= log_append_keyword_updates(&ctx);
+	/* keep modseq updates almost last */
+	if (array_is_created(&t->modseq_updates)) {
+		log_append_buffer(&ctx, t->modseq_updates.arr.buffer,
+				  MAIL_TRANSACTION_MODSEQ_UPDATE);
+	}
 
 	if (array_is_created(&t->expunges)) {
 		/* non-external expunges are only requests, ignore them when
diff -r d303e3319720 -r b09d9350a2d9 src/lib-index/mail-index-transaction-finish.c
--- a/src/lib-index/mail-index-transaction-finish.c	Tue Jul 28 13:57:24 2009 -0400
+++ b/src/lib-index/mail-index-transaction-finish.c	Tue Jul 28 18:58:31 2009 -0400
@@ -317,6 +317,7 @@ mail_index_transaction_convert_to_uids(s
         keyword_updates_convert_to_uids(t);
 	expunges_convert_to_uids(t);
 	mail_index_convert_to_uids(t, (void *)&t->uid_updates);
+	mail_index_convert_to_uids(t, (void *)&t->modseq_updates);
 	mail_index_convert_to_uid_ranges(t, (void *)&t->updates);
 	mail_index_convert_to_uid_ranges(t, &t->keyword_resets);
 }
diff -r d303e3319720 -r b09d9350a2d9 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h	Tue Jul 28 13:57:24 2009 -0400
+++ b/src/lib-index/mail-index-transaction-private.h	Tue Jul 28 18:58:31 2009 -0400
@@ -44,6 +44,7 @@ struct mail_index_transaction {
 	/* lowest/highest sequence that updates flags/keywords */
 	uint32_t min_flagupdate_seq, max_flagupdate_seq;
 
+	ARRAY_DEFINE(modseq_updates, struct mail_transaction_modseq_update);
 	ARRAY_DEFINE(uid_updates, struct mail_transaction_uid_update);
 	ARRAY_DEFINE(expunges, struct mail_transaction_expunge_guid);
 	ARRAY_DEFINE(updates, struct mail_transaction_flag_update);
diff -r d303e3319720 -r b09d9350a2d9 src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c	Tue Jul 28 13:57:24 2009 -0400
+++ b/src/lib-index/mail-index-transaction-update.c	Tue Jul 28 18:58:31 2009 -0400
@@ -71,6 +71,8 @@ void mail_index_transaction_reset_v(stru
 		array_free(&t->appends);
 	if (array_is_created(&t->uid_updates))
 		array_free(&t->uid_updates);
+	if (array_is_created(&t->modseq_updates))
+		array_free(&t->modseq_updates);
 	if (array_is_created(&t->expunges))
 		array_free(&t->expunges);
 	if (array_is_created(&t->updates))
@@ -108,6 +110,7 @@ void mail_index_transaction_set_log_upda
 	/* flag updates aren't included in log_updates */
 	t->log_updates = array_is_created(&t->appends) ||
 		array_is_created(&t->uid_updates) ||
+		array_is_created(&t->modseq_updates) ||
 		array_is_created(&t->expunges) ||
 		array_is_created(&t->keyword_resets) ||
 		array_is_created(&t->keyword_updates) ||
@@ -249,6 +252,20 @@ void mail_index_update_uid(struct mail_i
 	u = array_append_space(&t->uid_updates);
 	u->old_uid = seq;
 	u->new_uid = new_uid;
+}
+
+void mail_index_update_modseq(struct mail_index_transaction *t, uint32_t seq,
+			      uint64_t min_modseq)
+{
+	struct mail_transaction_modseq_update *u;


More information about the dovecot-cvs mailing list