[dovecot-cvs] dovecot/src/lib-storage/index index-mail-headers.c, 1.26, 1.27 index-mail.c, 1.43, 1.44 index-mail.h, 1.17, 1.18 index-search.c, 1.91, 1.92 index-storage.c, 1.57, 1.58 index-storage.h, 1.73, 1.74

cras at dovecot.org cras at dovecot.org
Sun Jul 18 05:25:10 EEST 2004


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

Modified Files:
	index-mail-headers.c index-mail.c index-mail.h index-search.c 
	index-storage.c index-storage.h 
Log Message:
Header caching redesigned. New design allows caching decisions per field, so
they can be divided to temporary/permanent. Cached headers are now always
returned in original order, old code didn't guarantee it. Some other caching
changes. (still missing code to store changes in caching decisions)



Index: index-mail-headers.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail-headers.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- index-mail-headers.c	9 Jul 2004 00:10:37 -0000	1.26
+++ index-mail-headers.c	18 Jul 2004 02:25:07 -0000	1.27
@@ -1,45 +1,12 @@
 /* Copyright (C) 2003 Timo Sirainen */
 
-/*
-   Headers are stored in 1-4 pieces. There's a list of header names that each
-   piece contains, so if piece doesn't actually contain some listed header,
-   it's known not to exist in the mail at all.
-
-   Header name lists are stored in sorted order, so we can use binary
-   searching.
-
-   We have to be able to do 3 things:
[...1085 lines suppressed...]
+
+		/* @UNSAFE */
+		for (i = 0; i < size; i++) {
+			ctx->idx[i] = fields[i].idx;
+			ctx->name[i] = p_strdup(pool, sorted_headers[i]);
+		}
 	}
-	data->header_save = FALSE;
+
+	t_pop();
+	return &ctx->ctx;
+}
+
+void index_header_lookup_deinit(struct mailbox_header_lookup_ctx *_ctx)
+{
+	struct index_header_lookup_ctx *ctx =
+		(struct index_header_lookup_ctx *)_ctx;
+
+	pool_unref(ctx->pool);
 }

Index: index-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- index-mail.c	11 Jul 2004 21:04:46 -0000	1.43
+++ index-mail.c	18 Jul 2004 02:25:07 -0000	1.44
@@ -13,6 +13,22 @@
 #include "index-storage.h"
 #include "index-mail.h"
 
+struct mail_cache_field cache_fields[MAIL_CACHE_FIELD_COUNT] = {
+	{ "index.flags", 0, MAIL_CACHE_FIELD_BITMASK,
+	  sizeof(uint32_t), 0, 0, 0 },
+	{ "date.sent", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
+	  sizeof(struct mail_sent_date), 0, 0, 0 },
+	{ "date.received", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
+	  sizeof(time_t), 0, 0, 0 },
+	{ "size.virtual", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
+	  sizeof(uoff_t), 0, 0, 0 },
+	{ "imap.body", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 },
+	{ "imap.bodystructure", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 },
+	{ "imap.envelope", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 },
+	{ "mime.parts", 0, MAIL_CACHE_FIELD_VARIABLE_SIZE, 0, 0, 0, 0 },
+	{ "mail.uid", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 }
+};
+
 static void index_mail_parse_body(struct index_mail *mail, int need_parts);
 
 static struct message_part *get_cached_parts(struct index_mail *mail)
@@ -25,8 +41,8 @@
 	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) <= 0) {
+			mail->data.seq,
+			cache_fields[MAIL_CACHE_MESSAGEPART].idx) <= 0) {
 		t_pop();
 		return NULL;
 	}
