changeset 7105:f0ad529ac9ea HEAD

Fixes to handling when fields are dropped from cache file.
author Timo Sirainen <tss@iki.fi>
date Fri, 04 Jan 2008 02:46:48 +0200
parents db5f55daa002
children 1bd8b17bfabe
files src/lib-index/mail-cache-compress.c src/lib-index/mail-cache-fields.c src/lib-index/mail-cache-private.h src/lib-index/mail-cache-transaction.c
diffstat 4 files changed, 36 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
 	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 @@
 		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;
+			    (time_t)field->last_used < max_drop_time &&
+			    !field->adding) {
+				dec = MAIL_CACHE_DECISION_NO;
+				field->field.decision = dec;
+			}
 
-			ctx.field_file_map[i] = !cache->fields[i].used ?
+			/* 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++;
 		}
 	}
--- 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 @@
 	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++;
 	}
--- 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 @@
 
 	/* Unused fields aren't written to cache file */
 	unsigned int used:1;
+	unsigned int adding:1;
 	unsigned int decision_dirty:1;
 };
 
--- 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,19 +803,26 @@
 	return 0;
 }
 
+static void mail_cache_mark_adding(struct mail_cache *cache, bool set)
+{
+	unsigned int i;
+
+	/* 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++) {
+		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;
-	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;
-
 	if ((ret = mail_cache_transaction_lock(ctx)) <= 0) {
 		if (MAIL_CACHE_IS_UNUSABLE(cache))
 			return -1;
@@ -875,6 +882,7 @@
 	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 @@
 	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)