[dovecot-cvs] dovecot/src/lib-storage/index index-fetch.c, 1.54, 1.55 index-mail-headers.c, 1.24, 1.25 index-mail.c, 1.40, 1.41 index-mail.h, 1.15, 1.16 index-search.c, 1.90, 1.91 index-storage.c, 1.55, 1.56

cras at dovecot.org cras at dovecot.org
Thu Jul 8 23:26:19 EEST 2004


Update of /home/cvs/dovecot/src/lib-storage/index
In directory talvi:/tmp/cvs-serv1384/lib-storage/index

Modified Files:
	index-fetch.c index-mail-headers.c index-mail.c index-mail.h 
	index-search.c index-storage.c 
Log Message:
Cache file fixes, API changes, etc. It's still in somewhat ugly state, but
getting better..



Index: index-fetch.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-fetch.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- index-fetch.c	22 Jun 2004 07:36:33 -0000	1.54
+++ index-fetch.c	8 Jul 2004 20:26:16 -0000	1.55
@@ -10,23 +10,13 @@
 {
 	struct index_transaction_context *t =
 		(struct index_transaction_context *)_t;
-        const struct mail_index_record *rec;
-
-	if (mail_index_lookup(t->trans_view, seq, &rec) < 0) {
-		mail_storage_set_index_error(t->ibox);
-		return NULL;
-	}
-
-	if (rec == NULL)
-		return NULL;
 
 	if (t->fetch_mail.pool != NULL)
 		index_mail_deinit(&t->fetch_mail);
 
 	index_mail_init(t, &t->fetch_mail, wanted_fields, NULL);
-	if (index_mail_next(&t->fetch_mail, rec, seq, FALSE) <= 0)
+	if (index_mail_next(&t->fetch_mail, seq) < 0)
 		return NULL;
-
 	return &t->fetch_mail.mail;
 }
 

Index: index-mail-headers.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail-headers.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- index-mail-headers.c	4 Jul 2004 21:22:00 -0000	1.24
+++ index-mail-headers.c	8 Jul 2004 20:26:16 -0000	1.25
@@ -191,8 +191,9 @@
 		return -1;
 
 	for (; idx < MAIL_CACHE_HEADERS_COUNT; idx++) {
-		if ((mail->data.cached_fields &
-		     mail_cache_header_fields[idx]) != 0)
+		if (mail_cache_field_exists(mail->trans->cache_view,
+					    mail->data.seq,
+					    mail_cache_header_fields[idx]) > 0)
 			return idx;
 	}
 
@@ -320,9 +321,9 @@
 			data->save_sent_date = FALSE;
 		}
 		if (data->sent_date.time != (time_t)-1) {
-			index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE,
-					     &data->sent_date,
-					     sizeof(data->sent_date));
+                        mail_cache_add(mail->trans->cache_trans, data->seq,
+				       MAIL_CACHE_SENT_DATE, &data->sent_date,
+				       sizeof(data->sent_date));
 		}
 
 		cached_headers_mark_fully_saved(mail);
