mail->data.destroying_stream = FALSE;
}
+enum index_mail_access_part index_mail_get_access_part(struct index_mail *mail)
+{
+ struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
+
+ if ((mail->data.access_part & (READ_HDR | PARSE_HDR)) != 0 &&
+ (mail->data.access_part & (READ_BODY | PARSE_BODY)) != 0)
+ return mail->data.access_part;
+
+ /* lazy virtual size access check */
+ if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0) {
+ unsigned int cache_field =
+ cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
+
+ if (mail_cache_field_exists(mail->trans->cache_view,
+ mail->mail.mail.seq,
+ cache_field) <= 0)
+ mail->data.access_part |= READ_HDR | READ_BODY;
+ }
+ return mail->data.access_part;
+}
+
void index_mail_set_read_buffer_size(struct mail *_mail, struct istream *input)
{
struct index_mail *mail = (struct index_mail *)_mail;
unsigned int block_size;
i_stream_set_max_buffer_size(input, MAIL_READ_FULL_BLOCK_SIZE);
- block_size = (mail->data.access_part & READ_BODY) != 0 ?
+ block_size = (index_mail_get_access_part(mail) & READ_BODY) != 0 ?
MAIL_READ_FULL_BLOCK_SIZE : MAIL_READ_HDR_BLOCK_SIZE;
i_stream_set_init_buffer_size(input, block_size);
}
if (hdr_size != NULL || body_size != NULL) {
i_stream_seek(data->stream, 0);
if (!data->hdr_size_set) {
- if ((data->access_part & PARSE_HDR) != 0) {
+ if ((index_mail_get_access_part(mail) & PARSE_HDR) != 0) {
(void)get_cached_parts(mail);
if (index_mail_parse_headers(mail, NULL) < 0)
return -1;
if (!data->body_size_set) {
i_stream_seek(data->stream,
data->hdr_size.physical_size);
- if ((data->access_part & PARSE_BODY) != 0) {
+ if ((index_mail_get_access_part(mail) & PARSE_BODY) != 0) {
if (index_mail_parse_body(mail, 0) < 0)
return -1;
} else {
mail->ibox->cache_fields[MAIL_CACHE_IMAP_ENVELOPE].idx;
unsigned int cache_field_hdr;
- if ((mail->data.access_part & PARSE_HDR) != 0) {
+ if ((index_mail_get_access_part(mail) & PARSE_HDR) != 0) {
mail->data.save_envelope = TRUE;
return;
}
}
}
- if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0) {
- unsigned int cache_field =
- cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
-
- if (mail_cache_field_exists(cache_view, seq, cache_field) <= 0)
- data->access_part |= READ_HDR | READ_BODY;
- }
-
if ((mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0)
check_envelope(mail);
if (mail->lookup_abort == MAIL_LOOKUP_ABORT_NOT_IN_CACHE)
return mail_set_aborted(mail);
- if (imail->data.access_part != 0 && imail->data.stream == NULL) {
+ if (index_mail_get_access_part(imail) != 0 &&
+ imail->data.stream == NULL) {
/* we're going to open the mail anyway */
struct istream *input;
static int maildir_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
{
+ struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
struct index_mail *mail = (struct index_mail *)_mail;
struct index_mail_data *data = &mail->data;
struct message_size hdr_size, body_size;
struct istream *input;
uoff_t old_offset;
- if (index_mail_get_cached_virtual_size(mail, size_r)) {
- i_assert(mail->data.virtual_size != (uoff_t)-1);
- maildir_handle_size_caching(mail, TRUE, TRUE);
- return 0;
+ if (maildir_uidlist_is_read(mbox->uidlist) ||
+ (_mail->box->flags & MAILBOX_FLAG_POP3_SESSION) != 0) {
+ /* try to get the size from uidlist. this is especially useful
+ with pop3 to avoid unnecessarily opening the cache file. */
+ if (maildir_quick_size_lookup(mail, TRUE,
+ &data->virtual_size) < 0)
+ return -1;
}
- if (maildir_quick_size_lookup(mail, TRUE, &data->virtual_size) < 0)
- return -1;
+ if (data->virtual_size == (uoff_t)-1) {
+ if (index_mail_get_cached_virtual_size(mail, size_r)) {
+ i_assert(mail->data.virtual_size != (uoff_t)-1);
+ maildir_handle_size_caching(mail, TRUE, TRUE);
+ return 0;
+ }
+
+ if (maildir_quick_size_lookup(mail, TRUE, &data->virtual_size) < 0)
+ return -1;
+ }
if (data->virtual_size != (uoff_t)-1) {
data->dont_cache_fetch_fields |= MAIL_FETCH_VIRTUAL_SIZE;
*size_r = data->virtual_size;