[dovecot-cvs] dovecot/src/lib-storage/index index-mail-headers.c,1.1,1.2 index-mail.c,1.17,1.18 index-mail.h,1.7,1.8

cras at procontrol.fi cras at procontrol.fi
Wed Aug 20 05:41:33 EEST 2003


Update of /home/cvs/dovecot/src/lib-storage/index
In directory danu:/tmp/cvs-serv282/lib-storage/index

Modified Files:
	index-mail-headers.c index-mail.c index-mail.h 
Log Message:
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
headers only once. If body contains multiple MIME parts, cache the internal
MIME structure so BODY[part] fetching doesn't need to parse it again.



Index: index-mail-headers.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail-headers.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- index-mail-headers.c	18 Aug 2003 03:24:37 -0000	1.1
+++ index-mail-headers.c	20 Aug 2003 01:41:30 -0000	1.2
@@ -40,6 +40,7 @@
 #include "str.h"
 #include "message-date.h"
 #include "imap-envelope.h"
+#include "imap-bodystructure.h"
 #include "index-storage.h"
 #include "index-mail.h"
 
@@ -258,13 +259,19 @@
 	}
 }
 
-void index_mail_parse_header(struct message_part *part __attr_unused__,
+void index_mail_parse_header(struct message_part *part,
 			     struct message_header_line *hdr, void *context)
 {
 	struct index_mail *mail = context;
 	struct index_mail_data *data = &mail->data;
 	struct cached_header *cached_hdr;
 
+	if (data->bodystructure_header_parse)
+		imap_bodystructure_parse_header(mail->pool, part, hdr);
+
+	if (part != NULL && part->parent != NULL)
+		return;
+
 	if (data->save_envelope) {
 		imap_envelope_parse_header(mail->pool,
 					   &data->envelope_data, hdr);
@@ -413,7 +420,7 @@
 	return TRUE;
 }
 
-int index_mail_parse_headers(struct index_mail *mail)
+int index_mail_parse_headers(struct index_mail *mail, int get_parts)
 {
 	struct mail_cache *cache = mail->ibox->index->cache;
 	struct index_mail_data *data = &mail->data;
@@ -481,9 +488,42 @@
 		data->header_save_idx = idx;
 	}
 
+	data->bodystructure_header_parse = data->bodystructure_header_want;
 	index_mail_parse_header_init(mail, NULL);
-	message_parse_header(NULL, data->stream, &data->hdr_size,
-			     index_mail_parse_header, mail);
+
+	if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0)
+		get_parts = TRUE;
+	if (data->parts != NULL)
+		get_parts = FALSE;
+
+	if (!data->bodystructure_header_want && !get_parts) {
+		message_parse_header(data->parts, data->stream, &data->hdr_size,
+				     index_mail_parse_header, mail);
+	} else if (data->parts == NULL) {
+		data->parts = message_parse(mail->pool, data->stream,
+					    index_mail_parse_header, mail);
+	} else {
+		message_parse_from_parts(data->parts, data->stream,
+					 index_mail_parse_header, mail);
+	}
+
+	if (data->bodystructure_header_want) {
+		data->bodystructure_header_want = FALSE;
+		data->bodystructure_header_parse = FALSE;
+		data->bodystructure_header_parsed = TRUE;
+	}
+
+	if (get_parts) {
+		/* 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;
+		}
+	}
+
 	data->parse_header = FALSE;
 	data->hdr_size_set = TRUE;
 	data->header_fully_parsed = TRUE;
@@ -514,7 +554,7 @@
 		}
 
 		if (idx < 0) {
-			index_mail_parse_headers(mail);
+			index_mail_parse_headers(mail, FALSE);
 
 			/* might have been moved in memory, get it again */
 			hdr = cached_header_find(mail, field, NULL);
@@ -567,7 +607,7 @@
 		}
 
 		if (!all_saved)
-			index_mail_parse_headers(mail);
+			index_mail_parse_headers(mail, FALSE);
 	}
 
 	return i_stream_create_from_data(mail->pool,

Index: index-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- index-mail.c	18 Aug 2003 03:24:37 -0000	1.17
+++ index-mail.c	20 Aug 2003 01:41:30 -0000	1.18
@@ -210,14 +210,29 @@
 	return &data->flags;
 }
 
