changeset 7623:1285aedb353c HEAD

Keep view's map always at least up-to-date with syncing. If there have been no expunges, the map is immediately replaced with the latest map. Before the map may not have been updated until syncing was finished. This change is necessary to update modseqs correctly while they're being enabled.
author Timo Sirainen <tss@iki.fi>
date Sat, 15 Mar 2008 08:27:38 +0200
parents 23bbefd2ef4e
children 271131a1e060
files src/lib-index/mail-index-view-private.h src/lib-index/mail-index-view-sync.c
diffstat 2 files changed, 21 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-view-private.h	Fri Mar 14 11:56:37 2008 +0200
+++ b/src/lib-index/mail-index-view-private.h	Sat Mar 15 08:27:38 2008 +0200
@@ -52,8 +52,6 @@
 	unsigned int inconsistency_id;
 
 	struct mail_index_map *map;
-	/* After syncing view, map is replaced with sync_new_map. */
-	struct mail_index_map *sync_new_map;
 	/* All mappings where we have returned records. They need to be kept
 	   valid until view is synchronized. */
 	ARRAY_DEFINE(map_refs, struct mail_index_map *);
--- a/src/lib-index/mail-index-view-sync.c	Fri Mar 14 11:56:37 2008 +0200
+++ b/src/lib-index/mail-index-view-sync.c	Sat Mar 15 08:27:38 2008 +0200
@@ -13,6 +13,9 @@
 	enum mail_index_view_sync_flags flags;
 	struct mail_index_sync_map_ctx sync_map_ctx;
 
+	/* After syncing view, map is replaced with sync_new_map. */
+	struct mail_index_map *sync_new_map;
+
 	ARRAY_TYPE(seq_range) expunges;
 	unsigned int finish_min_msg_count;
 
@@ -271,7 +274,7 @@
 	struct mail_index_map *map;
 	ARRAY_TYPE(seq_range) expunges = ARRAY_INIT;
 	unsigned int expunge_count = 0;
-	bool reset, sync_expunges, quick_sync;
+	bool reset, sync_expunges, quick_sync, have_expunges;
 
 	i_assert(!view->syncing);
 	i_assert(view->transactions == 0);
@@ -321,7 +324,9 @@
 				     view->index->filepath);
 	}
 
-	if (sync_expunges || !view_sync_have_expunges(view)) {
+	have_expunges = view_sync_have_expunges(view);
+	if (!have_expunges) {
+		/* no expunges, we can just replace the map */
 		if (view->index->map->hdr.messages_count <
 		    ctx->finish_min_msg_count) {
 			mail_index_set_error(view->index,
@@ -333,24 +338,14 @@
 			view->inconsistent = TRUE;
 		}
 
-		view->sync_new_map = view->index->map;
-		view->sync_new_map->refcount++;
-
-		/* keep the old mapping without expunges until we're
-		   fully synced */
+		view->index->map->refcount++;
+		mail_index_unmap(&view->map);
+		view->map = view->index->map;
 	} else {
-		/* We need a private copy of the map if we don't want to
-		   sync expunges.
-
-		   If view's map is the head map, it means that it contains
-		   already all the latest changes and there's no need for us
-		   to apply any changes to it. This can only happen if there
-		   hadn't been any expunges. */
-		if (view->map != view->index->map) {
-			/* Using non-head mapping. We have to apply
-			   transactions to it to get latest changes into it. */
-			ctx->sync_map_update = TRUE;
-		}
+		/* expunges seen. create a private map which we update.
+		   if we're syncing expunges the map will finally be replaced
+		   with the head map to remove the expunged messages. */
+		ctx->sync_map_update = TRUE;
 
 		if (view->map->refcount > 1) {
 			map = mail_index_map_clone(view->map);
@@ -359,6 +354,11 @@
 		} else {
 			map = view->map;
 		}
+
+		if (sync_expunges) {
+			ctx->sync_new_map = view->index->map;
+			ctx->sync_new_map->refcount++;
+		}
 	}
 
 #ifdef DEBUG
@@ -667,10 +667,9 @@
 	}
 	mail_index_modseq_sync_end(&ctx->sync_map_ctx.modseq_ctx);
 
-	if (view->sync_new_map != NULL) {
+	if (ctx->sync_new_map != NULL) {
 		mail_index_unmap(&view->map);
-		view->map = view->sync_new_map;
-		view->sync_new_map = NULL;
+		view->map = ctx->sync_new_map;
 	}
 
 	i_assert(view->map->hdr.messages_count >= ctx->finish_min_msg_count);