@@ -387,8 +388,11 @@
 
 static int index_mail_can_cache_headers(struct index_mail *mail)
 {
-	if ((mail->data.cached_fields &
-	     mail_cache_header_fields[MAIL_CACHE_HEADERS_COUNT-1]) != 0)
+	enum mail_cache_field field;
+
+	field = mail_cache_header_fields[MAIL_CACHE_HEADERS_COUNT-1];
+	if (mail_cache_field_exists(mail->trans->cache_view, mail->data.seq,
+				    field) != 0)
 		return FALSE; /* all headers used */
 
 	/* FIXME: add some smart checks here. we don't necessarily want to
@@ -493,9 +497,6 @@
 	if (mail->data.header_data == NULL)
 		mail->data.header_data = str_new(mail->pool, 4096);
 
-	/* can_cache_headers() locks the cache file. it must be done before
-	   we can expect cached headers to stay the same. it's not a good idea
-	   to cache some headers twice because of race conditions.. */
 	if (!data->header_fully_parsed && index_mail_can_cache_headers(mail)) {
 		if (data->header_data_cached_partial) {
 			/* too difficult to handle efficiently, trash it */
@@ -722,8 +723,10 @@
 	if (idx != -2) {
 		if (idx >= 0) {
 			for (; idx < MAIL_CACHE_HEADERS_COUNT; idx++) {
-				if ((data->cached_fields &
-				     mail_cache_header_fields[idx]) != 0)
+				if (mail_cache_field_exists(
+					mail->trans->cache_view,
+					data->seq,
+					mail_cache_header_fields[idx]) > 0)
 					break;
 			}
 		}

Index: index-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- index-mail.c	4 Jul 2004 21:07:43 -0000	1.40
+++ index-mail.c	8 Jul 2004 20:26:16 -0000	1.41
@@ -13,7 +13,7 @@
 #include "index-storage.h"
 #include "index-mail.h"
 
-static void index_mail_parse_body(struct index_mail *mail);
+static void index_mail_parse_body(struct index_mail *mail, int need_parts);
 
 static struct message_part *get_cached_parts(struct index_mail *mail)
 {
@@ -21,17 +21,13 @@
 	buffer_t *part_buf;
 	const char *error;
 
-	if ((mail->data.cached_fields & MAIL_CACHE_MESSAGEPART) == 0) {
-		mail_cache_mark_missing(mail->trans->cache_view, mail->data.seq,
-					MAIL_CACHE_MESSAGEPART);
-		return NULL;
-	}
-
+	t_push();
 	part_buf = buffer_create_dynamic(pool_datastack_create(),
 					 128, (size_t)-1);
-	if (!mail_cache_lookup_field(mail->trans->cache_view, part_buf,
-				     mail->data.seq, MAIL_CACHE_MESSAGEPART)) {
-		/* unexpected - must be an error */
+	if (mail_cache_lookup_field(mail->trans->cache_view, part_buf,
+				    mail->data.seq,
+				    MAIL_CACHE_MESSAGEPART) <= 0) {
+		t_pop();
 		return NULL;
 	}
 
@@ -39,6 +35,8 @@
 					buffer_get_data(part_buf, NULL),
 					buffer_get_used_size(part_buf),
 					&error);
+	t_pop();
+
 	if (part == NULL) {
 		mail_cache_set_corrupted(mail->ibox->cache,
 			"Corrupted cached message_part data (%s)", error);
@@ -62,16 +60,12 @@
 {
 	string_t *str;
 
-	if ((mail->data.cached_fields & field) == 0) {
-		mail_cache_mark_missing(mail->trans->cache_view,
-					mail->data.seq, field);
-		return NULL;
-	}
-
 	str = str_new(mail->pool, 32);
-	if (!mail_cache_lookup_string_field(mail->trans->cache_view, str,
-					    mail->data.seq, field))
+	if (mail_cache_lookup_string_field(mail->trans->cache_view, str,
+					   mail->data.seq, field) <= 0) {
+		p_free(mail->pool, str);
 		return NULL;
+	}
 
 	return str_c(str);
 }
@@ -85,10 +79,8 @@
 
 	t_push();
 	buf = buffer_create_data(pool_datastack_create(), data, data_size);
-	if (!mail_cache_lookup_field(mail->trans->cache_view, buf,
-				     mail->data.seq, field)) {
-		mail_cache_mark_missing(mail->trans->cache_view,
-					mail->data.seq, field);
+	if (mail_cache_lookup_field(mail->trans->cache_view, buf,
+				    mail->data.seq, field) <= 0) {
 		ret = FALSE;
 	} else {
 		i_assert(buffer_get_used_size(buf) == data_size);
@@ -144,35 +136,6 @@
 	}
 }
 
-static int index_mail_cache_can_add(struct index_mail *mail,
-				    enum mail_cache_field field)
-{
-	if ((mail->data.cached_fields & field) != 0)
-		return FALSE;
-
-	// FIXME: check if we really want to cache this
-
-	index_mail_cache_transaction_begin(mail);
-
-	/* cached_fields may have changed, recheck */
-	if ((mail->data.cached_fields & field) != 0)
-		return FALSE;
-
-	return TRUE;
-}
-
-void index_mail_cache_add(struct index_mail *mail, enum mail_cache_field field,
-			  const void *data, size_t size)
-{
-        if (!index_mail_cache_can_add(mail, field))
-		return;
-
-	mail_cache_add(mail->trans->cache_trans, mail->data.seq,
-		       field, data, size);
-
-	mail->data.cached_fields |= field;
-}
-
 const struct mail_full_flags *index_mail_get_flags(struct mail *_mail)
 {
 	struct index_mail *mail = (struct index_mail *) _mail;
@@ -194,17 +157,15 @@
 	if (data->parts != NULL)
 		return data->parts;
 
-	if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) == 0) {
-		data->parts = get_cached_parts(mail);
-		if (data->parts != NULL)
-			return data->parts;
-	}
+	data->parts = get_cached_parts(mail);
+	if (data->parts != NULL)
+		return data->parts;
 
 	if (data->parser_ctx == NULL) {
 		if (!index_mail_parse_headers(mail))
 			return NULL;
 	}
-	index_mail_parse_body(mail);
+	index_mail_parse_body(mail, TRUE);
 
 	return data->parts;
 }
@@ -251,9 +212,9 @@
 				tz = 0;
 			}
                         data->sent_date.timezone = tz;
-			index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE,
-					     &data->sent_date,
-					     sizeof(data->sent_date));
+			mail_cache_add(mail->trans->cache_trans, mail->data.seq,
+				       MAIL_CACHE_SENT_DATE, &data->sent_date,
+				       sizeof(data->sent_date));
 		}
 	}
 
