[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