changeset 21982:9282e5b090f1

lib-storage: Add mail_storage.nonbody_access_fields This avoids index_mail_update_access_parts_pre() from opening the mail stream unnecessarily for fields that can be looked up via other methods by the storage.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 24 Apr 2017 13:27:43 +0300
parents 0b5db3e0cfc2
children 33dbc4cdd0c5
files src/lib-storage/index/index-mail.c src/lib-storage/mail-storage-private.h
diffstat 2 files changed, 13 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-mail.c	Mon Apr 24 13:05:48 2017 +0300
+++ b/src/lib-storage/index/index-mail.c	Mon Apr 24 13:27:43 2017 +0300
@@ -1730,6 +1730,7 @@
 {
 	struct index_mail *mail = (struct index_mail *)_mail;
 	struct index_mail_data *data = &mail->data;
+	struct mail_storage *storage = _mail->box->storage;
 	const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
 	struct mail_cache_view *cache_view = _mail->transaction->cache_view;
 
@@ -1760,6 +1761,7 @@
 	/* see if wanted_fields can tell us if we need to read/parse
 	   header/body */
 	if ((data->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0 &&
+	    (storage->nonbody_access_fields & MAIL_FETCH_MESSAGE_PARTS) == 0 &&
 	    data->parts == NULL) {
 		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
@@ -1772,11 +1774,13 @@
 	}
 
 	if ((data->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0 &&
+	    (storage->nonbody_access_fields & MAIL_FETCH_IMAP_ENVELOPE) == 0 &&
 	    data->envelope == NULL)
 		check_envelope(mail);
 
 	if ((data->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0 &&
 	    (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0 &&
+	    (storage->nonbody_access_fields & MAIL_FETCH_IMAP_BODY) == 0 &&
 	    data->body == NULL) {
 		/* we need either imap.body or imap.bodystructure */
 		const unsigned int cache_field1 =
@@ -1796,6 +1800,7 @@
 
 	if ((data->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0 &&
 	    (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0 &&
+	    (storage->nonbody_access_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) == 0 &&
 	    data->bodystructure == NULL) {
 		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
@@ -1809,6 +1814,7 @@
 	}
 
 	if ((data->wanted_fields & MAIL_FETCH_DATE) != 0 &&
+	    (storage->nonbody_access_fields & MAIL_FETCH_DATE) == 0 &&
 	    data->sent_date.time == (uint32_t)-1) {
 		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_SENT_DATE].idx;
@@ -1819,7 +1825,8 @@
 			data->save_sent_date = TRUE;
 		}
 	}
-	if ((data->wanted_fields & MAIL_FETCH_BODY_SNIPPET) != 0) {
+	if ((data->wanted_fields & MAIL_FETCH_BODY_SNIPPET) != 0 &&
+	    (storage->nonbody_access_fields & MAIL_FETCH_BODY_SNIPPET) == 0) {
 		const unsigned int cache_field =
 			cache_fields[MAIL_CACHE_BODY_SNIPPET].idx;
 
--- a/src/lib-storage/mail-storage-private.h	Mon Apr 24 13:05:48 2017 +0300
+++ b/src/lib-storage/mail-storage-private.h	Mon Apr 24 13:27:43 2017 +0300
@@ -110,6 +110,11 @@
 struct mail_storage {
 	const char *name;
 	enum mail_storage_class_flags class_flags;
+	/* Fields that the storage backend can get by other means than parsing
+	   the message header/body. For example the imapc backend can lookup
+	   MAIL_FETCH_IMAP_BODYSTRUCTURE from the remote server. Adding fields
+	   here avoids adding them to index_mail_data.access_part. */
+	enum mail_fetch_field nonbody_access_fields;
 
         struct mail_storage_vfuncs v, *vlast;