dovecot-2.2: lib-index: Don't keep cache file locked for as long...

dovecot at dovecot.org dovecot at dovecot.org
Mon Oct 6 23:33:37 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/d6e08d98a170
changeset: 17899:d6e08d98a170
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Oct 07 02:33:03 2014 +0300
description:
lib-index: Don't keep cache file locked for as long while syncing index.
The earlier code was required for updating the cache offsets, but this code
no longer exists. Now we just need to update the record counts in the
header, which can be done quickly at the end of the sync.

diffstat:

 src/lib-index/mail-cache-private.h     |   2 -
 src/lib-index/mail-cache-sync-update.c |  74 +++++++++------------------------
 src/lib-index/mail-cache-transaction.c |  15 ------
 3 files changed, 20 insertions(+), 71 deletions(-)

diffs (144 lines):

diff -r f5e4566f1e03 -r d6e08d98a170 src/lib-index/mail-cache-private.h
--- a/src/lib-index/mail-cache-private.h	Mon Oct 06 20:50:34 2014 +0000
+++ b/src/lib-index/mail-cache-private.h	Tue Oct 07 02:33:03 2014 +0300
@@ -256,8 +256,6 @@
 void mail_cache_file_close(struct mail_cache *cache);
 int mail_cache_reopen(struct mail_cache *cache);
 
-void mail_cache_delete(struct mail_cache *cache);
-
 /* Notify the decision handling code that field was looked up for seq.
    This should be called even for fields that aren't currently in cache file */
 void mail_cache_decision_state_update(struct mail_cache_view *view,
diff -r f5e4566f1e03 -r d6e08d98a170 src/lib-index/mail-cache-sync-update.c
--- a/src/lib-index/mail-cache-sync-update.c	Mon Oct 06 20:50:34 2014 +0000
+++ b/src/lib-index/mail-cache-sync-update.c	Tue Oct 07 02:33:03 2014 +0300
@@ -5,21 +5,9 @@
 #include "mail-index-sync-private.h"
 
 struct mail_cache_sync_context {
-	unsigned int locked:1;
-	unsigned int lock_failed:1;
+	unsigned expunge_count;
 };
 
-static void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx,
-				      struct mail_cache_sync_context *ctx)
-{
-	if (ctx == NULL)
-		return;
-
-	if (ctx->locked)
-		(void)mail_cache_unlock(sync_ctx->view->index->cache);
-	i_free(ctx);
-}
-
 static struct mail_cache_sync_context *mail_cache_handler_init(void **context)
 {
 	struct mail_cache_sync_context *ctx;
@@ -33,48 +21,35 @@
 	return ctx;
 }
 
-static int mail_cache_handler_lock(struct mail_cache_sync_context *ctx,
-				   struct mail_cache *cache)
+static void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx,
+				      struct mail_cache_sync_context *ctx)
 {
-	int ret;
+	struct mail_cache *cache = sync_ctx->view->index->cache;
 
-	if (ctx->locked)
-		return MAIL_CACHE_IS_UNUSABLE(cache) ? 0 : 1;
-	if (ctx->lock_failed)
-		return 0;
+	if (ctx == NULL)
+		return;
 
-	if (!ctx->locked) {
-		if ((ret = mail_cache_lock(cache, TRUE)) <= 0) {
-                        ctx->lock_failed = TRUE;
-			return ret;
-		}
-		ctx->locked = TRUE;
+	if (mail_cache_lock(cache, TRUE) > 0) {
+		/* update the record counts in the cache file's header. these
+		   are used to figure out when a cache file should be
+		   recreated and the old data dropped. */
+		cache->hdr_copy.deleted_record_count += ctx->expunge_count;
+		if (cache->hdr_copy.record_count >= ctx->expunge_count)
+			cache->hdr_copy.record_count -= ctx->expunge_count;
+		else
+			cache->hdr_copy.record_count = 0;
+		cache->hdr_modified = TRUE;
+		(void)mail_cache_unlock(cache);
 	}
-	return 1;
-}
-
-static bool get_cache_file_seq(struct mail_index_view *view,
-			      uint32_t *cache_file_seq_r)
-{
-	const struct mail_index_ext *ext;
-
-	ext = mail_index_view_get_ext(view, view->index->cache->ext_id);
-	if (ext == NULL)
-		return FALSE;
-
-	*cache_file_seq_r = ext->reset_id;
-	return TRUE;
+	i_free(ctx);
 }
 
 int mail_cache_expunge_handler(struct mail_index_sync_map_ctx *sync_ctx,
 			       uint32_t seq ATTR_UNUSED, const void *data,
-			       void **sync_context, void *context)
+			       void **sync_context, void *context ATTR_UNUSED)
 {
-	struct mail_cache *cache = context;
 	struct mail_cache_sync_context *ctx = *sync_context;
 	const uint32_t *cache_offset = data;
-	uint32_t cache_file_seq;
-	int ret;
 
 	if (data == NULL) {
 		mail_cache_handler_deinit(sync_ctx, ctx);
@@ -86,15 +61,6 @@
 		return 0;
 
 	ctx = mail_cache_handler_init(sync_context);
-	ret = mail_cache_handler_lock(ctx, cache);
-	if (ret <= 0)
-		return ret;
-
-	if (!get_cache_file_seq(sync_ctx->view, &cache_file_seq))
-		return 0;
-
-	if (!MAIL_CACHE_IS_UNUSABLE(cache) &&
-	    cache_file_seq == cache->hdr->file_seq)
-		mail_cache_delete(cache);
+	ctx->expunge_count++;
 	return 0;
 }
diff -r f5e4566f1e03 -r d6e08d98a170 src/lib-index/mail-cache-transaction.c
--- a/src/lib-index/mail-cache-transaction.c	Mon Oct 06 20:50:34 2014 +0000
+++ b/src/lib-index/mail-cache-transaction.c	Tue Oct 07 02:33:03 2014 +0300
@@ -800,18 +800,3 @@
 
 	return mail_cache_field_exists(ctx->view, seq, field_idx) == 0;
 }
-
-void mail_cache_delete(struct mail_cache *cache)
-{
-	i_assert(cache->locked);
-
-	/* we'll only update the deleted record count in the header. we can't
-	   really do any actual deleting as other processes might still be
-	   using the data. also it's actually useful as old index views are
-	   still able to ask cached data for messages that have already been
-	   expunged. */
-	cache->hdr_copy.deleted_record_count++;
-	if (cache->hdr_copy.record_count > 0)
-		cache->hdr_copy.record_count--;
-	cache->hdr_modified = TRUE;
-}


More information about the dovecot-cvs mailing list