mailbox-guid-cache.c revision 6feb0ff583c425dbe5b77ad99bc5ecbd2e508f29
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2005-2011 Dovecot authors, see the included COPYING file */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#include "lib.h"
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#include "hash.h"
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#include "mail-storage.h"
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#include "mailbox-list-private.h"
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#include "mailbox-guid-cache.h"
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenstruct mailbox_guid_cache_rec {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen uint8_t guid[MAIL_GUID_128_SIZE];
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const char *vname;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen};
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenstatic unsigned int guid_cache_rec_hash(const void *_rec)
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen{
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const struct mailbox_guid_cache_rec *rec = _rec;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen return mem_hash(rec->guid, sizeof(rec->guid));
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen}
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenstatic int guid_cache_rec_cmp(const void *_r1, const void *_r2)
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen{
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const struct mailbox_guid_cache_rec *r1 = _r1, *r2 = _r2;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen return memcmp(r1->guid, r2->guid, sizeof(r1->guid));
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen}
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenint mailbox_guid_cache_find(struct mailbox_list *list,
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen uint8_t guid[MAIL_GUID_128_SIZE],
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const char **vname_r)
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen{
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const struct mailbox_guid_cache_rec *rec;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct mailbox_guid_cache_rec lookup_rec;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen memcpy(lookup_rec.guid, guid, sizeof(lookup_rec.guid));
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen if (list->guid_cache == NULL) {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen mailbox_guid_cache_refresh(list);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen rec = hash_table_lookup(list->guid_cache, &lookup_rec);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen } else {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen rec = hash_table_lookup(list->guid_cache, &lookup_rec);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen if (rec == NULL) {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen mailbox_guid_cache_refresh(list);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen rec = hash_table_lookup(list->guid_cache, &lookup_rec);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen }
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen }
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen if (rec == NULL) {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen *vname_r = NULL;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen return list->guid_cache_errors ? -1 : 0;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen }
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen *vname_r = rec->vname;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen return 0;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen}
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenvoid mailbox_guid_cache_refresh(struct mailbox_list *list)
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen{
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct mailbox_list_iterate_context *ctx;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const struct mailbox_info *info;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct mailbox *box;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct mailbox_metadata metadata;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct mailbox_guid_cache_rec *rec;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen if (list->guid_cache == NULL) {
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen list->guid_cache_pool =
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen pool_alloconly_create("guid cache", 1024*16);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen list->guid_cache = hash_table_create(default_pool,
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen list->guid_cache_pool, 0,
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen guid_cache_rec_hash,
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen guid_cache_rec_cmp);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen } else {
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen hash_table_clear(list->guid_cache, TRUE);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen p_clear(list->guid_cache_pool);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen }
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen list->guid_cache_errors = FALSE;
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen ctx = mailbox_list_iter_init(list, "*",
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen while ((info = mailbox_list_iter_next(ctx)) != NULL) {
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen if ((info->flags &
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) != 0)
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen continue;
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen box = mailbox_alloc(list, info->name, MAILBOX_FLAG_KEEP_RECENT);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID,
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen &metadata) < 0) {
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen i_error("Couldn't get mailbox %s GUID: %s",
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen info->name, mailbox_get_last_error(box, NULL));
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen list->guid_cache_errors = TRUE;
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen } else {
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen rec = p_new(list->guid_cache_pool,
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen struct mailbox_guid_cache_rec, 1);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen memcpy(rec->guid, metadata.guid, sizeof(rec->guid));
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen rec->vname = p_strdup(list->guid_cache_pool, info->name);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen hash_table_insert(list->guid_cache, rec, rec);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen }
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen mailbox_free(&box);
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen }
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen if (mailbox_list_iter_deinit(&ctx) < 0)
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen list->guid_cache_errors = TRUE;
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen}
108340ffacae3b7d09fa51b566d77aa51dd6483bTimo Sirainen