dovecot: Use the flags, keywords and cache from old index even w...

dovecot at dovecot.org dovecot at dovecot.org
Sat Nov 3 22:33:24 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/715ef6f98f44
changeset: 6680:715ef6f98f44
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Nov 03 22:33:16 2007 +0200
description:
Use the flags, keywords and cache from old index even when rebuilding dbox.

diffstat:

2 files changed, 127 insertions(+), 23 deletions(-)
src/lib-storage/index/dbox/dbox-sync-rebuild.c |  100 ++++++++++++++++++++++--
src/lib-storage/index/dbox/dbox-sync.c         |   50 ++++++++----

diffs (268 lines):

diff -r 90196328bcce -r 715ef6f98f44 src/lib-storage/index/dbox/dbox-sync-rebuild.c
--- a/src/lib-storage/index/dbox/dbox-sync-rebuild.c	Sat Nov 03 22:32:33 2007 +0200
+++ b/src/lib-storage/index/dbox/dbox-sync-rebuild.c	Sat Nov 03 22:33:16 2007 +0200
@@ -15,10 +15,16 @@ struct dbox_sync_rebuild_context {
 struct dbox_sync_rebuild_context {
 	struct dbox_mailbox *mbox;
 	struct dbox_index_append_context *append_ctx;
+
+	struct mail_index_view *view;
 	struct mail_index_transaction *trans;
+	uint32_t cache_ext_id;
+	uint32_t cache_reset_id;
 
 	struct maildir_uidlist *maildir_uidlist;
 	struct maildir_keywords *mk;
+
+	unsigned int cache_used:1;
 };
 
 static int dbox_sync_set_uidvalidity(struct dbox_sync_rebuild_context *ctx)
@@ -35,13 +41,80 @@ static int dbox_sync_set_uidvalidity(str
 	return 0;
 }
 
-static void dbox_sync_index_metadata(struct dbox_sync_rebuild_context *ctx,
-				     struct dbox_file *file, uint32_t seq)
+static void
+dbox_sync_index_copy_cache(struct dbox_sync_rebuild_context *ctx,
+			   uint32_t old_seq, uint32_t new_seq)
+{
+	struct mail_index_map *map;
+	const void *data;
+	uint32_t reset_id;
+	bool expunged;
+
+	if (ctx->cache_ext_id == (uint32_t)-1)
+		return;
+
+	mail_index_lookup_ext_full(ctx->view, old_seq, ctx->cache_ext_id,
+				   &map, &data, &expunged);
+	if (expunged)
+		return;
+
+	if (!mail_index_ext_get_reset_id(ctx->view, map, ctx->cache_ext_id,
+					 &reset_id))
+		return;
+
+	if (!ctx->cache_used) {
+		/* set reset id */
+		ctx->cache_used = TRUE;
+		ctx->cache_reset_id = reset_id;
+		mail_index_ext_reset(ctx->trans, ctx->cache_ext_id,
+				     ctx->cache_reset_id);
+	}
+	if (ctx->cache_reset_id == reset_id) {
+		mail_index_update_ext(ctx->trans, new_seq,
+				      ctx->cache_ext_id, data, NULL);
+	}
+}
+
+static void
+dbox_sync_index_copy_from_old(struct dbox_sync_rebuild_context *ctx,
+			      uint32_t old_seq, uint32_t new_seq)
+{
+	struct mail_index *index = mail_index_view_get_index(ctx->view);
+	const struct mail_index_record *rec;
+	ARRAY_TYPE(keyword_indexes) old_keywords;
+	struct mail_keywords *kw;
+
+	/* copy flags */
+	rec = mail_index_lookup(ctx->view, old_seq);
+	mail_index_update_flags(ctx->trans, new_seq,
+				MODIFY_REPLACE, rec->flags);
+
+	/* copy keywords */
+	t_array_init(&old_keywords, 32);
+	mail_index_lookup_keywords(ctx->view, old_seq, &old_keywords);
+	kw = mail_index_keywords_create_from_indexes(index, &old_keywords);
+	mail_index_update_keywords(ctx->trans, new_seq, MODIFY_REPLACE, kw);
+	mail_index_keywords_free(&kw);
+
+	dbox_sync_index_copy_cache(ctx, old_seq, new_seq);
+}
+
+static void
+dbox_sync_index_metadata(struct dbox_sync_rebuild_context *ctx,
+			 struct dbox_file *file, uint32_t seq, uint32_t uid)
 {
 	const char *value;
 	struct mail_keywords *keywords;
 	enum mail_flags flags = 0;
+	uint32_t old_seq;
 	unsigned int i;
+
+	if (mail_index_lookup_seq(ctx->view, uid, &old_seq)) {
+		/* the message exists in the old index.
+		   copy the metadata from it. */
+		dbox_sync_index_copy_from_old(ctx, old_seq, seq);
+		return;
+	}
 
 	value = dbox_file_metadata_get(file, DBOX_METADATA_FLAGS);
 	if (value != NULL) {
@@ -115,7 +188,7 @@ static int dbox_sync_index_file_next(str
 	if (!expunged) {
 		mail_index_append(ctx->trans, uid, &seq);
 		file->maildir_append_seq = seq;
-		dbox_sync_index_metadata(ctx, file, seq);
+		dbox_sync_index_metadata(ctx, file, seq, uid);
 	}
 	return 1;
 }
@@ -257,10 +330,20 @@ static void dbox_sync_update_maildir_ids
 	}
 }
 
+static void
+dbox_index_update_cache_header(struct dbox_sync_rebuild_context *ctx)
+{
+	const void *data;
+	size_t size;
+
+	mail_index_get_header_ext(ctx->view, ctx->cache_ext_id, &data, &size);
+	mail_index_update_header_ext(ctx->trans, ctx->cache_ext_id,
+				     0, data, size);
+}
+
 int dbox_sync_index_rebuild(struct dbox_mailbox *mbox)
 {
 	struct dbox_sync_rebuild_context ctx;
-	struct mail_index_view *view;
 	uint32_t seq;
 	uoff_t offset;
 	int ret;
@@ -268,14 +351,17 @@ int dbox_sync_index_rebuild(struct dbox_
 	memset(&ctx, 0, sizeof(ctx));
 	ctx.mbox = mbox;
 	ctx.append_ctx = dbox_index_append_begin(mbox->dbox_index);
-	view = mail_index_view_open(mbox->ibox.index);
-	ctx.trans = mail_index_transaction_begin(view,
+	ctx.view = mail_index_view_open(mbox->ibox.index);
+	ctx.trans = mail_index_transaction_begin(ctx.view,
 					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
 	mail_index_reset(ctx.trans);
+	mail_index_ext_lookup(mbox->ibox.index, "cache", &ctx.cache_ext_id);
 
 	if ((ret = dbox_sync_index_rebuild_ctx(&ctx)) < 0)
 		mail_index_transaction_rollback(&ctx.trans);
 	else {
+		if (ctx.cache_used)
+			dbox_index_update_cache_header(&ctx);
 		ret = dbox_index_append_assign_file_ids(ctx.append_ctx);
 		if (ret == 0) {
 			dbox_sync_update_maildir_ids(&ctx);
@@ -283,7 +369,7 @@ int dbox_sync_index_rebuild(struct dbox_
 							    &seq, &offset);
 		}
 	}
-	mail_index_view_close(&view);
+	mail_index_view_close(&ctx.view);
 
 	if (ret == 0)
 		ret = dbox_index_append_commit(&ctx.append_ctx);
diff -r 90196328bcce -r 715ef6f98f44 src/lib-storage/index/dbox/dbox-sync.c
--- a/src/lib-storage/index/dbox/dbox-sync.c	Sat Nov 03 22:32:33 2007 +0200
+++ b/src/lib-storage/index/dbox/dbox-sync.c	Sat Nov 03 22:33:16 2007 +0200
@@ -147,9 +147,17 @@ static void dbox_sync_update_header(stru
 static void dbox_sync_update_header(struct dbox_sync_context *ctx)
 {
 	struct dbox_index_header hdr;
-
-	if (!ctx->flush_dirty_flags)
-		return;
+	const void *data;
+	size_t data_size;
+
+	if (!ctx->flush_dirty_flags) {
+		/* write the header if it doesn't exist yet */
+		mail_index_get_header_ext(ctx->mbox->ibox.view,
+					  ctx->mbox->dbox_hdr_ext_id,
+					  &data, &data_size);
+		if (data_size != 0)
+			return;
+	}
 
 	hdr.last_dirty_flush_stamp = ioloop_time;
 	mail_index_update_header_ext(ctx->trans, ctx->mbox->dbox_hdr_ext_id, 0,
@@ -224,8 +232,8 @@ static int dbox_sync_index(struct dbox_s
 	return ret;
 }
 
-static bool dbox_sync_want_flush_dirty(struct dbox_mailbox *mbox,
-				       bool close_flush_dirty_flags)
+static int dbox_sync_want_flush_dirty(struct dbox_mailbox *mbox,
+				      bool close_flush_dirty_flags)
 {
 	const struct dbox_index_header *hdr;
 	const void *data;
@@ -233,29 +241,30 @@ static bool dbox_sync_want_flush_dirty(s
 
 	if (mbox->last_interactive_change <
 	    ioloop_time - DBOX_FLUSH_SECS_INTERACTIVE)
-		return TRUE;
+		return 1;
 
 	mail_index_get_header_ext(mbox->ibox.view, mbox->dbox_hdr_ext_id,
 				  &data, &data_size);
-	if (data_size == 0 || data_size != sizeof(*hdr)) {
+	if (data_size != sizeof(*hdr)) {
+		/* data_size=0 means it's never been synced as dbox */
 		if (data_size != 0) {
 			i_warning("dbox %s: Invalid dbox header size",
 				  mbox->path);
 		}
-		return TRUE;
+		return -1;
 	}
 	hdr = data;
 
 	if (!close_flush_dirty_flags) {
 		if (hdr->last_dirty_flush_stamp <
 		    ioloop_time - DBOX_FLUSH_SECS_IMMEDIATE)
-			return TRUE;
+			return 1;
 	} else {
 		if (hdr->last_dirty_flush_stamp <
 		    ioloop_time - DBOX_FLUSH_SECS_CLOSE)
-			return TRUE;
-	}
-	return FALSE;
+			return 1;
+	}
+	return 0;
 }
 
 int dbox_sync_begin(struct dbox_mailbox *mbox,
@@ -267,9 +276,13 @@ int dbox_sync_begin(struct dbox_mailbox 
 	enum mail_index_sync_flags sync_flags = 0;
 	unsigned int i;
 	int ret;
-
-	if (dbox_sync_want_flush_dirty(mbox, close_flush_dirty_flags))
+	bool rebuild = FALSE;
+
+	ret = dbox_sync_want_flush_dirty(mbox, close_flush_dirty_flags);
+	if (ret > 0)
 		sync_flags |= MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY;
+	else if (ret < 0)
+		rebuild = TRUE;
 	else {
 		if (close_flush_dirty_flags) {
 			/* no need to sync */
@@ -298,8 +311,13 @@ int dbox_sync_begin(struct dbox_mailbox 
 			return -1;
 		}
 
-		if ((ret = dbox_sync_index(ctx)) > 0)
-			break;
+		if (rebuild) {
+			ret = 0;
+			rebuild = FALSE;
+		} else {
+			if ((ret = dbox_sync_index(ctx)) > 0)
+				break;
+		}
 
 		/* failure. keep the index locked while we're doing a
 		   rebuild. */


More information about the dovecot-cvs mailing list