Mercurial > dovecot > core-2.2
changeset 18905:84392ca460ab
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.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 11 Jul 2015 12:11:48 +0300 |
parents | 8e47bb182a42 |
children | 421f595a0e93 |
files | src/lib-storage/index/index-mailbox-size.c src/lib-storage/index/index-status.c src/lib-storage/index/index-storage.h src/lib-storage/mail-storage.h |
diffstat | 4 files changed, 69 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- 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; +}
--- 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)
--- 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,
--- 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 */