@@ -266,12 +227,8 @@
 {
 	struct index_mail_data *data = &mail->data;
 
-	if (data->parts == NULL) {
-		if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0)
-			(void)index_mail_get_parts(&mail->mail);
-		else
-			data->parts = get_cached_parts(mail);
-	}
+	if (data->parts == NULL)
+		(void)index_mail_get_parts(&mail->mail);
 
 	if (data->parts != NULL) {
 		data->hdr_size = data->parts->header_size;
@@ -294,11 +251,9 @@
 	if (data->size != (uoff_t)-1)
 		return data->size;
 
-	if ((mail->wanted_fields & MAIL_FETCH_SIZE) == 0) {
-		data->size = index_mail_get_cached_virtual_size(mail);
-		if (data->size != (uoff_t)-1)
-			return data->size;
-	}
+	data->size = index_mail_get_cached_virtual_size(mail);
+	if (data->size != (uoff_t)-1)
+		return data->size;
 
 	if (get_msgpart_sizes(mail))
 		return data->size;
@@ -318,10 +273,11 @@
 	imap_bodystructure_parse_header(pool, part, hdr);
 }
 
-static void index_mail_parse_body(struct index_mail *mail)
+static void index_mail_parse_body(struct index_mail *mail, int need_parts)
 {
 	struct index_mail_data *data = &mail->data;
         enum mail_cache_record_flag cache_flags;
+	enum mail_cache_decision_type decision;
 	buffer_t *buffer;
 	const void *buf_data;
 	size_t buf_size;
@@ -332,6 +288,8 @@
 	i_stream_seek(data->stream, data->hdr_size.physical_size);
 
 	if (data->bodystructure_header_parsed) {
+		/* bodystructure header is parsed, we want the body's mime
+		   headers too */
 		message_parser_parse_body(data->parser_ctx,
 					  parse_bodystructure_header,
 					  NULL, mail->pool);
@@ -344,41 +302,50 @@
 	data->body_size = data->parts->body_size;
 	data->body_size_set = TRUE;
 
-	if (mail->mail.has_nuls || mail->mail.has_no_nuls)
-		return;
+	index_mail_cache_transaction_begin(mail);
 
-	/* we know the NULs now, update them */
-	if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
-		mail->mail.has_nuls = TRUE;
-		mail->mail.has_no_nuls = FALSE;
-	} else {
-		mail->mail.has_nuls = FALSE;
-		mail->mail.has_no_nuls = TRUE;
-	}
+	if (!mail->mail.has_nuls && !mail->mail.has_no_nuls) {
+		/* we know the NULs now, update them */
+		if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
+			mail->mail.has_nuls = TRUE;
+			mail->mail.has_no_nuls = FALSE;
+		} else {
+			mail->mail.has_nuls = FALSE;
+			mail->mail.has_no_nuls = TRUE;
+		}
 
-	index_mail_cache_transaction_begin(mail);
+		/* update cache_flags */
+		cache_flags =
+			mail_cache_get_record_flags(mail->trans->cache_view,
+						    mail->data.seq);
+		if (mail->mail.has_nuls)
+			cache_flags |= MAIL_INDEX_FLAG_HAS_NULS;
+		else
+			cache_flags |= MAIL_INDEX_FLAG_HAS_NO_NULS;
 
-	/* update cache_flags */
-	cache_flags = mail_cache_get_record_flags(mail->trans->cache_view,
-						  mail->data.seq);
-	if (mail->mail.has_nuls)
-		cache_flags |= MAIL_INDEX_FLAG_HAS_NULS;
-	else
-		cache_flags |= MAIL_INDEX_FLAG_HAS_NO_NULS;
+		(void)mail_cache_update_record_flags(mail->trans->cache_view,
+						     mail->data.seq,
+						     cache_flags);
+	}
 
