dovecot-2.2: lib-imap-storage: Don't waste effort getting mail's...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Apr 3 22:03:30 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/95ae49692ccb
changeset: 17198:95ae49692ccb
user: Timo Sirainen <tss at iki.fi>
date: Fri Apr 04 01:03:17 2014 +0300
description:
lib-imap-storage: Don't waste effort getting mail's physical size if it can't be done quickly.
diffstat:
src/lib-imap-storage/imap-msgpart.c | 71 +++++++++++++++++++++---------------
1 files changed, 42 insertions(+), 29 deletions(-)
diffs (199 lines):
diff -r cba3890dafdb -r 95ae49692ccb src/lib-imap-storage/imap-msgpart.c
--- a/src/lib-imap-storage/imap-msgpart.c Fri Apr 04 00:53:34 2014 +0300
+++ b/src/lib-imap-storage/imap-msgpart.c Fri Apr 04 01:03:17 2014 +0300
@@ -336,11 +336,12 @@
static int
imap_msgpart_get_partial_header(struct mail *mail, struct istream *mail_input,
const struct imap_msgpart *msgpart,
- struct message_size *hdr_size_r,
+ uoff_t *virtual_size_r, bool *have_crlfs_r,
struct imap_msgpart_open_result *result_r)
{
const char *const *hdr_fields = msgpart->headers;
unsigned int hdr_count = str_array_length(hdr_fields);
+ struct message_size hdr_size;
struct istream *input;
bool has_nuls;
@@ -361,7 +362,7 @@
(void *)NULL);
}
- if (message_get_header_size(input, hdr_size_r, &has_nuls) < 0) {
+ if (message_get_header_size(input, &hdr_size, &has_nuls) < 0) {
errno = input->stream_errno;
mail_storage_set_critical(mail->box->storage,
"read(%s) failed: %m", i_stream_get_name(mail_input));
@@ -370,7 +371,10 @@
}
i_stream_seek(input, 0);
result_r->input = input;
- result_r->size = hdr_size_r->virtual_size;
+ result_r->size = hdr_size.virtual_size;
+ result_r->size_field = 0;
+ *virtual_size_r = hdr_size.virtual_size;
+ *have_crlfs_r = hdr_size.physical_size == hdr_size.virtual_size;
return 0;
}
@@ -426,7 +430,7 @@
static void
imap_msgpart_get_partial(struct mail *mail, const struct imap_msgpart *msgpart,
bool convert_nuls, bool use_partial_cache,
- const struct message_size *part_size,
+ uoff_t virtual_size, bool have_crlfs,
struct imap_msgpart_open_result *result)
{
struct istream *input2;
@@ -434,7 +438,7 @@
/* input is already seeked to the beginning of the wanted data */
- if (msgpart->partial_offset >= part_size->virtual_size) {
+ if (msgpart->partial_offset >= virtual_size) {
/* can't seek past the MIME part */
i_stream_unref(&result->input);
result->input = i_stream_create_from_data("", 0);
@@ -442,7 +446,7 @@
return;
}
- if (part_size->virtual_size == part_size->physical_size) {
+ if (have_crlfs) {
/* input has CRLF linefeeds, we can quickly seek to
wanted position */
i_stream_skip(result->input, msgpart->partial_offset);
@@ -454,7 +458,7 @@
msgpart);
}
- bytes_left = part_size->virtual_size - msgpart->partial_offset;
+ bytes_left = virtual_size - msgpart->partial_offset;
if (msgpart->partial_size <= bytes_left) {
/* limit output to specified number of bytes */
result->size = msgpart->partial_size;
@@ -527,15 +531,16 @@
static int
imap_msgpart_open_normal(struct mail *mail, struct imap_msgpart *msgpart,
const struct message_part *part,
- struct message_size *part_size_r,
+ uoff_t *virtual_size_r, bool *have_crlfs_r,
struct imap_msgpart_open_result *result_r)
{
- struct message_size hdr_size, body_size;
+ struct message_size hdr_size, body_size, part_size;
struct istream *input = NULL;
+ bool unknown_crlfs = FALSE;
memset(&hdr_size, 0, sizeof(hdr_size));
memset(&body_size, 0, sizeof(body_size));
- memset(part_size_r, 0, sizeof(*part_size_r));
+ memset(&part_size, 0, sizeof(part_size));
if (*msgpart->section_number != '\0') {
/* find the MIME part */
@@ -549,10 +554,15 @@
case FETCH_FULL:
/* fetch the whole message */
if (mail_get_stream(mail, NULL, NULL, &input) < 0 ||
- mail_get_virtual_size(mail, &body_size.virtual_size) < 0 ||
- mail_get_physical_size(mail, &body_size.physical_size) < 0)
+ mail_get_virtual_size(mail, &body_size.virtual_size) < 0)
return -1;
result_r->size_field = MAIL_FETCH_VIRTUAL_SIZE;
+
+ i_assert(mail->lookup_abort == MAIL_LOOKUP_ABORT_NEVER);
+ mail->lookup_abort = MAIL_LOOKUP_ABORT_READ_MAIL;
+ if (mail_get_physical_size(mail, &body_size.physical_size) < 0)
+ unknown_crlfs = TRUE;
+ mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER;
break;
case FETCH_MIME:
case FETCH_MIME_BODY:
@@ -587,18 +597,19 @@
if (msgpart->headers != NULL) {
/* return specific headers */
return imap_msgpart_get_partial_header(mail, input, msgpart,
- part_size_r, result_r);
+ virtual_size_r,
+ have_crlfs_r, result_r);
}
switch (msgpart->fetch_type) {
case FETCH_FULL:
- part_size_r->physical_size += body_size.physical_size;
- part_size_r->virtual_size += body_size.virtual_size;
+ part_size.physical_size += body_size.physical_size;
+ part_size.virtual_size += body_size.virtual_size;
/* fall through */
case FETCH_MIME:
case FETCH_HEADER:
- part_size_r->physical_size += hdr_size.physical_size;
- part_size_r->virtual_size += hdr_size.virtual_size;
+ part_size.physical_size += hdr_size.physical_size;
+ part_size.virtual_size += hdr_size.virtual_size;
break;
case FETCH_HEADER_FIELDS:
case FETCH_HEADER_FIELDS_NOT:
@@ -606,13 +617,16 @@
case FETCH_BODY:
case FETCH_MIME_BODY:
i_stream_skip(input, hdr_size.physical_size);
- part_size_r->physical_size += body_size.physical_size;
- part_size_r->virtual_size += body_size.virtual_size;
+ part_size.physical_size += body_size.physical_size;
+ part_size.virtual_size += body_size.virtual_size;
break;
}
result_r->input = input;
i_stream_ref(input);
+ *virtual_size_r = part_size.virtual_size;
+ *have_crlfs_r = !unknown_crlfs &&
+ part_size.virtual_size == part_size.physical_size;
return 0;
}
@@ -620,9 +634,8 @@
struct imap_msgpart_open_result *result_r)
{
struct message_part *part;
- struct message_size part_size;
- uoff_t size;
- bool include_hdr, binary, use_partial_cache;
+ uoff_t virtual_size;
+ bool include_hdr, binary, use_partial_cache, have_crlfs;
int ret;
memset(result_r, 0, sizeof(*result_r));
@@ -645,15 +658,15 @@
if (mail_get_parts(mail, &part) < 0)
return -1;
}
- if (mail_get_binary_stream(mail, part, include_hdr, &size,
- &binary, &result_r->input) < 0)
+ if (mail_get_binary_stream(mail, part, include_hdr,
+ &virtual_size, &binary,
+ &result_r->input) < 0)
return -1;
- part_size.virtual_size = size;
- part_size.physical_size = size;
+ have_crlfs = TRUE;
use_partial_cache = FALSE;
} else {
- if (imap_msgpart_open_normal(mail, msgpart, part, &part_size,
- result_r) < 0)
+ if (imap_msgpart_open_normal(mail, msgpart, part, &virtual_size,
+ &have_crlfs, result_r) < 0)
return -1;
binary = FALSE;
use_partial_cache = TRUE;
@@ -663,7 +676,7 @@
result_r->binary_decoded_input_has_nuls = TRUE;
imap_msgpart_get_partial(mail, msgpart, !binary, use_partial_cache,
- &part_size, result_r);
+ virtual_size, have_crlfs, result_r);
return 0;
}
More information about the dovecot-cvs
mailing list