@@ -56,13 +72,14 @@
 }
 
 const char *index_mail_get_cached_string(struct index_mail *mail,
-					 enum mail_cache_field field)
+					 enum index_cache_field field)
 {
 	string_t *str;
 
 	str = str_new(mail->pool, 32);
-	if (mail_cache_lookup_string_field(mail->trans->cache_view, str,
-					   mail->data.seq, field) <= 0) {
+	if (mail_cache_lookup_field(mail->trans->cache_view, str,
+				    mail->data.seq,
+				    cache_fields[field].idx) <= 0) {
 		p_free(mail->pool, str);
 		return NULL;
 	}
@@ -71,7 +88,7 @@
 }
 
 static int index_mail_get_fixed_field(struct index_mail *mail,
-				      enum mail_cache_field field,
+				      enum index_cache_field field,
 				      void *data, size_t data_size)
 {
 	buffer_t *buf;
@@ -80,7 +97,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) <= 0) {
+				    mail->data.seq,
+				    cache_fields[field].idx) <= 0) {
 		ret = FALSE;
 	} else {
 		i_assert(buffer_get_used_size(buf) == data_size);
@@ -92,11 +110,12 @@
 }
 
 uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
-				    enum mail_cache_field field)
+				    enum index_cache_field field)
 {
 	uoff_t uoff;
 
-	if (!index_mail_get_fixed_field(mail, field, &uoff, sizeof(uoff)))
+	if (!index_mail_get_fixed_field(mail, cache_fields[field].idx,
+					&uoff, sizeof(uoff)))
 		uoff = (uoff_t)-1;
 
 	return uoff;
@@ -207,7 +226,8 @@
 			}
                         data->sent_date.timezone = tz;
 			mail_cache_add(mail->trans->cache_trans, mail->data.seq,
-				       MAIL_CACHE_SENT_DATE, &data->sent_date,
+				       cache_fields[MAIL_CACHE_SENT_DATE].idx,
+				       &data->sent_date,
 				       sizeof(data->sent_date));
 		}
 	}
@@ -258,9 +278,9 @@
 	return data->size;
 }
 
-static void parse_bodystructure_header(struct message_part *part,
-				       struct message_header_line *hdr,
-				       void *context)
+static void parse_bodystructure_part_header(struct message_part *part,
+					    struct message_header_line *hdr,
+					    void *context)
 {
 	pool_t pool = context;
 
@@ -281,11 +301,12 @@
 
 	i_stream_seek(data->stream, data->hdr_size.physical_size);
 
-	if (data->bodystructure_header_parsed) {
+	if (data->save_bodystructure_body) {
 		/* bodystructure header is parsed, we want the body's mime
 		   headers too */
+		i_assert(!data->save_bodystructure_header);
 		message_parser_parse_body(data->parser_ctx,
-					  parse_bodystructure_header,
+					  parse_bodystructure_part_header,
 					  NULL, mail->pool);
 	} else {
 		message_parser_parse_body(data->parser_ctx, NULL, NULL, NULL);
@@ -307,7 +328,7 @@
 		}
 
 		/* update cache_flags */
-		cache_flags =
+		/*FIXME:cache_flags =
 			mail_cache_get_record_flags(mail->trans->cache_view,
 						    mail->data.seq);
 		if (mail->mail.has_nuls)
@@ -317,16 +338,16 @@
 
 		(void)mail_cache_update_record_flags(mail->trans->cache_view,
 						     mail->data.seq,
-						     cache_flags);
+						     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)
+			cache_fields[MAIL_CACHE_MESSAGEPART].idx) != 0)
 		return;
 
 	decision = mail_cache_field_get_decision(mail->ibox->cache,
-						 MAIL_CACHE_MESSAGEPART);
+				cache_fields[MAIL_CACHE_MESSAGEPART].idx);
 	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)) {
@@ -337,7 +358,8 @@
 
 		buf_data = buffer_get_data(buffer, &buf_size);
 		mail_cache_add(mail->trans->cache_trans, mail->data.seq,
-			       MAIL_CACHE_MESSAGEPART, buf_data, buf_size);
+			       cache_fields[MAIL_CACHE_MESSAGEPART].idx,
+			       buf_data, buf_size);
 		t_pop();
 	}
 }
@@ -378,15 +400,17 @@
 }
 
 static void index_mail_parse_bodystructure(struct index_mail *mail,
-					   enum mail_cache_field field)
+					   enum index_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 (data->save_bodystructure_header || !data->save_bodystructure_body) {
+		/* we haven't parsed the header yet */
+		data->save_bodystructure_header = TRUE;
+		data->save_bodystructure_body = TRUE;
 		if (!index_mail_parse_headers(mail))
 			return;
 	}
@@ -394,18 +418,18 @@
 	if (data->parts != NULL) {
 		i_assert(data->parts->next == NULL);
 		message_parse_from_parts(data->parts->children, data->stream,
-					 parse_bodystructure_header,
+					 parse_bodystructure_part_header,
 					 mail->pool);
 	} else {
 		index_mail_parse_body(mail, FALSE);
 	}
 
 	dec = mail_cache_field_get_decision(mail->ibox->cache,
-					    MAIL_CACHE_BODYSTRUCTURE);
+				cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx);
 	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) {
+			cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) == 0)) {
 		str = str_new(mail->pool, 128);
 		imap_bodystructure_write(data->parts, str, TRUE);
 		data->bodystructure = str_c(str);
@@ -413,17 +437,18 @@
 		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);