-	if (!mail_cache_update_record_flags(mail->trans->cache_view,
-					    mail->data.seq, cache_flags))
+	/* see if we want to cache the message part */
+	if (mail_cache_field_exists(mail->trans->cache_view, mail->data.seq,
+				    MAIL_CACHE_MESSAGEPART) != 0)
 		return;
 
-	if (index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART)) {
+	decision = mail_cache_field_get_decision(mail->ibox->cache,
+						 MAIL_CACHE_MESSAGEPART);
+	if (decision != (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED) &&
+	    (decision != MAIL_CACHE_DECISION_NO || need_parts ||
+	     (mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0)) {
 		t_push();
 		buffer = buffer_create_dynamic(pool_datastack_create(),
 					       1024, (size_t)-1);
 		message_part_serialize(mail->data.parts, buffer);
 
 		buf_data = buffer_get_data(buffer, &buf_size);
-		index_mail_cache_add(mail, MAIL_CACHE_MESSAGEPART,
-				     buf_data, buf_size);
+		mail_cache_add(mail->trans->cache_trans, mail->data.seq,
+			       MAIL_CACHE_MESSAGEPART, buf_data, buf_size);
 		t_pop();
 	}
 }
@@ -404,7 +371,7 @@
 
 	if (body_size != NULL) {
 		if (!data->body_size_set)
-			index_mail_parse_body(mail);
+			index_mail_parse_body(mail, FALSE);
 
 		*body_size = data->body_size;
 	}
@@ -418,83 +385,127 @@
 	return data->stream;
 }
 
