dovecot: Added support for resetting index.

dovecot at dovecot.org dovecot at dovecot.org
Sun Jul 1 01:05:51 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/a9df50952600
changeset: 5849:a9df50952600
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 01 01:05:26 2007 +0300
description:
Added support for resetting index.

diffstat:

13 files changed, 201 insertions(+), 81 deletions(-)
src/lib-index/mail-index-sync-update.c         |   13 ++
src/lib-index/mail-index-sync.c                |    3 
src/lib-index/mail-index-transaction-private.h |    6 +
src/lib-index/mail-index-transaction.c         |    9 +
src/lib-index/mail-index-view-sync.c           |   68 +++++++++-----
src/lib-index/mail-index-write.c               |    4 
src/lib-index/mail-index.h                     |    3 
src/lib-index/mail-transaction-log-append.c    |   11 ++
src/lib-index/mail-transaction-log-file.c      |   17 ++-
src/lib-index/mail-transaction-log-private.h   |    5 -
src/lib-index/mail-transaction-log-view.c      |  115 ++++++++++++++++--------
src/lib-index/mail-transaction-log.c           |   14 +-
src/lib-index/mail-transaction-log.h           |   14 +-

diffs (truncated from 621 to 300 lines):

diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Sun Jul 01 01:05:26 2007 +0300
@@ -697,7 +697,7 @@ int mail_index_sync_map(struct mail_inde
 	uint32_t prev_seq;
 	uoff_t start_offset, prev_offset;
 	int ret;
-	bool had_dirty;
+	bool had_dirty, reset;
 
 	i_assert(index->map == map || type == MAIL_INDEX_SYNC_HANDLER_VIEW);
 
@@ -725,7 +725,7 @@ int mail_index_sync_map(struct mail_inde
 	view = mail_index_view_open_with_map(index, map);
 	ret = mail_transaction_log_view_set(view->log_view,
 					    map->hdr.log_file_seq, start_offset,
-					    (uint32_t)-1, (uoff_t)-1);
+					    (uint32_t)-1, (uoff_t)-1, &reset);
 	if (ret <= 0) {
 		if (force && ret == 0) {
 			/* the seq/offset is probably broken */
@@ -758,6 +758,15 @@ int mail_index_sync_map(struct mail_inde
 	}
 
 	mail_index_sync_map_init(&sync_map_ctx, view, type);
+	if (reset) {
+		/* Reset the entire index. Leave only indexid and
+		   log_file_seq. */
+		mail_transaction_log_view_get_prev_pos(view->log_view,
+						       &prev_seq, &prev_offset);
+		map = mail_index_map_alloc(index);
+		map->hdr.log_file_seq = prev_seq;
+		mail_index_sync_replace_map(&sync_map_ctx, map);
+	}
 	map = NULL;
 
 	/* FIXME: when transaction sync lock is removed, we'll need to handle
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-sync.c	Sun Jul 01 01:05:26 2007 +0300
@@ -308,13 +308,14 @@ mail_index_sync_set_log_view(struct mail
 {
 	uint32_t log_seq;
 	uoff_t log_offset;
+	bool reset;
 	int ret;
 
 	mail_transaction_log_get_head(view->index->log, &log_seq, &log_offset);
 
 	ret = mail_transaction_log_view_set(view->log_view,
                                             start_file_seq, start_file_offset,
-					    log_seq, log_offset);
+					    log_seq, log_offset, &reset);
 	if (ret <= 0) {
 		/* either corrupted or the file was deleted for
 		   some reason. either way, we can't go forward */
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-transaction-private.h	Sun Jul 01 01:05:26 2007 +0300
@@ -25,6 +25,8 @@ struct mail_index_transaction {
 	struct mail_index_transaction_vfuncs v;
 	struct mail_index_view *view;
 
+	/* NOTE: If you add anything new, remember to update
+	   mail_index_transaction_reset() to reset it. */
         ARRAY_DEFINE(appends, struct mail_index_record);
 	uint32_t first_new_seq, last_new_seq;
 
@@ -55,10 +57,12 @@ struct mail_index_transaction {
 	unsigned int sync_transaction:1;
 	unsigned int hide_transaction:1;
 	unsigned int no_appends:1;
+	unsigned int external:1;
+
 	unsigned int appends_nonsorted:1;
-	unsigned int external:1;
 	unsigned int pre_hdr_changed:1;
 	unsigned int post_hdr_changed:1;
+	unsigned int reset:1;
 	unsigned int log_updates:1;
 };
 
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-transaction.c	Sun Jul 01 01:05:26 2007 +0300
@@ -77,6 +77,7 @@ void mail_index_transaction_reset(struct
 	t->appends_nonsorted = FALSE;
 	t->pre_hdr_changed = FALSE;
 	t->post_hdr_changed = FALSE;
+	t->reset = FALSE;
 	t->log_updates = FALSE;
 }
 
@@ -1039,6 +1040,14 @@ void mail_index_update_keywords(struct m
 	t->log_updates = TRUE;
 }
 
+void mail_index_reset(struct mail_index_transaction *t)
+{
+	mail_index_transaction_reset(t);
+
+	t->reset = TRUE;
+	t->log_updates = TRUE;
+}
+
 struct mail_index_transaction_vfuncs trans_vfuncs = {
 	_mail_index_transaction_commit,
 	_mail_index_transaction_rollback
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-view-sync.c
--- a/src/lib-index/mail-index-view-sync.c	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-view-sync.c	Sun Jul 01 01:05:26 2007 +0300
@@ -87,27 +87,53 @@ mail_transaction_log_sort_expunges(ARRAY
 	return 0;
 }
 
-static int view_sync_set_log_view_range(struct mail_index_view *view)
+static int
+view_sync_set_log_view_range(struct mail_index_view *view, bool sync_expunges)
 {
 	const struct mail_index_header *hdr = &view->index->map->hdr;
+	uint32_t start_seq, end_seq;
+	uoff_t start_offset, end_offset;
+	bool reset;
 	int ret;
 
-	/* the view begins from the first non-synced transaction */
-	ret = mail_transaction_log_view_set(view->log_view,
-					    view->log_file_expunge_seq,
-					    view->log_file_expunge_offset,
-					    hdr->log_file_seq,
-					    hdr->log_file_head_offset);
-	if (ret <= 0) {
-		if (ret == 0) {
-			/* FIXME: use the new index to get needed changes */
+	start_seq = view->log_file_expunge_seq;
+	start_offset = view->log_file_expunge_offset;
+	end_seq = hdr->log_file_seq;
+	end_offset = hdr->log_file_head_offset;
+
+	for (;;) {
+		/* the view begins from the first non-synced transaction */
+		ret = mail_transaction_log_view_set(view->log_view,
+						    start_seq, start_offset,
+						    end_seq, end_offset,
+						    &reset);
+		if (ret <= 0) {
+			if (ret < 0)
+				return -1;
+
+			/* FIXME: use the new index to get needed
+			   changes */
 			mail_index_set_error(view->index,
 				"Transaction log got desynced for index %s",
 				view->index->filepath);
 			view->inconsistent = TRUE;
-		}
-		return -1;
-	}
+			return -1;
+		}
+
+		if (!reset || sync_expunges)
+			break;
+
+		/* we can't do this. sync only up to reset. */
+		mail_transaction_log_view_get_prev_pos(view->log_view,
+						       &end_seq, &end_offset);
+		end_seq--; end_offset = (uoff_t)-1;
+		if (end_seq < start_seq) {
+			/* we have only this reset log */
+			mail_transaction_log_view_clear(view->log_view);
+			break;
+		}
+	}
+
 	return 0;
 }
 
@@ -121,7 +147,7 @@ view_sync_get_expunges(struct mail_index
 	unsigned int count;
 	int ret;
 
-	if (view_sync_set_log_view_range(view) < 0)
+	if (view_sync_set_log_view_range(view, TRUE) < 0)
 		return -1;
 
 	/* get a list of expunge transactions. there may be some that we have
@@ -196,6 +222,7 @@ int mail_index_view_sync_begin(struct ma
 	struct mail_index_view_sync_ctx *ctx;
 	struct mail_index_map *map;
 	ARRAY_TYPE(seq_range) expunges = ARRAY_INIT;
+	bool sync_expunges;
 
 	i_assert(!view->syncing);
 	i_assert(view->transactions == 0);
@@ -203,13 +230,14 @@ int mail_index_view_sync_begin(struct ma
 	if (mail_index_view_lock_head(view) < 0)
 		return -1;
 
-	if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0) {
+	sync_expunges = (flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0;
+	if (sync_expunges) {
 		/* get list of all expunges first */
 		if (view_sync_get_expunges(view, &expunges) < 0)
 			return -1;
 	}
 
-	if (view_sync_set_log_view_range(view) < 0) {
+	if (view_sync_set_log_view_range(view, sync_expunges) < 0) {
 		if (array_is_created(&expunges))
 			array_free(&expunges);
 		return -1;
@@ -222,7 +250,7 @@ int mail_index_view_sync_begin(struct ma
 	mail_index_sync_map_init(&ctx->sync_map_ctx, view,
 				 MAIL_INDEX_SYNC_HANDLER_VIEW);
 
-	if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0) {
+	if (sync_expunges) {
 		view->sync_new_map = view->index->map;
 		view->sync_new_map->refcount++;
 
@@ -590,11 +618,7 @@ void mail_index_view_sync_end(struct mai
 #endif
 
 	/* set log view to empty range so unneeded memory gets freed */
-	(void)mail_transaction_log_view_set(view->log_view,
-					    view->log_file_head_seq,
-					    view->log_file_head_offset,
-					    view->log_file_head_seq,
-					    view->log_file_head_offset);
+	mail_transaction_log_view_clear(view->log_view);
 
 	if (array_is_created(&ctx->expunges))
 		array_free(&ctx->expunges);
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index-write.c
--- a/src/lib-index/mail-index-write.c	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index-write.c	Sun Jul 01 01:05:26 2007 +0300
@@ -214,5 +214,5 @@ void mail_index_write(struct mail_index 
 	if (want_rotate &&
 	    hdr->log_file_seq == index->log->head->hdr.file_seq &&
 	    hdr->log_file_tail_offset == hdr->log_file_head_offset)
-		(void)mail_transaction_log_rotate(index->log);
-}
+		(void)mail_transaction_log_rotate(index->log, FALSE);
+}
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-index.h	Sun Jul 01 01:05:26 2007 +0300
@@ -323,6 +323,9 @@ void mail_index_update_flags_range(struc
 				   uint32_t seq1, uint32_t seq2,
 				   enum modify_type modify_type,
 				   enum mail_flags flags);
+/* Reset the index before committing this transaction. This is usually done
+   only when UIDVALIDITY changes. */
+void mail_index_reset(struct mail_index_transaction *t);
 
 /* Lookup a keyword, returns TRUE if found, FALSE if not. If autocreate is
    TRUE, the keyword is automatically created and TRUE is always returned. */
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-transaction-log-append.c
--- a/src/lib-index/mail-transaction-log-append.c	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-transaction-log-append.c	Sun Jul 01 01:05:26 2007 +0300
@@ -173,7 +173,8 @@ static void log_append_ext_intro(struct 
 	uint32_t idx;
 	unsigned int count;
 
-	if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) {
+	if (t->reset ||
+	    !mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) {
 		/* new extension */
 		idx = (uint32_t)-1;
 	}
@@ -410,6 +411,14 @@ mail_transaction_log_append_locked(struc
 	index = mail_index_view_get_index(view);
 	log = index->log;
 
+	if (t->reset) {
+		/* Reset the whole index, preserving only indexid. Begin by
+		   rotating the log. We don't care if we skip some non-synced
+		   transactions. */
+		if (mail_transaction_log_rotate(log, TRUE) < 0)
+			return -1;
+	}
+
 	if (!index->log_locked) {
 		/* update sync_offset */
 		if (mail_transaction_log_file_map(log->head,
diff -r 064aa8ff69c2 -r a9df50952600 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c	Sun Jul 01 01:04:57 2007 +0300
+++ b/src/lib-index/mail-transaction-log-file.c	Sun Jul 01 01:05:26 2007 +0300
@@ -429,7 +429,8 @@ mail_transaction_log_file_is_dupe(struct
 
 static int
 mail_transaction_log_file_create2(struct mail_transaction_log_file *file,
-				  int new_fd, struct dotlock **dotlock)
+				  int new_fd, bool reset,
+				  struct dotlock **dotlock)
 {
 	struct mail_index *index = file->log->index;
 	struct stat st;
@@ -443,7 +444,9 @@ mail_transaction_log_file_create2(struct


More information about the dovecot-cvs mailing list