+				cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx,
+				str_c(str), str_len(str)+1);
 			bodystructure_cached = TRUE;
 		}
 	}
 
-	dec = mail_cache_field_get_decision(mail->ibox->cache, MAIL_CACHE_BODY);
+	dec = mail_cache_field_get_decision(mail->ibox->cache,
+					    cache_fields[MAIL_CACHE_BODY].idx);
 	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) {
+				     cache_fields[MAIL_CACHE_BODY].idx) == 0)) {
 		str = str_new(mail->pool, 128);
 		imap_bodystructure_write(data->parts, str, FALSE);
 		data->body = str_c(str);
@@ -431,7 +456,7 @@
 		if (!bodystructure_cached && dec !=
 		    (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
 			mail_cache_add(mail->trans->cache_trans, data->seq,
-				       MAIL_CACHE_BODY,
+				       cache_fields[MAIL_CACHE_BODY].idx,
 				       str_c(str), str_len(str)+1);
 		}
 	}
@@ -455,16 +480,16 @@
 		      depending on what we want cached */
 
 		str = str_new(mail->pool, 128);
-		if (mail_cache_lookup_string_field(mail->trans->cache_view,
-						   str, mail->data.seq,
-						   MAIL_CACHE_BODY) > 0) {
+		if (mail_cache_lookup_field(mail->trans->cache_view, str,
+				mail->data.seq,
+				cache_fields[MAIL_CACHE_BODY].idx) > 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);
+		if (mail_cache_lookup_field(mail->trans->cache_view, str,
+			      mail->data.seq,
+			      cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) > 0) {
+			data->bodystructure = p_strdup(mail->pool, str_c(str));
 			str_truncate(str, 0);
 
 			if (imap_body_parse_from_bodystructure(
@@ -474,10 +499,10 @@
 			}
 
 			/* broken, continue.. */
-			data->bodystructure = NULL;
 			mail_cache_set_corrupted(mail->ibox->cache,
 				"Corrupted BODYSTRUCTURE for mail %u",
 				mail->mail.uid);
+			data->bodystructure = NULL;
 		}
 		p_free(mail->pool, str);
 
@@ -488,9 +513,9 @@
 			return data->bodystructure;
 
 		str = str_new(mail->pool, 128);
-		if (mail_cache_lookup_string_field(mail->trans->cache_view,
-					str, mail->data.seq,
-					MAIL_CACHE_BODYSTRUCTURE) > 0) {
+		if (mail_cache_lookup_field(mail->trans->cache_view, str,
+			      mail->data.seq,
+			      cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) > 0) {
 			data->bodystructure = str_c(str);
 			return data->bodystructure;
 		}
@@ -499,11 +524,8 @@
 		index_mail_parse_bodystructure(mail, MAIL_CACHE_BODYSTRUCTURE);
 		return data->bodystructure;
 	case MAIL_FETCH_IMAP_ENVELOPE:
-		if (data->envelope != NULL)
-			return data->envelope;
-
-		data->save_envelope = TRUE;
-		(void)_mail->get_header(_mail, "Date");
+		if (data->envelope == NULL)
+			index_mail_headers_get_envelope(mail);
 		return data->envelope;
 	case MAIL_FETCH_FROM_ENVELOPE:
 		return NULL;
@@ -523,8 +545,10 @@
 void index_mail_init(struct index_transaction_context *t,
 		     struct index_mail *mail,
 		     enum mail_fetch_field wanted_fields,
-		     const char *const wanted_headers[])
+		     struct mailbox_header_lookup_ctx *_wanted_headers)
 {
+	struct index_header_lookup_ctx *wanted_headers =
+		(struct index_header_lookup_ctx *)_wanted_headers;
 	const struct mail_index_header *hdr;
 	int ret;
 
@@ -541,16 +565,14 @@
 	mail->trans = t;
 	mail->wanted_fields = wanted_fields;
 	mail->wanted_headers = wanted_headers;
-
-	index_mail_headers_init(mail);
 }
 
 static void index_mail_close(struct index_mail *mail)
 {
 	if (mail->data.stream != NULL)
 		i_stream_unref(mail->data.stream);
-
-	index_mail_headers_close(mail);
+	if (mail->data.filter_stream != NULL)
+		i_stream_unref(mail->data.filter_stream);
 }
 
 int index_mail_next(struct index_mail *mail, uint32_t seq)
@@ -564,13 +586,12 @@
 		return -1;
 	}
 
-	t_push();
-
 	index_mail_close(mail);
+
 	memset(data, 0, sizeof(*data));
 	p_clear(mail->pool);
 
-	cache_flags = mail_cache_get_record_flags(mail->trans->cache_view, seq);
+	cache_flags = 0;//FIXME:mail_cache_get_record_flags(mail->trans->cache_view, seq);
 
 	mail->mail.seq = seq;
 	mail->mail.uid = rec->uid;
@@ -583,6 +604,8 @@
 	data->size = (uoff_t)-1;
 	data->received_date = data->sent_date.time = (time_t)-1;
 
+	t_push();
+
 	/* if some wanted fields are cached, get them */
 	if (mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS)
 		data->parts = get_cached_parts(mail);
@@ -611,20 +634,20 @@
 			data->parts = get_cached_parts(mail);
 		data->open_mail = TRUE;
 		data->parse_header = data->parts == NULL;
-		data->bodystructure_header_want = TRUE;
+		data->save_bodystructure_header = TRUE;
+		data->save_bodystructure_body = 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);
 		data->open_mail = TRUE;
 		data->parse_header = data->parts == NULL;
-                data->bodystructure_header_want = TRUE;
+		data->save_bodystructure_header = TRUE;
+		data->save_bodystructure_body = TRUE;
 	} else if (mail->wanted_fields & (MAIL_FETCH_STREAM_HEADER |
 					  MAIL_FETCH_STREAM_BODY))
 		data->open_mail = TRUE;
 