+static void index_mail_parse_bodystructure(struct index_mail *mail,
+					   enum mail_cache_field field)
+{
+	struct index_mail_data *data = &mail->data;
+	enum mail_cache_decision_type dec;
+	string_t *str;
+	int bodystructure_cached = FALSE;
+
+	if (!data->bodystructure_header_parsed) {
+		data->bodystructure_header_want = TRUE;
+		if (!index_mail_parse_headers(mail))
+			return;
+	}
+
+	if (data->parts != NULL) {
+		i_assert(data->parts->next == NULL);
+		message_parse_from_parts(data->parts->children, data->stream,
+					 parse_bodystructure_header,
+					 mail->pool);
+	} else {
+		index_mail_parse_body(mail, FALSE);
+	}
+
+	dec = mail_cache_field_get_decision(mail->ibox->cache,
+					    MAIL_CACHE_BODYSTRUCTURE);
+	if (field == MAIL_CACHE_BODYSTRUCTURE ||
+	    ((dec & ~MAIL_CACHE_DECISION_FORCED) != MAIL_CACHE_DECISION_NO &&
+	     mail_cache_field_exists(mail->trans->cache_view, data->seq,
+				      MAIL_CACHE_BODYSTRUCTURE)) == 0) {
+		str = str_new(mail->pool, 128);
+		imap_bodystructure_write(data->parts, str, TRUE);
+		data->bodystructure = str_c(str);
+
+		if (dec !=
+		    (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
+			mail_cache_add(mail->trans->cache_trans, data->seq,
+				       MAIL_CACHE_BODYSTRUCTURE,
+				       str_c(str), str_len(str)+1);
+			bodystructure_cached = TRUE;
+		}
+	}
+
+	dec = mail_cache_field_get_decision(mail->ibox->cache, MAIL_CACHE_BODY);
+	if (field == MAIL_CACHE_BODY ||
+	    ((dec & ~MAIL_CACHE_DECISION_FORCED) != MAIL_CACHE_DECISION_NO &&
+	     mail_cache_field_exists(mail->trans->cache_view, data->seq,
+				     MAIL_CACHE_BODY)) == 0) {
+		str = str_new(mail->pool, 128);
+		imap_bodystructure_write(data->parts, str, FALSE);
+		data->body = str_c(str);
+
+		if (!bodystructure_cached && dec !=
+		    (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
+			mail_cache_add(mail->trans->cache_trans, data->seq,
+				       MAIL_CACHE_BODY,
+				       str_c(str), str_len(str)+1);
+		}
+	}
+}
+
 const char *index_mail_get_special(struct mail *_mail,
 				   enum mail_fetch_field field)
 {
 	struct index_mail *mail = (struct index_mail *) _mail;
 	struct index_mail_data *data = &mail->data;
-	struct mail_cache *cache = mail->ibox->cache;
-	enum mail_cache_field cache_field;
-	char *str;
+	string_t *str;
 
 	switch (field) {
 	case MAIL_FETCH_IMAP_BODY:
-		if ((data->cached_fields & MAIL_CACHE_BODY) &&
-		    data->body == NULL) {
-			data->body = index_mail_get_cached_string(mail,
-					MAIL_CACHE_BODY);
-		}
 		if (data->body != NULL)
 			return data->body;
-		/* fall through */
-	case MAIL_FETCH_IMAP_BODYSTRUCTURE:
-		if ((data->cached_fields & MAIL_CACHE_BODYSTRUCTURE) &&
-		    data->bodystructure == NULL) {
-			data->bodystructure = index_mail_get_cached_string(mail,
-						MAIL_CACHE_BODYSTRUCTURE);
-		}
 
-		if (data->bodystructure != NULL) {
-			if (field == MAIL_FETCH_IMAP_BODYSTRUCTURE)
-				return data->bodystructure;
-
-			/* create BODY from cached BODYSTRUCTURE */
-			t_push();
-			data->body = p_strdup(mail->pool,
-				imap_body_parse_from_bodystructure(
-							data->bodystructure));
-			t_pop();
+		/* 1) get BODY if it exists
+		   2) get it using BODYSTRUCTURE if it exists
+		   3) parse body structure, and save BODY/BODYSTRUCTURE
+		      depending on what we want cached */
 
-			if (data->body == NULL) {
-				mail_cache_set_corrupted(cache,
-					"Corrupted BODYSTRUCTURE");
-			}
+		str = str_new(mail->pool, 128);
+		if (mail_cache_lookup_string_field(mail->trans->cache_view,
+						   str, mail->data.seq,
+						   MAIL_CACHE_BODY) > 0) {
+			data->body = str_c(str);
 			return data->body;
 		}
+		if (mail_cache_lookup_string_field(mail->trans->cache_view,
+					str, mail->data.seq,
+					MAIL_CACHE_BODYSTRUCTURE) > 0) {
+			data->bodystructure = str_c(str);
+			str_truncate(str, 0);
 
-		if (!data->bodystructure_header_parsed) {
-			data->bodystructure_header_want = TRUE;
-			if (!index_mail_parse_headers(mail))
-				return NULL;
-		}
+			if (imap_body_parse_from_bodystructure(
+						data->bodystructure, str)) {
+				data->body = str_c(str);
+				return data->body;
+			}
 
-		if (data->parts != NULL) {
-			i_assert(data->parts->next == NULL);
-			message_parse_from_parts(data->parts->children,
-						 data->stream,
-						 parse_bodystructure_header,
-						 mail->pool);
-		} else {
-			index_mail_parse_body(mail);
+			/* broken, continue.. */
+			data->bodystructure = NULL;
+			mail_cache_set_corrupted(mail->ibox->cache,
+				"Corrupted BODYSTRUCTURE for mail %u",
+				mail->mail.uid);
 		}
+		p_free(mail->pool, str);
 
-		t_push();
-                str = p_strdup(mail->pool, imap_bodystructure_parse_finish(
-			data->parts, field == MAIL_FETCH_IMAP_BODYSTRUCTURE));
-		t_pop();
-
-		/* should never fail */
-		i_assert(str != NULL);
+		index_mail_parse_bodystructure(mail, MAIL_CACHE_BODY);
+		return data->body;
+	case MAIL_FETCH_IMAP_BODYSTRUCTURE:
+		if (data->bodystructure != NULL)
+			return data->bodystructure;
 
-		cache_field = field == MAIL_FETCH_IMAP_BODYSTRUCTURE ?
-			MAIL_CACHE_BODYSTRUCTURE : MAIL_CACHE_BODY;
-		index_mail_cache_add(mail, cache_field, str, strlen(str)+1);
+		str = str_new(mail->pool, 128);
+		if (mail_cache_lookup_string_field(mail->trans->cache_view,
+					str, mail->data.seq,
+					MAIL_CACHE_BODYSTRUCTURE) > 0) {
+			data->bodystructure = str_c(str);
+			return data->bodystructure;
+		}
+		p_free(mail->pool, str);
 
-		if (field == MAIL_FETCH_IMAP_BODYSTRUCTURE)
-			data->bodystructure = str;
-		else
-			data->body = str;
-		return str;
+		index_mail_parse_bodystructure(mail, MAIL_CACHE_BODYSTRUCTURE);
+		return data->bodystructure;
 	case MAIL_FETCH_IMAP_ENVELOPE:
 		if (data->envelope != NULL)
 			return data->envelope;
@@ -550,13 +561,16 @@
 	index_mail_headers_close(mail);
 }
 
-int index_mail_next(struct index_mail *mail,
-		    const struct mail_index_record *rec,
-		    uint32_t seq, int delay_open)
+int index_mail_next(struct index_mail *mail, uint32_t seq)
 {
 	struct index_mail_data *data = &mail->data;
+        const struct mail_index_record *rec;
         enum mail_cache_record_flag cache_flags;
-	int ret, open_mail;
+
+	if (mail_index_lookup(mail->trans->trans_view, seq, &rec) < 0) {
+		mail_storage_set_index_error(mail->ibox);
+		return -1;
+	}
 
 	t_push();
 
@@ -564,10 +578,7 @@
 	memset(data, 0, sizeof(*data));
 	p_clear(mail->pool);
 
-	data->cached_fields =
-		mail_cache_get_fields(mail->trans->cache_view, seq);
-	cache_flags = (data->cached_fields & MAIL_CACHE_INDEX_FLAGS) == 0 ? 0 :
-		mail_cache_get_record_flags(mail->trans->cache_view, seq);
+	cache_flags = mail_cache_get_record_flags(mail->trans->cache_view, seq);
 
 	mail->mail.seq = seq;
 	mail->mail.uid = rec->uid;
@@ -599,7 +610,6 @@
 		get_cached_sent_date(mail, &data->sent_date);
 
 	/* see if we have to parse the message */
-	open_mail = FALSE;
 	if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) &&
 	    data->parts == NULL)
 		data->parse_header = TRUE;
@@ -607,36 +617,22 @@
 		 data->bodystructure == NULL) {
 		if (data->parts == NULL)
 			data->parts = get_cached_parts(mail);
-		open_mail = TRUE;
+		data->open_mail = TRUE;
 		data->parse_header = data->parts == NULL;
-                data->bodystructure_header_want = TRUE;
+		data->bodystructure_header_want = TRUE;
 	} else if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODY) &&
 		   data->body == NULL && data->bodystructure == NULL) {
 		if (data->parts == NULL)
 			data->parts = get_cached_parts(mail);
-		open_mail = TRUE;
+		data->open_mail = TRUE;
 		data->parse_header = data->parts == NULL;
                 data->bodystructure_header_want = TRUE;
 	} else if (mail->wanted_fields & (MAIL_FETCH_STREAM_HEADER |
 					  MAIL_FETCH_STREAM_BODY))
-		open_mail = TRUE;
+		data->open_mail = TRUE;
 
         index_mail_headers_init_next(mail);
 
-	if ((open_mail || data->parse_header) && !delay_open) {
-		if (mail->mail.get_stream(&mail->mail, NULL, NULL) == NULL)
-			ret = data->deleted ? 0 : -1;
-		else
-			ret = 1;
-	} else {
-		if (mail->wanted_fields & MAIL_FETCH_RECEIVED_DATE) {
-			/* check this only after open_mail() */
-			data->received_date =
-				index_mail_get_cached_received_date(mail);
-		}
-		ret = 1;
-	}
-
 	if ((mail->wanted_fields & MAIL_FETCH_DATE) &&
 	    data->sent_date.time == (time_t)-1)
 		data->save_sent_date = TRUE;
@@ -645,7 +641,7 @@
 		data->save_envelope = TRUE;
 
 	t_pop();
-	return ret;
+	return 0;
 }
 
 void index_mail_deinit(struct index_mail *mail)

Index: index-mail.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- index-mail.h	4 Jul 2004 21:07:43 -0000	1.15
+++ index-mail.h	8 Jul 2004 20:26:16 -0000	1.16
@@ -12,7 +12,6 @@
 	time_t date, received_date;
 	uoff_t size;
 
-	enum mail_cache_field cached_fields;
 	struct mail_sent_date sent_date;
 
 	buffer_t *headers;
@@ -46,6 +45,7 @@
 	unsigned int header_data_cached_partial:1;
 	unsigned int header_fully_parsed:1;
 	unsigned int header_save:1;
+	unsigned int open_mail:1;
 };
 
 struct index_mail {
@@ -68,9 +68,7 @@
 		     struct index_mail *mail,
 		     enum mail_fetch_field wanted_fields,
 		     const char *const wanted_headers[]);
-int index_mail_next(struct index_mail *mail,
-		    const struct mail_index_record *rec,
-		    uint32_t seq, int delay_open);
+int index_mail_next(struct index_mail *mail, uint32_t seq);
 void index_mail_deinit(struct index_mail *mail);
 
 void index_mail_parse_header_init(struct index_mail *mail,
@@ -80,9 +78,6 @@
 			    struct index_mail *mail);
 
 void index_mail_cache_transaction_begin(struct index_mail *mail);
