From: Timo Sirainen Date: Sat, 10 Dec 2011 06:44:33 +0000 (+0200) Subject: dsync: Update cache fields' decision and last_used fields explicitly. X-Git-Tag: 2.1.rc2~56 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28c959a90483d00c36b7746bd630e76bf3ad0950;p=thirdparty%2Fdovecot%2Fcore.git dsync: Update cache fields' decision and last_used fields explicitly. This makes v2.1's dsync incompatible with v2.0's when used in different servers. --- diff --git a/src/dsync/dsync-data.c b/src/dsync/dsync-data.c index d986c5b973..48fad3f829 100644 --- a/src/dsync/dsync-data.c +++ b/src/dsync/dsync-data.c @@ -10,7 +10,8 @@ struct dsync_mailbox * dsync_mailbox_dup(pool_t pool, const struct dsync_mailbox *box) { struct dsync_mailbox *dest; - const char *const *cache_fields = NULL, *dup; + const struct mailbox_cache_field *cache_fields = NULL; + struct mailbox_cache_field *dup; unsigned int i, count = 0; dest = p_new(pool, struct dsync_mailbox, 1); @@ -24,8 +25,9 @@ dsync_mailbox_dup(pool_t pool, const struct dsync_mailbox *box) else { p_array_init(&dest->cache_fields, pool, count); for (i = 0; i < count; i++) { - dup = p_strdup(pool, cache_fields[i]); - array_append(&dest->cache_fields, &dup, 1); + dup = array_append_space(&dest->cache_fields); + *dup = cache_fields[i]; + dup->name = p_strdup(pool, dup->name); } } return dest; diff --git a/src/dsync/dsync-data.h b/src/dsync/dsync-data.h index c80fbf0089..3f028c7fbd 100644 --- a/src/dsync/dsync-data.h +++ b/src/dsync/dsync-data.h @@ -28,7 +28,7 @@ struct dsync_mailbox { otherwise it's the last rename timestamp. */ time_t last_change; enum dsync_mailbox_flags flags; - ARRAY_TYPE(const_string) cache_fields; + ARRAY_TYPE(mailbox_cache_field) cache_fields; }; ARRAY_DEFINE_TYPE(dsync_mailbox, struct dsync_mailbox *); #define dsync_mailbox_is_noselect(dsync_box) \ diff --git a/src/dsync/dsync-proxy-client.c b/src/dsync/dsync-proxy-client.c index 6b002aa635..ae32b0a2bb 100644 --- a/src/dsync/dsync-proxy-client.c +++ b/src/dsync/dsync-proxy-client.c @@ -893,7 +893,7 @@ proxy_client_worker_update_mailbox(struct dsync_worker *_worker, static void proxy_client_worker_select_mailbox(struct dsync_worker *_worker, const mailbox_guid_t *mailbox, - const ARRAY_TYPE(const_string) *cache_fields) + const ARRAY_TYPE(mailbox_cache_field) *cache_fields) { struct proxy_client_dsync_worker *worker = (struct proxy_client_dsync_worker *)_worker; @@ -908,7 +908,7 @@ proxy_client_worker_select_mailbox(struct dsync_worker *_worker, str_append(str, "BOX-SELECT\t"); dsync_proxy_mailbox_guid_export(str, mailbox); if (cache_fields != NULL) - dsync_proxy_strings_export(str, cache_fields); + dsync_proxy_cache_fields_export(str, cache_fields); str_append_c(str, '\n'); proxy_client_worker_cmd(worker, str); } T_END; diff --git a/src/dsync/dsync-proxy-server-cmd.c b/src/dsync/dsync-proxy-server-cmd.c index f1549a9e92..d090778796 100644 --- a/src/dsync/dsync-proxy-server-cmd.c +++ b/src/dsync/dsync-proxy-server-cmd.c @@ -315,7 +315,7 @@ static int cmd_box_select(struct dsync_proxy_server *server, const char *const *args) { struct dsync_mailbox box; - unsigned int i, count; + const char *error; memset(&box, 0, sizeof(box)); if (args[0] == NULL || @@ -325,10 +325,11 @@ cmd_box_select(struct dsync_proxy_server *server, const char *const *args) } args++; - count = str_array_length(args); - t_array_init(&box.cache_fields, count + 1); - for (i = 0; i < count; i++) - array_append(&box.cache_fields, &args[i], 1); + if (dsync_proxy_cache_fields_import(args, pool_datastack_create(), + &box.cache_fields, &error) < 0) { + i_error("box-select: %s", error); + return -1; + } dsync_worker_select_mailbox(server->worker, &box); return 1; } diff --git a/src/dsync/dsync-proxy.c b/src/dsync/dsync-proxy.c index bab578c0f4..a2535accd8 100644 --- a/src/dsync/dsync-proxy.c +++ b/src/dsync/dsync-proxy.c @@ -8,25 +8,102 @@ #include "hex-binary.h" #include "mail-types.h" #include "imap-util.h" +#include "mail-cache.h" #include "dsync-data.h" #include "dsync-proxy.h" #include -void dsync_proxy_strings_export(string_t *str, - const ARRAY_TYPE(const_string) *strings) +#define DSYNC_CACHE_DECISION_NO 'n' +#define DSYNC_CACHE_DECISION_YES 'y' +#define DSYNC_CACHE_DECISION_TEMP 't' +#define DSYNC_CACHE_DECISION_FORCED 'f' + +void dsync_proxy_cache_fields_export(string_t *str, + const ARRAY_TYPE(mailbox_cache_field) *_fields) { - const char *const *fields; + const struct mailbox_cache_field *fields; unsigned int i, count; - if (!array_is_created(strings)) + if (!array_is_created(_fields)) return; - fields = array_get(strings, &count); + fields = array_get(_fields, &count); for (i = 0; i < count; i++) { str_append_c(str, '\t'); - str_tabescape_write(str, fields[i]); + str_tabescape_write(str, fields[i].name); + str_append_c(str, '\t'); + switch (fields[i].decision & ~MAIL_CACHE_DECISION_FORCED) { + case MAIL_CACHE_DECISION_NO: + str_append_c(str, DSYNC_CACHE_DECISION_NO); + break; + case MAIL_CACHE_DECISION_YES: + str_append_c(str, DSYNC_CACHE_DECISION_YES); + break; + case MAIL_CACHE_DECISION_TEMP: + str_append_c(str, DSYNC_CACHE_DECISION_TEMP); + break; + } + if ((fields[i].decision & MAIL_CACHE_DECISION_FORCED) != 0) + str_append_c(str, DSYNC_CACHE_DECISION_FORCED); + str_printfa(str, "\t%ld", fields[i].last_used); + } +} + +static int dsync_proxy_cache_dec_parse(const char *str, + enum mail_cache_decision_type *dec_r) +{ + switch (*str++) { + case DSYNC_CACHE_DECISION_NO: + *dec_r = MAIL_CACHE_DECISION_NO; + break; + case DSYNC_CACHE_DECISION_YES: + *dec_r = MAIL_CACHE_DECISION_YES; + break; + case DSYNC_CACHE_DECISION_TEMP: + *dec_r = MAIL_CACHE_DECISION_TEMP; + break; + default: + return -1; + } + if (*str == DSYNC_CACHE_DECISION_FORCED) { + *dec_r |= MAIL_CACHE_DECISION_FORCED; + str++; + } + if (*str != '\0') + return -1; + return 0; +} + +int dsync_proxy_cache_fields_import(const char *const *args, pool_t pool, + ARRAY_TYPE(mailbox_cache_field) *fields, + const char **error_r) +{ + struct mailbox_cache_field *cache_field; + enum mail_cache_decision_type dec; + unsigned int i, count = str_array_length(args); + + if (count % 3 != 0) { + *error_r = "Invalid mailbox cache fields"; + return -1; + } + if (!array_is_created(fields)) + p_array_init(fields, pool, (count/3) + 1); + for (i = 0; i < count; i += 3) { + cache_field = array_append_space(fields); + cache_field->name = p_strdup(pool, args[i]); + + if (dsync_proxy_cache_dec_parse(args[i+1], &dec) < 0) { + *error_r = "Invalid cache decision"; + return -1; + } + cache_field->decision = dec; + if (str_to_time(args[i+2], &cache_field->last_used) < 0) { + *error_r = "Invalid cache last_used"; + return -1; + } } + return 0; } void dsync_proxy_msg_export(string_t *str, @@ -178,7 +255,7 @@ void dsync_proxy_mailbox_export(string_t *str, box->uid_validity, box->uid_next, box->message_count, (unsigned long long)box->highest_modseq, box->first_recent_uid); - dsync_proxy_strings_export(str, &box->cache_fields); + dsync_proxy_cache_fields_export(str, &box->cache_fields); } int dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args, @@ -270,11 +347,9 @@ int dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args, args += i; count -= i; - p_array_init(&box_r->cache_fields, pool, count + 1); - for (i = 0; i < count; i++) { - const char *field_name = p_strdup(pool, args[i]); - array_append(&box_r->cache_fields, &field_name, 1); - } + if (dsync_proxy_cache_fields_import(args, pool, &box_r->cache_fields, + error_r) < 0) + return -1; return 0; } diff --git a/src/dsync/dsync-proxy.h b/src/dsync/dsync-proxy.h index 063a9f3369..b4ea94b520 100644 --- a/src/dsync/dsync-proxy.h +++ b/src/dsync/dsync-proxy.h @@ -6,14 +6,17 @@ #define DSYNC_PROXY_CLIENT_TIMEOUT_MSECS (14*60*1000) #define DSYNC_PROXY_SERVER_TIMEOUT_MSECS (15*60*1000) -#define DSYNC_PROXY_CLIENT_GREETING_LINE "dsync-client\t1" -#define DSYNC_PROXY_SERVER_GREETING_LINE "dsync-server\t1" +#define DSYNC_PROXY_CLIENT_GREETING_LINE "dsync-client\t2" +#define DSYNC_PROXY_SERVER_GREETING_LINE "dsync-server\t2" struct dsync_message; struct dsync_mailbox; -void dsync_proxy_strings_export(string_t *str, - const ARRAY_TYPE(const_string) *strings); +void dsync_proxy_cache_fields_export(string_t *str, + const ARRAY_TYPE(mailbox_cache_field) *fields); +int dsync_proxy_cache_fields_import(const char *const *args, pool_t pool, + ARRAY_TYPE(mailbox_cache_field) *fields, + const char **error_r); void dsync_proxy_msg_export(string_t *str, const struct dsync_message *msg); int dsync_proxy_msg_parse_flags(pool_t pool, const char *str, diff --git a/src/dsync/dsync-worker-local.c b/src/dsync/dsync-worker-local.c index c61ed505d0..7c642f2dd6 100644 --- a/src/dsync/dsync-worker-local.c +++ b/src/dsync/dsync-worker-local.c @@ -528,8 +528,8 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter, struct local_dsync_dir_change *dir_change, change_lookup; struct local_dsync_mailbox *old_lbox; enum mail_error error; - const char *const *fields; - unsigned int i, field_count; + struct mailbox_cache_field *cache_fields; + unsigned int i, cache_field_count; memset(dsync_box_r, 0, sizeof(*dsync_box_r)); @@ -595,12 +595,14 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter, dsync_box_r->highest_modseq = status.highest_modseq; p_clear(iter->ret_pool); - fields = array_get(metadata.cache_fields, &field_count); - p_array_init(&dsync_box_r->cache_fields, iter->ret_pool, field_count); - for (i = 0; i < field_count; i++) { - const char *field_name = p_strdup(iter->ret_pool, fields[i]); - - array_append(&dsync_box_r->cache_fields, &field_name, 1); + p_array_init(&dsync_box_r->cache_fields, iter->ret_pool, + array_count(metadata.cache_fields)); + array_append_array(&dsync_box_r->cache_fields, metadata.cache_fields); + cache_fields = array_get_modifiable(&dsync_box_r->cache_fields, + &cache_field_count); + for (i = 0; i < cache_field_count; i++) { + cache_fields[i].name = + p_strdup(iter->ret_pool, cache_fields[i].name); } old_lbox = hash_table_lookup(worker->mailbox_hash, @@ -1443,25 +1445,26 @@ local_worker_update_mailbox(struct dsync_worker *_worker, static void local_worker_set_cache_fields(struct local_dsync_worker *worker, - const ARRAY_TYPE(const_string) *cache_fields) + const ARRAY_TYPE(mailbox_cache_field) *cache_fields) { struct mailbox_update update; - const char *const *fields, **new_fields; + const struct mailbox_cache_field *fields; + struct mailbox_cache_field *new_fields; unsigned int count; fields = array_get(cache_fields, &count); - new_fields = t_new(const char *, count + 1); - memcpy(new_fields, fields, sizeof(const char *) * count); + new_fields = t_new(struct mailbox_cache_field, count + 1); + memcpy(new_fields, fields, sizeof(struct mailbox_cache_field) * count); memset(&update, 0, sizeof(update)); - update.cache_fields = new_fields; + update.cache_updates = new_fields; mailbox_update(worker->selected_box, &update); } static void local_worker_select_mailbox(struct dsync_worker *_worker, const mailbox_guid_t *mailbox, - const ARRAY_TYPE(const_string) *cache_fields) + const ARRAY_TYPE(mailbox_cache_field) *cache_fields) { struct local_dsync_worker *worker = (struct local_dsync_worker *)_worker; diff --git a/src/dsync/dsync-worker-private.h b/src/dsync/dsync-worker-private.h index 6cf1a05b38..a5cd65f56b 100644 --- a/src/dsync/dsync-worker-private.h +++ b/src/dsync/dsync-worker-private.h @@ -50,7 +50,7 @@ struct dsync_worker_vfuncs { void (*select_mailbox)(struct dsync_worker *worker, const mailbox_guid_t *mailbox, - const ARRAY_TYPE(const_string) *cache_fields); + const ARRAY_TYPE(mailbox_cache_field) *cache_fields); void (*msg_update_metadata)(struct dsync_worker *worker, const struct dsync_message *msg); void (*msg_update_uid)(struct dsync_worker *worker, diff --git a/src/dsync/test-dsync-common.c b/src/dsync/test-dsync-common.c index 9f28d76615..ee0fb6c722 100644 --- a/src/dsync/test-dsync-common.c +++ b/src/dsync/test-dsync-common.c @@ -44,7 +44,7 @@ bool dsync_messages_equal(const struct dsync_message *m1, bool dsync_mailboxes_equal(const struct dsync_mailbox *box1, const struct dsync_mailbox *box2) { - const char *const *f1 = NULL, *const *f2 = NULL; + const struct mailbox_cache_field *f1 = NULL, *f2 = NULL; unsigned int i, f1_count = 0, f2_count = 0; if (strcmp(box1->name, box2->name) != 0 || @@ -63,7 +63,9 @@ bool dsync_mailboxes_equal(const struct dsync_mailbox *box1, if (f1_count != f2_count) return FALSE; for (i = 0; i < f1_count; i++) { - if (strcmp(f1[i], f2[i]) != 0) + if (strcmp(f1[i].name, f2[i].name) != 0 || + f1[i].decision != f2[i].decision || + f1[i].last_used != f2[i].last_used) return FALSE; } return TRUE; diff --git a/src/dsync/test-dsync-proxy.c b/src/dsync/test-dsync-proxy.c index 8dc4e06db9..6759fb43e6 100644 --- a/src/dsync/test-dsync-proxy.c +++ b/src/dsync/test-dsync-proxy.c @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "str.h" +#include "mail-cache.h" #include "dsync-proxy.h" #include "test-dsync-common.h" #include "test-common.h" @@ -85,8 +86,10 @@ static void test_dsync_proxy_msg(void) static void test_dsync_proxy_mailbox(void) { - static const char *cache1 = "cache1"; - static const char *cache2 = "cache2"; + static struct mailbox_cache_field cache1 = + { "cache1", MAIL_CACHE_DECISION_NO, 1234 }; + static struct mailbox_cache_field cache2 = + { "cache2", MAIL_CACHE_DECISION_TEMP | MAIL_CACHE_DECISION_FORCED, 0 }; string_t *str; struct dsync_mailbox box_in, box_out; const char *error; diff --git a/src/dsync/test-dsync-worker.c b/src/dsync/test-dsync-worker.c index e7026cdb16..363738e4d7 100644 --- a/src/dsync/test-dsync-worker.c +++ b/src/dsync/test-dsync-worker.c @@ -285,7 +285,7 @@ test_worker_update_mailbox(struct dsync_worker *_worker, static void test_worker_select_mailbox(struct dsync_worker *_worker, const mailbox_guid_t *mailbox, - const ARRAY_TYPE(const_string) *cache_fields) + const ARRAY_TYPE(mailbox_cache_field) *cache_fields) { struct test_dsync_worker *worker = (struct test_dsync_worker *)_worker; struct dsync_mailbox box; diff --git a/src/dsync/test-dsync-worker.h b/src/dsync/test-dsync-worker.h index f2ce6bf0a0..c313552c3f 100644 --- a/src/dsync/test-dsync-worker.h +++ b/src/dsync/test-dsync-worker.h @@ -83,7 +83,7 @@ struct test_dsync_worker { mailbox_guid_t selected_mailbox; mailbox_guid_t *msg_iter_mailboxes; unsigned int msg_iter_mailbox_count; - const ARRAY_TYPE(const_string) *cache_fields; + const ARRAY_TYPE(mailbox_cache_field) *cache_fields; }; struct dsync_worker *dsync_worker_init_test(void); diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage.c b/src/lib-storage/index/dbox-multi/mdbox-storage.c index cd52964661..fa4b2e3116 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c @@ -401,8 +401,8 @@ mdbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update) if (mailbox_open(box) < 0) return -1; } - if (update->cache_fields != NULL) - index_storage_mailbox_update_cache_fields(box, update); + if (update->cache_updates != NULL) + index_storage_mailbox_update_cache(box, update); return mdbox_write_index_header(box, update, NULL); } diff --git a/src/lib-storage/index/dbox-single/sdbox-storage.c b/src/lib-storage/index/dbox-single/sdbox-storage.c index bc57af6c34..4600f8e738 100644 --- a/src/lib-storage/index/dbox-single/sdbox-storage.c +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c @@ -287,8 +287,8 @@ dbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update) if (mailbox_open(box) < 0) return -1; } - if (update->cache_fields != NULL) - index_storage_mailbox_update_cache_fields(box, update); + if (update->cache_updates != NULL) + index_storage_mailbox_update_cache(box, update); return sdbox_mailbox_create_indexes(box, update, NULL); } diff --git a/src/lib-storage/index/index-status.c b/src/lib-storage/index/index-status.c index 48ad258d3f..8871ca0bef 100644 --- a/src/lib-storage/index/index-status.c +++ b/src/lib-storage/index/index-status.c @@ -94,18 +94,23 @@ get_metadata_cache_fields(struct mailbox *box, { const struct mail_cache_field *fields; enum mail_cache_decision_type dec; - ARRAY_TYPE(const_string) *cache_fields; + ARRAY_TYPE(mailbox_cache_field) *cache_fields; + struct mailbox_cache_field *cf; unsigned int i, count; fields = mail_cache_register_get_list(box->cache, pool_datastack_create(), &count); - cache_fields = t_new(ARRAY_TYPE(const_string), 1); + cache_fields = t_new(ARRAY_TYPE(mailbox_cache_field), 1); t_array_init(cache_fields, 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); + if (dec != MAIL_CACHE_DECISION_NO) { + cf = array_append_space(cache_fields); + cf->name = fields[i].name; + cf->decision = fields[i].decision; + cf->last_used = fields[i].last_used; + } } metadata_r->cache_fields = cache_fields; } diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 9b55c9e478..77000cc723 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -353,10 +353,10 @@ void index_storage_mailbox_free(struct mailbox *box) mail_index_alloc_cache_unref(&box->index); } -void index_storage_mailbox_update_cache_fields(struct mailbox *box, - const struct mailbox_update *update) +void index_storage_mailbox_update_cache(struct mailbox *box, + const struct mailbox_update *update) { - const char *const *field_names = update->cache_fields; + const struct mailbox_cache_field *updates = update->cache_updates; ARRAY_DEFINE(new_fields, struct mail_cache_field); const struct mail_cache_field *old_fields; struct mail_cache_field field; @@ -368,28 +368,28 @@ void index_storage_mailbox_update_cache_fields(struct mailbox *box, /* 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++) { + for (i = 0; updates[i].name != 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) + if (strcmp(updates[i].name, old_fields[j].name) == 0) break; } if (j != old_count) { field = old_fields[j]; - 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) { + } else if (strncmp(updates[i].name, "hdr.", 4) == 0) { /* new header */ memset(&field, 0, sizeof(field)); - field.name = field_names[i]; + field.name = updates[i].name; 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 */ + continue; } + field.decision = updates[i].decision; + if (updates[i].last_used != (time_t)-1) + field.last_used = updates[i].last_used; + array_append(&new_fields, &field, 1); } if (array_count(&new_fields) > 0) { mail_cache_register_fields(box->cache, @@ -408,8 +408,8 @@ int index_storage_mailbox_update(struct mailbox *box, if (mailbox_open(box) < 0) return -1; - if (update->cache_fields != NULL) - index_storage_mailbox_update_cache_fields(box, update); + if (update->cache_updates != NULL) + index_storage_mailbox_update_cache(box, update); /* make sure we get the latest index info */ (void)mail_index_refresh(box->index); @@ -641,7 +641,7 @@ void index_copy_cache_fields(struct mail_save_context *ctx, { T_BEGIN { struct mailbox_metadata src_metadata; - const char *const *namep; + const struct mailbox_cache_field *field; buffer_t *buf; if (mailbox_get_metadata(src_mail->box, @@ -650,9 +650,9 @@ void index_copy_cache_fields(struct mail_save_context *ctx, i_unreached(); buf = buffer_create_dynamic(pool_datastack_create(), 1024); - array_foreach(src_metadata.cache_fields, namep) { + array_foreach(src_metadata.cache_fields, field) { mail_copy_cache_field(ctx, src_mail, dest_seq, - *namep, buf); + field->name, buf); } } T_END; } diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index 2e4a38eb16..eb7106fed4 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -69,8 +69,8 @@ void index_storage_mailbox_close(struct mailbox *box); void index_storage_mailbox_free(struct mailbox *box); int index_storage_mailbox_update(struct mailbox *box, const struct mailbox_update *update); -void index_storage_mailbox_update_cache_fields(struct mailbox *box, - const struct mailbox_update *update); +void index_storage_mailbox_update_cache(struct mailbox *box, + const struct mailbox_update *update); int index_storage_mailbox_delete(struct mailbox *box); int index_storage_mailbox_delete_dir(struct mailbox *box, bool mailbox_deleted); int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest, diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index ae42d19914..9bf156691b 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -225,12 +225,20 @@ struct mailbox_status { unsigned int allow_new_keywords:1; }; +struct mailbox_cache_field { + const char *name; + int decision; /* enum mail_cache_decision_type */ + /* last_used is unchanged, if it's (time_t)-1 */ + time_t last_used; +}; +ARRAY_DEFINE_TYPE(mailbox_cache_field, struct mailbox_cache_field); + struct mailbox_metadata { guid_128_t guid; /* sum of virtual size of all messages in mailbox */ uint64_t virtual_size; /* Fields that have "temp" or "yes" caching decision. */ - const ARRAY_TYPE(const_string) *cache_fields; + const ARRAY_TYPE(mailbox_cache_field) *cache_fields; /* Fields that should be precached */ enum mail_fetch_field precache_fields; }; @@ -242,8 +250,8 @@ struct mailbox_update { uint32_t min_next_uid; uint32_t min_first_recent_uid; uint64_t min_highest_modseq; - /* Add these fields to be temporarily cached, if they aren't already. */ - const char *const *cache_fields; + /* Modify caching decisions, terminated by name=NULL */ + const struct mailbox_cache_field *cache_updates; }; struct mail_transaction_commit_changes {