mailbox-guid-cache.c revision 402e999a878e0cc41a0afb830fea0a93afc75f0d
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen#include "lib.h"
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen#include "hash.h"
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen#include "mail-storage.h"
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen#include "mailbox-list-private.h"
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen#include "mailbox-guid-cache.h"
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainenstruct mailbox_guid_cache_rec {
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen guid_128_t guid;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen const char *vname;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen};
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainenint mailbox_guid_cache_find(struct mailbox_list *list,
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen const guid_128_t guid, const char **vname_r)
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen{
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen const struct mailbox_guid_cache_rec *rec;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if (list->guid_cache == NULL) {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen mailbox_guid_cache_refresh(list);
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen rec = hash_table_lookup(list->guid_cache, guid);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen } else {
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen rec = hash_table_lookup(list->guid_cache, guid);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if (rec == NULL) {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen mailbox_guid_cache_refresh(list);
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen rec = hash_table_lookup(list->guid_cache, guid);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen }
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen }
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if (rec == NULL) {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen *vname_r = NULL;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen return list->guid_cache_errors ? -1 : 0;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen }
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen *vname_r = rec->vname;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen return 0;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen}
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainenvoid mailbox_guid_cache_refresh(struct mailbox_list *list)
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen{
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen struct mailbox_list_iterate_context *ctx;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen const struct mailbox_info *info;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen struct mailbox *box;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen struct mailbox_metadata metadata;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen struct mailbox_guid_cache_rec *rec;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if (list->guid_cache == NULL) {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen list->guid_cache_pool =
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen pool_alloconly_create("guid cache", 1024*16);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen list->guid_cache = hash_table_create(default_pool,
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen list->guid_cache_pool, 0,
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen guid_128_hash,
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen guid_128_cmp);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen } else {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen hash_table_clear(list->guid_cache, TRUE);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen p_clear(list->guid_cache_pool);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen }
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen list->guid_cache_errors = FALSE;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen ctx = mailbox_list_iter_init(list, "*",
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen while ((info = mailbox_list_iter_next(ctx)) != NULL) {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if ((info->flags &
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) != 0)
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen continue;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen box = mailbox_alloc(list, info->vname, 0);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID,
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen &metadata) < 0) {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen i_error("Couldn't get mailbox %s GUID: %s",
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen info->vname, mailbox_get_last_error(box, NULL));
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen list->guid_cache_errors = TRUE;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen } else {
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen rec = p_new(list->guid_cache_pool,
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen struct mailbox_guid_cache_rec, 1);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen memcpy(rec->guid, metadata.guid, sizeof(rec->guid));
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen rec->vname = p_strdup(list->guid_cache_pool, info->vname);
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen hash_table_insert(list->guid_cache, rec->guid, rec);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen }
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen mailbox_free(&box);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen }
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if (mailbox_list_iter_deinit(&ctx) < 0)
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen list->guid_cache_errors = TRUE;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen}