dovecot-2.2: lib-storage: Added MAILBOX_METADATA_PHYSICAL_SIZE

dovecot at dovecot.org dovecot at dovecot.org
Sat Jul 11 09:20:12 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/84392ca460ab
changeset: 18905:84392ca460ab
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Jul 11 12:11:48 2015 +0300
description:
lib-storage: Added MAILBOX_METADATA_PHYSICAL_SIZE
If backend always uses the same virtual and physical sizes, this is
implemented via the MAILBOX_METADATA_VIRTUAL_SIZE code. Otherwise it
searches all the messages and sums up their physical sizes.

diffstat:

 src/lib-storage/index/index-mailbox-size.c |  58 ++++++++++++++++++++++++++++++
 src/lib-storage/index/index-status.c       |   5 ++-
 src/lib-storage/index/index-storage.h      |   2 +
 src/lib-storage/mail-storage.h             |   7 ++-
 4 files changed, 69 insertions(+), 3 deletions(-)

diffs (125 lines):

diff -r 8e47bb182a42 -r 84392ca460ab src/lib-storage/index/index-mailbox-size.c
--- a/src/lib-storage/index/index-mailbox-size.c	Sat Jul 11 12:06:44 2015 +0300
+++ b/src/lib-storage/index/index-mailbox-size.c	Sat Jul 11 12:11:48 2015 +0300
@@ -110,3 +110,61 @@
 	metadata_r->virtual_size = vsize_hdr.vsize;
 	return ret;
 }
+
+int index_mailbox_get_physical_size(struct mailbox *box,
+				    struct mailbox_metadata *metadata_r)
+{
+	struct mailbox_transaction_context *trans;
+	struct mail_search_context *ctx;
+	struct mail *mail;
+	struct mail_search_args *search_args;
+	uoff_t size;
+	int ret = 0;
+
+	/* if physical size = virtual size always for the storage, we can
+	   use the optimized vsize code for this */
+	if (box->mail_vfuncs->get_physical_size ==
+	    box->mail_vfuncs->get_virtual_size) {
+		if (index_mailbox_get_virtual_size(box, metadata_r) < 0)
+			return -1;
+		metadata_r->physical_size = metadata_r->virtual_size;
+		return 0;
+	}
+	/* do it the slow way (we could implement similar logic as for vsize,
+	   but for now it's not really needed) */
+	if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
+		return -1;
+
+	trans = mailbox_transaction_begin(box, 0);
+
+	search_args = mail_search_build_init();
+	mail_search_build_add_all(search_args);
+	ctx = mailbox_search_init(trans, search_args, NULL,
+				  MAIL_FETCH_PHYSICAL_SIZE, NULL);
+	mail_search_args_unref(&search_args);
+
+	metadata_r->physical_size = 0;
+	while (mailbox_search_next(ctx, &mail)) {
+		if (mail_get_physical_size(mail, &size) == 0)
+			metadata_r->physical_size += size;
+		else {
+			const char *errstr;
+			enum mail_error error;
+
+			errstr = mailbox_get_last_error(box, &error);
+			if (error != MAIL_ERROR_EXPUNGED) {
+				i_error("Couldn't get size of mail UID %u in %s: %s",
+					mail->uid, box->vname, errstr);
+				ret = -1;
+				break;
+			}
+		}
+	}
+	if (mailbox_search_deinit(&ctx) < 0) {
+		i_error("Listing mails in %s failed: %s",
+			box->vname, mailbox_get_last_error(box, NULL));
+		ret = -1;
+	}
+	(void)mailbox_transaction_commit(&trans);
+	return ret;
+}
diff -r 8e47bb182a42 -r 84392ca460ab src/lib-storage/index/index-status.c
--- a/src/lib-storage/index/index-status.c	Sat Jul 11 12:06:44 2015 +0300
+++ b/src/lib-storage/index/index-status.c	Sat Jul 11 12:11:48 2015 +0300
@@ -3,7 +3,6 @@
 #include "lib.h"
 #include "array.h"
 #include "mail-cache.h"
-#include "mail-search-build.h"
 #include "mail-index-modseq.h"
 #include "index-storage.h"
 
@@ -289,6 +288,10 @@
 		if (index_mailbox_get_virtual_size(box, metadata_r) < 0)
 			return -1;
 	}
+	if ((items & MAILBOX_METADATA_PHYSICAL_SIZE) != 0) {
+		if (index_mailbox_get_physical_size(box, metadata_r) < 0)
+			return -1;
+	}
 	if ((items & MAILBOX_METADATA_CACHE_FIELDS) != 0)
 		get_metadata_cache_fields(box, metadata_r);
 	if ((items & MAILBOX_METADATA_PRECACHE_FIELDS) != 0)
diff -r 8e47bb182a42 -r 84392ca460ab src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h	Sat Jul 11 12:06:44 2015 +0300
+++ b/src/lib-storage/index/index-storage.h	Sat Jul 11 12:11:48 2015 +0300
@@ -112,6 +112,8 @@
 			       struct mailbox_metadata *metadata_r);
 int index_mailbox_get_virtual_size(struct mailbox *box,
 				   struct mailbox_metadata *metadata_r);
+int index_mailbox_get_physical_size(struct mailbox *box,
+				    struct mailbox_metadata *metadata_r);
 
 int index_storage_attribute_set(struct mailbox_transaction_context *t,
 				enum mail_attribute_type type, const char *key,
diff -r 8e47bb182a42 -r 84392ca460ab src/lib-storage/mail-storage.h
--- a/src/lib-storage/mail-storage.h	Sat Jul 11 12:06:44 2015 +0300
+++ b/src/lib-storage/mail-storage.h	Sat Jul 11 12:11:48 2015 +0300
@@ -90,10 +90,11 @@
 	MAILBOX_METADATA_VIRTUAL_SIZE		= 0x02,
 	MAILBOX_METADATA_CACHE_FIELDS		= 0x04,
 	MAILBOX_METADATA_PRECACHE_FIELDS	= 0x08,
-	MAILBOX_METADATA_BACKEND_NAMESPACE	= 0x10
+	MAILBOX_METADATA_BACKEND_NAMESPACE	= 0x10,
+	MAILBOX_METADATA_PHYSICAL_SIZE		= 0x20
 	/* metadata items that require mailbox to be synced at least once. */
 #define MAILBOX_METADATA_SYNC_ITEMS \
-	(MAILBOX_METADATA_VIRTUAL_SIZE)
+	(MAILBOX_METADATA_VIRTUAL_SIZE | MAILBOX_METADATA_PHYSICAL_SIZE)
 };
 
 enum mailbox_search_result_flags {
@@ -267,6 +268,8 @@
 	guid_128_t guid;
 	/* sum of virtual size of all messages in mailbox */
 	uint64_t virtual_size;
+	/* sum of physical size of all messages in mailbox */
+	uint64_t physical_size;
 	/* Fields that have "temp" or "yes" caching decision. */
 	const ARRAY_TYPE(mailbox_cache_field) *cache_fields;
 	/* Fields that should be precached */


More information about the dovecot-cvs mailing list