-void index_mail_cache_add(struct index_mail *mail, enum mail_cache_field field,
-			  const void *data, size_t size);
-
 int index_mail_parse_headers(struct index_mail *mail);
 
 void index_mail_headers_init(struct index_mail *mail);

Index: index-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -d -r1.90 -r1.91
--- index-search.c	22 Jun 2004 07:36:33 -0000	1.90
+++ index-search.c	8 Jul 2004 20:26:16 -0000	1.91
@@ -810,21 +810,15 @@
 struct mail *index_storage_search_next(struct mail_search_context *_ctx)
 {
         struct index_search_context *ctx = (struct index_search_context *)_ctx;
-	const struct mail_index_record *rec;
 	int ret;
 
 	ret = 0;
 	while (ctx->seq1 <= ctx->seq2) {
-		if (mail_index_lookup(ctx->view, ctx->seq1, &rec) < 0) {
+		if (index_mail_next(&ctx->imail, ctx->seq1++) < 0) {
 			ctx->failed = TRUE;
-			mail_storage_set_index_error(ctx->ibox);
 			return NULL;
 		}
 
-		ret = index_mail_next(&ctx->imail, rec, ctx->seq1++, TRUE);
-		if (ret < 0)
-			break;
-
 		t_push();
 		ret = search_match_next(ctx);
 		t_pop();

Index: index-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- index-storage.c	3 Jul 2004 20:17:37 -0000	1.55
+++ index-storage.c	8 Jul 2004 20:26:16 -0000	1.56
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002-2003 Timo Sirainen */
 
 #include "lib.h"
+#include "buffer.h"
 #include "ioloop.h"
 #include "mail-index.h"
 #include "index-storage.h"
@@ -172,15 +173,17 @@
 	destroy_unrefed(TRUE);
 }
 
-static enum mail_cache_field get_cache_fields(const char *fields)
+static void set_cache_fields(const char *fields,
+			     enum mail_cache_decision_type dest[32],
+			     enum mail_cache_decision_type dec)
 {
-	static enum mail_cache_field field_masks[] = {
+	static enum mail_cache_field field_enums[] = {
 		MAIL_CACHE_SENT_DATE,
 		MAIL_CACHE_RECEIVED_DATE,
 		MAIL_CACHE_VIRTUAL_FULL_SIZE,
 		MAIL_CACHE_BODY,
 		MAIL_CACHE_BODYSTRUCTURE,
-		MAIL_CACHE_MESSAGEPART,
+		MAIL_CACHE_MESSAGEPART
 	};
 	static const char *field_names[] = {
 		"sent_date",
@@ -193,17 +196,15 @@
 	};
 
 	const char *const *arr;
-	enum mail_cache_field ret;
 	int i;
 
 	if (fields == NULL || *fields == '\0')
-		return 0;
+		return;
 
-	ret = 0;
 	for (arr = t_strsplit_spaces(fields, " ,"); *arr != NULL; arr++) {
 		for (i = 0; field_names[i] != NULL; i++) {
 			if (strcasecmp(field_names[i], *arr) == 0) {
-				ret |= field_masks[i];
+				dest[field_enums[i]] = dec;
 				break;
 			}
 		}
@@ -212,34 +213,22 @@
 				*arr);
 		}
 	}
-
-	return ret;
 }
 
-static enum mail_cache_field get_default_cache_fields(void)
-{
-	static enum mail_cache_field ret = 0;
-	static int ret_set = FALSE;
-
-	if (ret_set)
-		return ret;
-
-	ret = get_cache_fields(getenv("MAIL_CACHE_FIELDS"));
-	ret_set = TRUE;
-	return ret;
-}
-
-static enum mail_cache_field get_never_cache_fields(void)
+static const enum mail_cache_decision_type *get_default_cache_decisions(void)
 {
-	static enum mail_cache_field ret = 0;
-	static int ret_set = FALSE;
+	static enum mail_cache_decision_type dec[32];
+	static int dec_set = FALSE;
 
-	if (ret_set)
-		return ret;
+	if (dec_set)
+		return dec;
 
-	ret = get_cache_fields(getenv("MAIL_NEVER_CACHE_FIELDS"));
-	ret_set = TRUE;
-	return ret;
+	memset(dec, 0, sizeof(dec));
+	set_cache_fields(getenv("MAIL_CACHE_FIELDS"), dec,
+			 MAIL_CACHE_DECISION_TEMP);
+	set_cache_fields(getenv("MAIL_NEVER_CACHE_FIELDS"), dec,
+			 MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED);
+	return dec;
 }
 
 void index_storage_lock_notify(struct index_mailbox *ibox,
@@ -339,9 +328,7 @@
 
 		ibox->cache = mail_index_get_cache(index);
 		mail_cache_set_defaults(ibox->cache,
-					get_default_cache_fields(),
-					get_never_cache_fields());
-
+					get_default_cache_decisions());
 		ibox->view = mail_index_view_open(index);
 		return ibox;
 	} while (0);



More information about the dovecot-cvs mailing list