-static const struct message_part *get_parts(struct mail *_mail)
+static void cache_parts(struct index_mail *mail)
 {
-	struct index_mail *mail = (struct index_mail *) _mail;
-	struct index_mail_data *data = &mail->data;
 	buffer_t *buffer;
 	const void *buf_data;
 	size_t buf_size;
 
+	if (!index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART))
+		return;
+
+	t_push();
+	buffer = buffer_create_dynamic(data_stack_pool, 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);
+	t_pop();
+}
+
+static const struct message_part *get_parts(struct mail *_mail)
+{
+	struct index_mail *mail = (struct index_mail *) _mail;
+	struct index_mail_data *data = &mail->data;
+
 	if (data->parts != NULL)
 		return data->parts;
 
@@ -227,32 +242,10 @@
 			return data->parts;
 	}
 
-	if (!index_mail_open_stream(mail, 0))
+	if (!index_mail_parse_headers(mail, TRUE))
 		return NULL;
 
-	data->parts = message_parse(mail->pool, data->stream,
-				    index_mail_parse_header, mail);
-
-	/* we know the NULs now, update them */
-	if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
-		_mail->has_nuls = TRUE;
-		_mail->has_no_nuls = FALSE;
-	} else {
-		_mail->has_nuls = FALSE;
-		_mail->has_no_nuls = TRUE;
-	}
-
-	if (index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART)) {
-		t_push();
-		buffer = buffer_create_dynamic(data_stack_pool,
-					       1024, (size_t)-1);
-		message_part_serialize(data->parts, buffer);
-
-		buf_data = buffer_get_data(buffer, &buf_size);
-		index_mail_cache_add(mail, MAIL_CACHE_MESSAGEPART,
-				     buf_data, buf_size);
-		t_pop();
-	}
+        cache_parts(mail);
 	return data->parts;
 }
 
@@ -398,7 +391,7 @@
 	if (!get_msgpart_sizes(mail)) {
 		/* this gives us header size for free */
 		if (data->parse_header)
-			index_mail_parse_headers(mail);
+			index_mail_parse_headers(mail, FALSE);
 	}
 
 	hdr_size = data->hdr_size_set ?
@@ -534,16 +527,15 @@
 			return data->body;
 		}
 
-		if (!index_mail_open_stream(mail, 0))
-			return NULL;
-
-		if (data->parts == NULL)
-			data->parts = get_cached_parts(mail);
+		if (!data->bodystructure_header_parsed) {
+			data->bodystructure_header_want = TRUE;
+			if (!index_mail_parse_headers(mail, FALSE))
+				return NULL;
+		}
 
 		t_push();
-		str = p_strdup(mail->pool, imap_part_get_bodystructure(
-				mail->pool, &data->parts, data->stream,
-				field == MAIL_FETCH_IMAP_BODYSTRUCTURE));
+                str = p_strdup(mail->pool, imap_bodystructure_parse_finish(
+			data->parts, field == MAIL_FETCH_IMAP_BODYSTRUCTURE));
 		t_pop();
 
 		/* should never fail */
@@ -553,6 +545,12 @@
 			MAIL_CACHE_BODYSTRUCTURE : MAIL_CACHE_BODY;
 		index_mail_cache_add(mail, cache_field, str, strlen(str)+1);
 
+		if (data->parts->children != NULL) {
+			/* cache the message parts only if this is a
+			   multipart message. it's pretty useless otherwise. */
+			cache_parts(mail);
+		}
+
 		if (field == MAIL_FETCH_IMAP_BODYSTRUCTURE)
 			data->bodystructure = str;
 		else
@@ -671,12 +669,14 @@
 			data->parts = get_cached_parts(mail);
 		open_mail = TRUE;
 		data->parse_header = data->parts == NULL;
+                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->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;

Index: index-mail.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- index-mail.h	18 Aug 2003 03:24:37 -0000	1.7
+++ index-mail.h	20 Aug 2003 01:41:30 -0000	1.8
@@ -23,7 +23,7 @@
 
 	struct message_part *parts;
 	const char *envelope, *body, *bodystructure;
-        struct message_part_envelope_data *envelope_data;
+	struct message_part_envelope_data *envelope_data;
 
 	struct mail_index_record *rec;
 	unsigned int idx_seq;
@@ -32,6 +32,9 @@
         struct message_size hdr_size, body_size;
 
 	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 hdr_size_set:1;
@@ -73,7 +76,7 @@
 			  const void *data, size_t size);
 
 int index_mail_open_stream(struct index_mail *mail, uoff_t position);
-int index_mail_parse_headers(struct index_mail *mail);
+int index_mail_parse_headers(struct index_mail *mail, int get_parts);
 
 void index_mail_headers_init(struct index_mail *mail);
 void index_mail_headers_init_next(struct index_mail *mail);



More information about the dovecot-cvs mailing list