-        index_mail_headers_init_next(mail);
-
 	if ((mail->wanted_fields & MAIL_FETCH_DATE) &&
 	    data->sent_date.time == (time_t)-1)
 		data->save_sent_date = TRUE;
@@ -641,9 +664,14 @@
 	if (mail->ibox->mail_deinit != NULL)
                 mail->ibox->mail_deinit(mail);
 
-	t_push();
 	index_mail_close(mail);
-	t_pop();
+
+	if (mail->header_data != NULL)
+		buffer_free(mail->header_data);
+	if (mail->header_lines != NULL)
+		buffer_free(mail->header_lines);
+	if (mail->header_match != NULL)
+		buffer_free(mail->header_match);
 
 	pool_unref(mail->pool);
 	memset(mail, 0, sizeof(*mail));

Index: index-mail.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- index-mail.h	9 Jul 2004 00:10:38 -0000	1.17
+++ index-mail.h	18 Jul 2004 02:25:07 -0000	1.18
@@ -5,6 +5,50 @@
 #include "mail-cache.h"
 #include "mail-storage-private.h"
 
+enum index_cache_field {
+	/* fixed size fields */
+	MAIL_CACHE_INDEX_FLAGS = 0,
+	MAIL_CACHE_SENT_DATE,
+	MAIL_CACHE_RECEIVED_DATE,
+	MAIL_CACHE_VIRTUAL_FULL_SIZE,
+
+	/* variable sized field */
+	MAIL_CACHE_BODY,
+	MAIL_CACHE_BODYSTRUCTURE,
+	MAIL_CACHE_ENVELOPE,
+	MAIL_CACHE_MESSAGEPART,
+	MAIL_CACHE_UID_STRING,
+
+	MAIL_CACHE_FIELD_COUNT
+};
+extern struct mail_cache_field cache_fields[MAIL_CACHE_FIELD_COUNT];
+
+enum mail_cache_record_flag {
+	/* If binary flags are set, it's not checked whether mail is
+	   missing CRs. So this flag may be set as an optimization for
+	   regular non-binary mails as well if it's known that it contains
+	   valid CR+LF line breaks. */
+	MAIL_INDEX_FLAG_BINARY_HEADER		= 0x0001,
+	MAIL_INDEX_FLAG_BINARY_BODY		= 0x0002,
+
+	/* Mail header or body is known to contain NUL characters. */
+	MAIL_INDEX_FLAG_HAS_NULS		= 0x0004,
+	/* Mail header or body is known to not contain NUL characters. */
+	MAIL_INDEX_FLAG_HAS_NO_NULS		= 0x0008
+};
+
+struct mail_sent_date {
+	time_t time;
+	int32_t timezone;
+};
+
+struct index_mail_line {
+	unsigned int field_idx;
+	uint32_t start_pos, end_pos;
+	uint32_t line_num;
+	unsigned int cache:1;
+};
+
 struct message_header_line;
 
 struct index_mail_data {
@@ -13,13 +57,8 @@
 	uoff_t size;
 
 	struct mail_sent_date sent_date;
-
-	buffer_t *headers;
-	string_t *header_data;
-	int header_data_cached, header_data_cached_contiguous;
-	size_t header_data_uncached_offset;
-	struct istream *header_stream;
-	int header_save_idx;
+	struct index_mail_line parse_line;
+	uint32_t parse_line_num;
 
 	struct message_part *parts;
 	const char *envelope, *body, *bodystructure, *uid_string;
@@ -28,24 +67,20 @@
 	uint32_t seq;
 	const struct mail_index_record *rec;
 
-	struct istream *stream;
+	struct istream *stream, *filter_stream;
 	struct message_size hdr_size, body_size;
 	struct message_parser_ctx *parser_ctx;
 	int parsing_count;
 
 	unsigned int parse_header:1;
-	unsigned int bodystructure_header_want:1;
-	unsigned int bodystructure_header_parse:1;
-	unsigned int bodystructure_header_parsed:1;
 	unsigned int save_envelope:1;
 	unsigned int save_sent_date:1;
+	unsigned int save_bodystructure_header:1;
+	unsigned int save_bodystructure_body:1;
 	unsigned int hdr_size_set:1;
 	unsigned int body_size_set:1;
-	unsigned int deleted:1;
-	unsigned int header_data_cached_partial:1;
-	unsigned int header_fully_parsed:1;
-	unsigned int header_save:1;
 	unsigned int open_mail:1;
+	unsigned int deleted:1;
 };
 
 struct index_mail {
@@ -55,37 +90,37 @@
 	pool_t pool;
 	struct index_mailbox *ibox;
 	struct index_transaction_context *trans;
-	unsigned int expunge_counter;
-	buffer_t *header_buf;
 	uint32_t uid_validity;
 
 	enum mail_fetch_field wanted_fields;
-	const char *const *wanted_headers;
-	int wanted_headers_idx;
+	struct index_header_lookup_ctx *wanted_headers;
+
+	/* per-mail variables, here for performance reasons: */
+	string_t *header_data;
+	buffer_t *header_lines;
+	buffer_t *header_match;
+	uint8_t header_match_value;
 };
 
 void index_mail_init(struct index_transaction_context *t,
 		     struct index_mail *mail,
 		     enum mail_fetch_field wanted_fields,
-		     const char *const wanted_headers[]);
+		     struct mailbox_header_lookup_ctx *wanted_headers);
 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,
