dovecot: Fixes to handling when fields are dropped from cache file.

dovecot at dovecot.org dovecot at dovecot.org
Fri Jan 4 02:46:52 EET 2008


details:   http://hg.dovecot.org/dovecot/rev/f0ad529ac9ea
changeset: 7105:f0ad529ac9ea
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jan 04 02:46:48 2008 +0200
description:
Fixes to handling when fields are dropped from cache file.

diffstat:

4 files changed, 37 insertions(+), 25 deletions(-)
src/lib-index/mail-cache-compress.c    |   29 +++++++++++++++++------------
src/lib-index/mail-cache-fields.c      |    5 -----
src/lib-index/mail-cache-private.h     |    1 +
src/lib-index/mail-cache-transaction.c |   27 +++++++++++++++++++--------

diffs (133 lines):

diff -r db5f55daa002 -r f0ad529ac9ea src/lib-index/mail-cache-compress.c
--- a/src/lib-index/mail-cache-compress.c	Fri Jan 04 02:14:29 2008 +0200
+++ b/src/lib-index/mail-cache-compress.c	Fri Jan 04 02:46:48 2008 +0200
@@ -191,13 +191,6 @@ mail_cache_copy(struct mail_cache *cache
 	max_drop_time = idx_hdr->day_stamp == 0 ? 0 :
 		idx_hdr->day_stamp - MAIL_CACHE_FIELD_DROP_SECS;
 
-	/* if some fields' "last used" time is zero, they were probably just
-	   added by us. change them to the current time. */
-	for (i = 0; i < cache->fields_count; i++) {
-		if (cache->fields[i].last_used == 0)
-			cache->fields[i].last_used = ioloop_time;
-	}
-
 	orig_fields_count = cache->fields_count;
 	if (cache->file_fields_count == 0) {
 		/* creating the initial cache file. add all fields. */
@@ -206,16 +199,28 @@ mail_cache_copy(struct mail_cache *cache
 		used_fields_count = i;
 	} else {
 		for (i = used_fields_count = 0; i < orig_fields_count; i++) {
+			struct mail_cache_field_private *field =
+				&cache->fields[i];
 			enum mail_cache_decision_type dec =
-				cache->fields[i].field.decision;
+				field->field.decision;
 
 			/* if the decision isn't forced and this field hasn't
 			   been accessed for a while, drop it */
 			if ((dec & MAIL_CACHE_DECISION_FORCED) == 0 &&
-			    (time_t)cache->fields[i].last_used < max_drop_time)
-				cache->fields[i].used = FALSE;
-
-			ctx.field_file_map[i] = !cache->fields[i].used ?
+			    (time_t)field->last_used < max_drop_time &&
+			    !field->adding) {
+				dec = MAIL_CACHE_DECISION_NO;
+				field->field.decision = dec;
+			}
+
+			/* drop all fields we don't want */
+			if ((dec & ~MAIL_CACHE_DECISION_FORCED) ==
+			    MAIL_CACHE_DECISION_NO && !field->adding) {
+				field->used = FALSE;
+				field->last_used = 0;
+			}
+
+			ctx.field_file_map[i] = !field->used ?
 				(uint32_t)-1 : used_fields_count++;
 		}
 	}
diff -r db5f55daa002 -r f0ad529ac9ea src/lib-index/mail-cache-fields.c
--- a/src/lib-index/mail-cache-fields.c	Fri Jan 04 02:14:29 2008 +0200
+++ b/src/lib-index/mail-cache-fields.c	Fri Jan 04 02:46:48 2008 +0200
@@ -503,11 +503,6 @@ void mail_cache_header_fields_get(struct
 	memset(&hdr, 0, sizeof(hdr));
 	hdr.fields_count = cache->file_fields_count;
 	for (i = 0; i < cache->fields_count; i++) {
-		if (cache->fields[i].last_used == 0) {
-			/* return newly added fields' last_used as
-			   the current time */
-			cache->fields[i].last_used = ioloop_time;
-		}
 		if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i))
 			hdr.fields_count++;
 	}
diff -r db5f55daa002 -r f0ad529ac9ea src/lib-index/mail-cache-private.h
--- a/src/lib-index/mail-cache-private.h	Fri Jan 04 02:14:29 2008 +0200
+++ b/src/lib-index/mail-cache-private.h	Fri Jan 04 02:46:48 2008 +0200
@@ -121,6 +121,7 @@ struct mail_cache_field_private {
 
 	/* Unused fields aren't written to cache file */
 	unsigned int used:1;
+	unsigned int adding:1;
 	unsigned int decision_dirty:1;
 };
 
diff -r db5f55daa002 -r f0ad529ac9ea src/lib-index/mail-cache-transaction.c
--- a/src/lib-index/mail-cache-transaction.c	Fri Jan 04 02:14:29 2008 +0200
+++ b/src/lib-index/mail-cache-transaction.c	Fri Jan 04 02:46:48 2008 +0200
@@ -803,18 +803,25 @@ mail_cache_header_fields_write(struct ma
 	return 0;
 }
 
-static int mail_cache_header_add_field(struct mail_cache_transaction_ctx *ctx,
-				       unsigned int field_idx)
-{
-	struct mail_cache *cache = ctx->cache;
+static void mail_cache_mark_adding(struct mail_cache *cache, bool set)
+{
 	unsigned int i;
-	int ret;
 
 	/* we want to avoid adding all the fields one by one to the cache file,
 	   so just add all of them at once in here. the unused ones get dropped
 	   later when compressing. */
-	for (i = 0; i < cache->fields_count; i++)
-		cache->fields[i].used = TRUE;
+	for (i = 0; i < cache->fields_count; i++) {
+		if (set)
+			cache->fields[i].used = TRUE;
+		cache->fields[i].adding = set;
+	}
+}
+
+static int mail_cache_header_add_field(struct mail_cache_transaction_ctx *ctx,
+				       unsigned int field_idx)
+{
+	struct mail_cache *cache = ctx->cache;
+	int ret;
 
 	if ((ret = mail_cache_transaction_lock(ctx)) <= 0) {
 		if (MAIL_CACHE_IS_UNUSABLE(cache))
@@ -875,6 +882,7 @@ void mail_cache_add(struct mail_cache_tr
 	uint32_t file_field, data_size32;
 	unsigned int fixed_size;
 	size_t full_size;
+	int ret;
 
 	i_assert(field_idx < ctx->cache->fields_count);
 	i_assert(data_size < (uint32_t)-1);
@@ -896,7 +904,10 @@ void mail_cache_add(struct mail_cache_tr
 	file_field = ctx->cache->field_file_map[field_idx];
 	if (MAIL_CACHE_IS_UNUSABLE(ctx->cache) || file_field == (uint32_t)-1) {
 		/* we'll have to add this field to headers */
-		if (mail_cache_header_add_field(ctx, field_idx) < 0)
+		mail_cache_mark_adding(ctx->cache, TRUE);
+		ret = mail_cache_header_add_field(ctx, field_idx);
+		mail_cache_mark_adding(ctx->cache, FALSE);
+		if (ret < 0)
 			return;
 
 		if (ctx->cache_file_seq == 0)


More information about the dovecot-cvs mailing list