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