-				  const char *const headers[]);
+				  struct mailbox_header_lookup_ctx *headers);
 int index_mail_parse_header(struct message_part *part,
 			    struct message_header_line *hdr,
 			    struct index_mail *mail);
-
 int index_mail_parse_headers(struct index_mail *mail);
-
-void index_mail_headers_init(struct index_mail *mail);
-void index_mail_headers_init_next(struct index_mail *mail);
-void index_mail_headers_close(struct index_mail *mail);
+void index_mail_headers_get_envelope(struct index_mail *mail);
 
 const char *index_mail_get_header(struct mail *_mail, const char *field);
-struct istream *index_mail_get_headers(struct mail *_mail,
-				       const char *const minimum_fields[]);
+struct istream *
+index_mail_get_headers(struct mail *_mail,
+		       struct mailbox_header_lookup_ctx *headers);
 
 const struct mail_full_flags *index_mail_get_flags(struct mail *_mail);
 const struct message_part *index_mail_get_parts(struct mail *_mail);
@@ -104,9 +139,9 @@
 int index_mail_expunge(struct mail *mail);
 
 const char *index_mail_get_cached_string(struct index_mail *mail,
-					 enum mail_cache_field field);
+					 enum index_cache_field field);
 uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
-				    enum mail_cache_field field);
+				    enum index_cache_field field);
 uoff_t index_mail_get_cached_virtual_size(struct index_mail *mail);
 time_t index_mail_get_cached_received_date(struct index_mail *mail);
 

