Mercurial > dovecot > core-2.2
changeset 10337:69c2aa08cf2c HEAD
lib-storage: Added support for listing/adding cache fields.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 16 Nov 2009 19:38:13 -0500 |
parents | e18645b47984 |
children | d7e946e3c0c4 |
files | src/lib-storage/index/index-status.c src/lib-storage/index/index-storage.c src/lib-storage/mail-storage.h |
diffstat | 3 files changed, 84 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/index-status.c Mon Nov 16 18:38:06 2009 -0500 +++ b/src/lib-storage/index/index-status.c Mon Nov 16 19:38:13 2009 -0500 @@ -1,9 +1,35 @@ /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" +#include "mail-cache.h" #include "index-storage.h" #include "mail-index-modseq.h" +static void +index_storage_get_status_cache_fields(struct index_mailbox *ibox, + struct mailbox_status *status_r) +{ + const struct mail_cache_field *fields; + enum mail_cache_decision_type dec; + ARRAY_TYPE(const_string) *cache_fields; + unsigned int i, count; + + fields = mail_cache_register_get_list(ibox->cache, + pool_datastack_create(), &count); + + /* a bit leaky to allocate memory from mailbox pool every time, but this + is unlikely to be called more than once for the mailbox anyway. */ + cache_fields = p_new(ibox->box.pool, ARRAY_TYPE(const_string), 1); + p_array_init(cache_fields, ibox->box.pool, count); + for (i = 0; i < count; i++) { + dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED; + if (dec != MAIL_CACHE_DECISION_NO) + array_append(cache_fields, &fields[i].name, 1); + } + status_r->cache_fields = cache_fields; +} + void index_storage_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r) @@ -35,11 +61,13 @@ } } - if (items & STATUS_FIRST_UNSEEN_SEQ) { + if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) { mail_index_lookup_first(ibox->view, 0, MAIL_SEEN, &status_r->first_unseen_seq); } - if (items & STATUS_KEYWORDS) + if ((items & STATUS_KEYWORDS) != 0) status_r->keywords = mail_index_get_keywords(ibox->index); + if ((items & STATUS_CACHE_FIELDS) != 0) + index_storage_get_status_cache_fields(ibox, status_r); }
--- a/src/lib-storage/index/index-storage.c Mon Nov 16 18:38:06 2009 -0500 +++ b/src/lib-storage/index/index-storage.c Mon Nov 16 19:38:13 2009 -0500 @@ -539,6 +539,52 @@ pool_unref(&box->pool); } +static void +index_storage_mailbox_update_cache_fields(struct index_mailbox *ibox, + const struct mailbox_update *update) +{ + const char *const *field_names = update->cache_fields; + ARRAY_DEFINE(new_fields, struct mail_cache_field); + const struct mail_cache_field *old_fields; + struct mail_cache_field field; + unsigned int i, j, old_count; + + old_fields = mail_cache_register_get_list(ibox->cache, + pool_datastack_create(), + &old_count); + + /* There shouldn't be many fields, so don't worry about O(n^2). */ + t_array_init(&new_fields, 32); + for (i = 0; field_names[i] != NULL; i++) { + /* see if it's an existing field */ + for (j = 0; j < old_count; j++) { + if (strcmp(field_names[i], old_fields[j].name) == 0) + break; + } + if (j != old_count) { + field = old_fields[i]; + if (field.decision == MAIL_CACHE_DECISION_NO) + field.decision = MAIL_CACHE_DECISION_TEMP; + array_append(&new_fields, &field, 1); + } else if (strncmp(field_names[i], "hdr.", 4) == 0) { + /* new header */ + memset(&field, 0, sizeof(field)); + field.name = field_names[i]; + field.type = MAIL_CACHE_FIELD_HEADER; + field.decision = MAIL_CACHE_DECISION_TEMP; + array_append(&new_fields, &field, 1); + } else { + /* new unknown field. we can't do anything about + this since we don't know its type */ + } + } + if (array_count(&new_fields) > 0) { + mail_cache_register_fields(ibox->cache, + array_idx_modifiable(&new_fields, 0), + array_count(&new_fields)); + } +} + int index_storage_mailbox_update(struct mailbox *box, const struct mailbox_update *update) { @@ -552,6 +598,8 @@ if (mailbox_open(box) < 0) return -1; } + if (update->cache_fields != NULL) + index_storage_mailbox_update_cache_fields(ibox, update); /* make sure we get the latest index info */ (void)mail_index_refresh(ibox->index);
--- a/src/lib-storage/mail-storage.h Mon Nov 16 18:38:06 2009 -0500 +++ b/src/lib-storage/mail-storage.h Mon Nov 16 19:38:13 2009 -0500 @@ -60,7 +60,8 @@ STATUS_FIRST_UNSEEN_SEQ = 0x20, STATUS_KEYWORDS = 0x40, STATUS_HIGHESTMODSEQ = 0x80, - STATUS_GUID = 0x100 + STATUS_GUID = 0x100, + STATUS_CACHE_FIELDS = 0x200 }; enum mailbox_search_result_flags { @@ -185,6 +186,8 @@ uint8_t mailbox_guid[MAIL_GUID_128_SIZE]; const ARRAY_TYPE(keywords) *keywords; + /* Fields that have "temp" or "yes" caching decision. */ + const ARRAY_TYPE(const_string) *cache_fields; /* There are expunges that haven't been synced yet */ unsigned int sync_delayed_expunges:1; @@ -198,6 +201,8 @@ uint32_t uid_validity; uint32_t min_next_uid; uint64_t min_highest_modseq; + /* Add these fields to be temporarily cached, if they aren't already. */ + const char *const *cache_fields; }; struct mail_transaction_commit_changes {