dovecot-2.2: lib-storage: If mailboxes' vsizes are used, keep th...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jul 11 09:20:18 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/46cbde67f50b
changeset: 18907:46cbde67f50b
user: Timo Sirainen <tss at iki.fi>
date: Sat Jul 11 12:16:56 2015 +0300
description:
lib-storage: If mailboxes' vsizes are used, keep them updated also in mailbox list index.
This allows looking them up quickly without opening the actual mailbox
indexes.
diffstat:
src/lib-storage/list/mailbox-list-index-backend.c | 2 +-
src/lib-storage/list/mailbox-list-index-notify.c | 2 +-
src/lib-storage/list/mailbox-list-index-status.c | 131 +++++++++++++++++++--
src/lib-storage/list/mailbox-list-index.h | 5 +-
src/lib-storage/list/mailbox-list-notify-tree.c | 2 +-
5 files changed, 122 insertions(+), 20 deletions(-)
diffs (truncated from 309 to 300 lines):
diff -r 421f595a0e93 -r 46cbde67f50b src/lib-storage/list/mailbox-list-index-backend.c
--- a/src/lib-storage/list/mailbox-list-index-backend.c Sat Jul 11 12:14:48 2015 +0300
+++ b/src/lib-storage/list/mailbox-list-index-backend.c Sat Jul 11 12:16:56 2015 +0300
@@ -175,7 +175,7 @@
T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
ret = -1;
} else if (!mailbox_list_index_status(_list, view, seq, 0,
- &status, mailbox_guid) ||
+ &status, mailbox_guid, NULL) ||
guid_128_is_empty(mailbox_guid)) {
mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND,
T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
diff -r 421f595a0e93 -r 46cbde67f50b src/lib-storage/list/mailbox-list-index-notify.c
--- a/src/lib-storage/list/mailbox-list-index-notify.c Sat Jul 11 12:14:48 2015 +0300
+++ b/src/lib-storage/list/mailbox-list-index-notify.c Sat Jul 11 12:16:56 2015 +0300
@@ -160,7 +160,7 @@
memset(status_r, 0, sizeof(*status_r));
memset(guid_r, 0, GUID_128_SIZE);
(void)mailbox_list_index_status(inotify->notify.list, view, seq,
- items, status_r, guid_r);
+ items, status_r, guid_r, NULL);
return index_node;
}
diff -r 421f595a0e93 -r 46cbde67f50b src/lib-storage/list/mailbox-list-index-status.c
--- a/src/lib-storage/list/mailbox-list-index-status.c Sat Jul 11 12:14:48 2015 +0300
+++ b/src/lib-storage/list/mailbox-list-index-status.c Sat Jul 11 12:16:56 2015 +0300
@@ -14,10 +14,12 @@
struct mailbox_status status;
guid_128_t guid;
uint32_t seq;
+ struct mailbox_index_vsize vsize;
bool rec_changed;
bool msgs_changed;
bool hmodseq_changed;
+ bool vsize_changed;
};
struct index_list_storage_module index_list_storage_module =
@@ -108,7 +110,8 @@
struct mail_index_view *view,
uint32_t seq, enum mailbox_status_items items,
struct mailbox_status *status_r,
- uint8_t *mailbox_guid)
+ uint8_t *mailbox_guid,
+ struct mailbox_index_vsize *vsize_r)
{
struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
const void *data;
@@ -161,6 +164,14 @@
else
status_r->highest_modseq = *rec;
}
+ if (vsize_r != NULL) {
+ mail_index_lookup_ext(view, seq, ilist->vsize_ext_id,
+ &data, &expunged);
+ if (data == NULL)
+ ret = FALSE;
+ else
+ memcpy(vsize_r, data, sizeof(*vsize_r));
+ }
return ret;
}
@@ -184,7 +195,7 @@
return ret;
ret = mailbox_list_index_status(box->list, view, seq, items,
- status_r, NULL) ? 1 : 0;
+ status_r, NULL, NULL) ? 1 : 0;
mail_index_view_close(&view);
return ret;
}
@@ -221,13 +232,81 @@
return ret;
ret = mailbox_list_index_status(box->list, view, seq, 0,
- &status, guid_r) ? 1 : 0;
+ &status, guid_r, NULL) ? 1 : 0;
if (ret > 0 && guid_128_is_empty(guid_r))
ret = 0;
mail_index_view_close(&view);
return ret;
}
+static int index_list_get_cached_vsize(struct mailbox *box, uoff_t *vsize_r)
+{
+ struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list);
+ struct mailbox_status status;
+ struct mailbox_index_vsize vsize;
+ struct mail_index_view *view;
+ uint32_t seq;
+ int ret;
+
+ i_assert(!ilist->syncing);
+
+ if ((ret = index_list_open_view(box, &view, &seq)) <= 0)
+ return ret;
+
+ ret = mailbox_list_index_status(box->list, view, seq,
+ STATUS_MESSAGES | STATUS_UIDNEXT,
+ &status, NULL, &vsize) ? 1 : 0;
+ if (ret > 0 && (vsize.highest_uid + 1 != status.uidnext ||
+ vsize.message_count != status.messages)) {
+ /* out of date vsize info */
+ ret = 0;
+ }
+ if (ret > 0)
+ *vsize_r = vsize.vsize;
+ mail_index_view_close(&view);
+ return ret;
+}
+
+static int
+index_list_try_get_metadata(struct mailbox *box,
+ enum mailbox_metadata_items items,
+ struct mailbox_metadata *metadata_r)
+{
+ enum mailbox_metadata_items noncached_items;
+ int ret;
+
+ if (box->opened) {
+ /* if mailbox is already opened, don't bother using the values
+ in mailbox list index. they have a higher chance of being
+ wrong. */
+ return 0;
+ }
+ /* see if we have a chance of fulfilling this without opening
+ the mailbox. */
+ noncached_items = items & ~(MAILBOX_METADATA_GUID |
+ MAILBOX_METADATA_VIRTUAL_SIZE);
+ if ((noncached_items & MAILBOX_METADATA_PHYSICAL_SIZE) != 0 &&
+ box->mail_vfuncs->get_physical_size ==
+ box->mail_vfuncs->get_virtual_size)
+ noncached_items = items & ~MAILBOX_METADATA_PHYSICAL_SIZE;
+
+ if (noncached_items != 0)
+ return 0;
+
+ if ((items & MAILBOX_METADATA_GUID) != 0) {
+ if ((ret = index_list_get_cached_guid(box, metadata_r->guid)) <= 0)
+ return ret;
+ }
+ if ((items & (MAILBOX_METADATA_VIRTUAL_SIZE |
+ MAILBOX_METADATA_PHYSICAL_SIZE)) != 0) {
+ if ((ret = index_list_get_cached_vsize(box, &metadata_r->virtual_size)) <= 0)
+ return ret;
+ if ((items & MAILBOX_METADATA_PHYSICAL_SIZE) != 0)
+ metadata_r->physical_size = metadata_r->virtual_size;
+ }
+ return 1;
+}
+
static int
index_list_get_metadata(struct mailbox *box,
enum mailbox_metadata_items items,
@@ -235,14 +314,25 @@
{
struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
- if (items == MAILBOX_METADATA_GUID && !box->opened) {
- if (index_list_get_cached_guid(box, metadata_r->guid) > 0)
- return 0;
- /* nonsynced / error, fallback to doing it the slow way */
- }
+ if (index_list_try_get_metadata(box, items, metadata_r) != 0)
+ return 0;
return ibox->module_ctx.super.get_metadata(box, items, metadata_r);
}
+static void
+index_list_update_fill_vsize(struct mailbox *box,
+ struct mail_index_view *view,
+ struct index_list_changes *changes_r)
+{
+ const void *data;
+ size_t size;
+
+ mail_index_get_header_ext(view, box->vsize_hdr_ext_id,
+ &data, &size);
+ if (size == sizeof(changes_r->vsize))
+ memcpy(&changes_r->vsize, data, sizeof(changes_r->vsize));
+}
+
static bool
index_list_update_fill_changes(struct mailbox *box,
struct mail_index_view *list_view,
@@ -286,6 +376,7 @@
/* modseqs not enabled yet, but we can't return 0 */
changes_r->status.highest_modseq = 1;
}
+ index_list_update_fill_vsize(box, view, changes_r);
mail_index_view_close(&view); hdr = NULL;
if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) == 0)
@@ -299,13 +390,15 @@
{
struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list);
struct mailbox_status old_status;
+ struct mailbox_index_vsize old_vsize;
guid_128_t old_guid;
memset(&old_status, 0, sizeof(old_status));
+ memset(&old_vsize, 0, sizeof(old_vsize));
memset(old_guid, 0, sizeof(old_guid));
(void)mailbox_list_index_status(box->list, list_view, changes->seq,
CACHED_STATUS_ITEMS,
- &old_status, old_guid);
+ &old_status, old_guid, &old_vsize);
changes->rec_changed =
old_status.uidvalidity != changes->status.uidvalidity &&
@@ -331,13 +424,11 @@
ilist->hmodseq_ext_id, &data, &expunged);
changes->hmodseq_changed = data != NULL;
}
-
- if (changes->hmodseq_changed &&
- old_status.highest_modseq != changes->status.highest_modseq)
- changes->hmodseq_changed = TRUE;
+ if (memcmp(&old_vsize, &changes->vsize, sizeof(old_vsize)) != 0)
+ changes->vsize_changed = TRUE;
return changes->rec_changed || changes->msgs_changed ||
- changes->hmodseq_changed;
+ changes->hmodseq_changed || changes->vsize_changed;
}
static void
@@ -382,6 +473,11 @@
ilist->hmodseq_ext_id,
&changes->status.highest_modseq, NULL);
}
+ if (changes->vsize_changed) {
+ mail_index_update_ext(list_trans, changes->seq,
+ ilist->vsize_ext_id,
+ &changes->vsize, NULL);
+ }
}
static int index_list_update_mailbox(struct mailbox *box)
@@ -482,7 +578,7 @@
(void)mailbox_list_index_status(box->list, list_view, changes.seq,
CACHED_STATUS_ITEMS, &status,
- mailbox_guid);
+ mailbox_guid, NULL);
if (update->uid_validity != 0) {
changes.rec_changed = TRUE;
changes.status.uidvalidity = update->uid_validity;
@@ -575,7 +671,7 @@
status.recent = 0;
(void)mailbox_list_index_status(box->list, view, seq, STATUS_RECENT,
- &status, NULL);
+ &status, NULL, NULL);
mail_index_view_close(&view);
if (status.recent != 0)
@@ -604,4 +700,7 @@
ilist->hmodseq_ext_id =
mail_index_ext_register(ilist->index, "hmodseq", 0,
sizeof(uint64_t), sizeof(uint64_t));
+ ilist->vsize_ext_id =
+ mail_index_ext_register(ilist->index, "vsize", 0,
+ sizeof(struct mailbox_index_vsize), sizeof(uint64_t));
}
diff -r 421f595a0e93 -r 46cbde67f50b src/lib-storage/list/mailbox-list-index.h
--- a/src/lib-storage/list/mailbox-list-index.h Sat Jul 11 12:14:48 2015 +0300
+++ b/src/lib-storage/list/mailbox-list-index.h Sat Jul 11 12:16:56 2015 +0300
@@ -36,6 +36,7 @@
MODULE_CONTEXT(obj, mailbox_list_index_module)
struct mail_index_view;
+struct mailbox_index_vsize;
/* stored in mail_index_record.flags: */
enum mailbox_list_index_flags {
@@ -88,6 +89,7 @@
const char *path;
struct mail_index *index;
uint32_t ext_id, msgs_ext_id, hmodseq_ext_id, subs_hdr_ext_id;
+ uint32_t vsize_ext_id;
struct timeval last_refresh_timeval;
pool_t mailbox_pool;
@@ -170,7 +172,8 @@
struct mail_index_view *view,
uint32_t seq, enum mailbox_status_items items,
struct mailbox_status *status_r,
- uint8_t *mailbox_guid);
+ uint8_t *mailbox_guid,
+ struct mailbox_index_vsize *vsize_r);
void mailbox_list_index_status_set_info_flags(struct mailbox *box, uint32_t uid,
enum mailbox_info_flags *flags);
void mailbox_list_index_update_mailbox_index(struct mailbox *box,
diff -r 421f595a0e93 -r 46cbde67f50b src/lib-storage/list/mailbox-list-notify-tree.c
--- a/src/lib-storage/list/mailbox-list-notify-tree.c Sat Jul 11 12:14:48 2015 +0300
+++ b/src/lib-storage/list/mailbox-list-notify-tree.c Sat Jul 11 12:16:56 2015 +0300
More information about the dovecot-cvs
mailing list