Index: index-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -d -r1.91 -r1.92
--- index-search.c	8 Jul 2004 20:26:16 -0000	1.91
+++ index-search.c	18 Jul 2004 02:25:07 -0000	1.92
@@ -444,7 +444,7 @@
 	if (hdr->eoh)
 		return;
 
-	index_mail_parse_header(part, hdr, &ctx->index_context->imail);
+	index_mail_parse_header(NULL, hdr, &ctx->index_context->imail);
 
 	if (ctx->custom_header || strcasecmp(hdr->name, "Date") == 0) {
 		ctx->hdr = hdr;
@@ -482,6 +482,7 @@
 				 struct index_search_context *ctx)
 {
 	struct istream *input;
+	struct mailbox_header_lookup_ctx *headers_ctx;
 	const char *const *headers;
 	int have_headers, have_body;
 
@@ -496,20 +497,33 @@
 		if (have_body)
 			headers = NULL;
 
-		input = headers == NULL ?
-			ctx->mail->get_stream(ctx->mail, NULL, NULL) :
-			ctx->mail->get_headers(ctx->mail, headers);
-		if (input == NULL)
-			return FALSE;
+		if (headers == NULL) {
+			headers_ctx = NULL;
+			input = ctx->mail->get_stream(ctx->mail, NULL, NULL);
+			if (input == NULL)
+				return FALSE;
+		} else {
+			/* FIXME: do this once in init */
+			headers_ctx =
+				mailbox_header_lookup_init(&ctx->ibox->box,
+							   headers);
+			input = ctx->mail->get_headers(ctx->mail, headers_ctx);
+			if (input == NULL) {
+				mailbox_header_lookup_deinit(headers_ctx);
+				return FALSE;
+			}
+		}
 
 		memset(&hdr_ctx, 0, sizeof(hdr_ctx));
 		hdr_ctx.index_context = ctx;
 		hdr_ctx.custom_header = TRUE;
 		hdr_ctx.args = args;
 
-		index_mail_parse_header_init(&ctx->imail, headers);
+		index_mail_parse_header_init(&ctx->imail, headers_ctx);
 		message_parse_header(NULL, input, NULL,
 				     search_header, &hdr_ctx);
+		if (headers_ctx != NULL)
+			mailbox_header_lookup_deinit(headers_ctx);
 	} else {
 		struct message_size hdr_size;
 
@@ -720,7 +734,7 @@
 			  const char *charset, struct mail_search_arg *args,
 			  const enum mail_sort_type *sort_program,
 			  enum mail_fetch_field wanted_fields,
-			  const char *const wanted_headers[])
+			  struct mailbox_header_lookup_ctx *wanted_headers)
 {
 	struct index_transaction_context *t =
 		(struct index_transaction_context *)_t;

Index: index-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- index-storage.c	11 Jul 2004 21:09:31 -0000	1.57
+++ index-storage.c	18 Jul 2004 02:25:07 -0000	1.58
@@ -11,6 +11,8 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
+#define DEFAULT_NEVER_CACHE_FIELDS "imap.envelope"
+
 /* How many seconds to keep index opened for reuse after it's been closed */
 #define INDEX_CACHE_TIMEOUT 10
 /* How many closed indexes to keep */
@@ -173,28 +175,9 @@
 	destroy_unrefed(TRUE);
 }
 
