dovecot-2.0: Maildir: If mail's virtual size can be found from f...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Sep 29 20:39:00 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/906746b4f383
changeset: 12205:906746b4f383
user: Timo Sirainen <tss at iki.fi>
date: Wed Sep 29 18:38:29 2010 +0100
description:
Maildir: If mail's virtual size can be found from filename/uidlist, do it instead of using cache.
This is especially useful with POP3 to avoid opening cache file.
diffstat:
src/lib-storage/index/index-mail.c | 37 ++++++++++++------
src/lib-storage/index/index-mail.h | 2 +
src/lib-storage/index/maildir/maildir-mail.c | 27 ++++++++++---
src/lib-storage/index/maildir/maildir-uidlist.c | 5 ++
src/lib-storage/index/maildir/maildir-uidlist.h | 1 +
5 files changed, 53 insertions(+), 19 deletions(-)
diffs (169 lines):
diff -r 062da0b83c01 -r 906746b4f383 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c Wed Sep 29 18:09:28 2010 +0100
+++ b/src/lib-storage/index/index-mail.c Wed Sep 29 18:38:29 2010 +0100
@@ -802,13 +802,34 @@
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);
}
@@ -844,7 +865,7 @@
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;
@@ -865,7 +886,7 @@
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 {
@@ -1181,7 +1202,7 @@
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;
}
@@ -1255,14 +1276,6 @@
}
}
- 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);
diff -r 062da0b83c01 -r 906746b4f383 src/lib-storage/index/index-mail.h
--- a/src/lib-storage/index/index-mail.h Wed Sep 29 18:09:28 2010 +0100
+++ b/src/lib-storage/index/index-mail.h Wed Sep 29 18:38:29 2010 +0100
@@ -225,4 +225,6 @@
int index_mail_cache_lookup_field(struct index_mail *mail, buffer_t *buf,
unsigned int field_idx);
+enum index_mail_access_part index_mail_get_access_part(struct index_mail *mail);
+
#endif
diff -r 062da0b83c01 -r 906746b4f383 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c Wed Sep 29 18:09:28 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-mail.c Wed Sep 29 18:38:29 2010 +0100
@@ -112,7 +112,8 @@
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;
@@ -364,20 +365,32 @@
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;
diff -r 062da0b83c01 -r 906746b4f383 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Wed Sep 29 18:09:28 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c Wed Sep 29 18:38:29 2010 +0100
@@ -227,6 +227,11 @@
return UIDLIST_IS_LOCKED(uidlist);
}
+bool maildir_uidlist_is_read(struct maildir_uidlist *uidlist)
+{
+ return uidlist->initial_read;
+}
+
void maildir_uidlist_unlock(struct maildir_uidlist *uidlist)
{
i_assert(uidlist->lock_count > 0);
diff -r 062da0b83c01 -r 906746b4f383 src/lib-storage/index/maildir/maildir-uidlist.h
--- a/src/lib-storage/index/maildir/maildir-uidlist.h Wed Sep 29 18:09:28 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h Wed Sep 29 18:38:29 2010 +0100
@@ -55,6 +55,7 @@
int maildir_uidlist_lock_touch(struct maildir_uidlist *uidlist);
void maildir_uidlist_unlock(struct maildir_uidlist *uidlist);
bool maildir_uidlist_is_locked(struct maildir_uidlist *uidlist);
+bool maildir_uidlist_is_read(struct maildir_uidlist *uidlist);
struct maildir_uidlist *maildir_uidlist_init(struct maildir_mailbox *mbox);
void maildir_uidlist_deinit(struct maildir_uidlist **uidlist);
More information about the dovecot-cvs
mailing list