-static void set_cache_fields(const char *fields,
-			     enum mail_cache_decision_type dest[32],
-			     enum mail_cache_decision_type dec)
+static void set_cache_decisions(const char *fields,
+				enum mail_cache_decision_type dec)
 {
-	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
-	};
-	static const char *field_names[] = {
-		"sent_date",
-		"received_date",
-		"virtual_size",
-		"body",
-		"bodystructure",
-		"messagepart",
-		NULL
-	};
-
 	const char *const *arr;
 	int i;
 
@@ -202,33 +185,34 @@
 		return;
 
 	for (arr = t_strsplit_spaces(fields, " ,"); *arr != NULL; arr++) {
-		for (i = 0; field_names[i] != NULL; i++) {
-			if (strcasecmp(field_names[i], *arr) == 0) {
-				dest[field_enums[i]] = dec;
+		for (i = 0; i < MAIL_CACHE_FIELD_COUNT; i++) {
+			if (strcasecmp(cache_fields[i].name, *arr) == 0) {
+				cache_fields[i].decision = dec;
 				break;
 			}
 		}
-		if (field_names[i] == NULL) {
+		if (i == MAIL_CACHE_FIELD_COUNT) {
 			i_error("Invalid cache field name '%s', ignoring ",
 				*arr);
 		}
 	}
 }
 
-static const enum mail_cache_decision_type *get_default_cache_decisions(void)
+static void index_cache_register_defaults(struct mail_cache *cache)
 {
-	static enum mail_cache_decision_type dec[32];
-	static int dec_set = FALSE;
+	const char *never_env;
 
-	if (dec_set)
-		return dec;
+	never_env = getenv("MAIL_NEVER_CACHE_FIELDS");
+	if (never_env == NULL)
+		never_env = DEFAULT_NEVER_CACHE_FIELDS;
 
-	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;
+	set_cache_decisions(getenv("MAIL_CACHE_FIELDS"),
+			    MAIL_CACHE_DECISION_TEMP);
+	set_cache_decisions(never_env, MAIL_CACHE_DECISION_NO |
+			    MAIL_CACHE_DECISION_FORCED);
+
+	mail_cache_register_fields(cache, cache_fields,
+				   MAIL_CACHE_FIELD_COUNT);
 }
 
 void index_storage_lock_notify(struct index_mailbox *ibox,
@@ -327,8 +311,7 @@
 			break;
 
 		ibox->cache = mail_index_get_cache(index);
-		mail_cache_set_defaults(ibox->cache,
-					get_default_cache_decisions());
+		index_cache_register_defaults(ibox->cache);
 		ibox->view = mail_index_view_open(index);
 		return ibox;
 	} while (0);

Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- index-storage.h	12 Jul 2004 11:35:51 -0000	1.73
+++ index-storage.h	18 Jul 2004 02:25:07 -0000	1.74
@@ -181,6 +181,10 @@
 int index_storage_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2,
 			   uint32_t *seq1_r, uint32_t *seq2_r);
 
+struct mailbox_header_lookup_ctx *
+index_header_lookup_init(struct mailbox *box, const char *const headers[]);
+void index_header_lookup_deinit(struct mailbox_header_lookup_ctx *ctx);
+
 int index_storage_search_get_sorting(struct mailbox *box,
 				     enum mail_sort_type *sort_program);
 struct mail_search_context *
@@ -188,7 +192,7 @@
 			  const char *charset, struct mail_search_arg *args,
 			  const enum mail_sort_type *sort_program,
 			  enum mail_fetch_field wanted_fields,
-			  const char *const wanted_headers[]);
+			  struct mailbox_header_lookup_ctx *wanted_headers);
 int index_storage_search_deinit(struct mail_search_context *ctx);
 struct mail *index_storage_search_next(struct mail_search_context *ctx);
 



More information about the dovecot-cvs mailing list