mailbox-list-index-status.c revision b09c165ba23e432685cee196b42873af26f1785f
/* Copyright (c) 2006-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "mail-index-modseq.h"
#include "mailbox-list-index-storage.h"
#include "mailbox-list-index.h"
#define CACHED_STATUS_ITEMS \
struct index_list_changes {
struct mailbox_status status;
bool rec_changed;
bool msgs_changed;
bool hmodseq_changed;
};
static int
{
struct mailbox_list_index_node *node;
struct mail_index_view *view;
int ret;
return -1;
/* mailbox not found */
return 0;
}
/* our in-memory tree is out of sync */
ret = 1;
} else T_BEGIN {
} T_END;
if (ret != 0) {
/* error / mailbox has changed. we'll need to sync it. */
if (ret < 0)
else
return ret < 0 ? -1 : 0;
}
return 1;
}
static int
enum mailbox_existence *existence_r)
{
struct mail_index_view *view;
const struct mail_index_record *rec;
int ret;
/* failure / not found. fallback to the real storage check
just in case to see if the mailbox was just created. */
}
if ((flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
else if ((flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0)
else
return 0;
}
struct mail_index_view *view,
struct mailbox_status *status_r,
{
const void *data;
bool expunged;
const struct mailbox_list_index_record *rec;
else {
if ((items & STATUS_UIDVALIDITY) != 0 &&
rec->uid_validity == 0)
else
if (mailbox_guid != NULL)
}
}
STATUS_RECENT | STATUS_UIDNEXT)) != 0) {
const struct mailbox_list_index_msgs_record *rec;
else {
}
}
if ((items & STATUS_HIGHESTMODSEQ) != 0) {
else
}
return ret;
}
static int
enum mailbox_status_items items,
struct mailbox_status *status_r)
{
struct mail_index_view *view;
int ret;
if ((items & STATUS_UNSEEN) != 0 &&
/* can't get UNSEEN from list index, since each user has
different \Seen flags */
return 0;
}
return ret;
return ret;
}
static int
struct mailbox_status *status_r)
{
return 0;
/* nonsynced / error, fallback to doing it the slow way */
}
}
static int
{
struct mailbox_status status;
struct mail_index_view *view;
int ret;
/* syncing wants to know the GUID for a new mailbox. */
return 0;
}
return ret;
ret = 0;
return ret;
}
static int
enum mailbox_metadata_items items,
struct mailbox_metadata *metadata_r)
{
return 0;
/* nonsynced / error, fallback to doing it the slow way */
}
}
static bool
struct mail_index_view *list_view,
struct index_list_changes *changes_r)
{
struct mailbox_list_index_node *node;
struct mail_index_view *view;
const struct mail_index_header *hdr;
struct mailbox_metadata metadata;
return FALSE;
return FALSE;
/* get STATUS info using the latest data in index.
note that for shared mailboxes (with private indexes) this
also means that the unseen count is always the owner's
count, not what exists in the private index. */
else
/* modseqs not enabled yet, but we can't return 0 */
}
return TRUE;
}
static bool
struct index_list_changes *changes)
{
struct mailbox_status old_status;
&old_status, old_guid);
/* update highest-modseq only if they're ever been used */
} else {
const void *data;
bool expunged;
}
if (changes->hmodseq_changed &&
}
static void
struct mail_index_transaction *list_trans,
const struct index_list_changes *changes)
{
if (changes->rec_changed) {
struct mailbox_list_index_record rec;
const void *old_data;
bool expunged;
}
if (changes->msgs_changed) {
struct mailbox_list_index_msgs_record msgs;
}
if (changes->hmodseq_changed) {
}
}
{
struct mail_index_sync_ctx *list_sync_ctx;
struct mail_index_view *list_view;
struct mail_index_transaction *list_trans;
struct index_list_changes changes;
int ret;
return 0;
/* refresh the mailbox list index once. we can't do this again after
locking, because it could trigger list syncing. */
/* first do a quick check while unlocked to see if anything changes */
ret = -1;
ret = 1;
else {
/* if backend state changed on the last check, update it here
now. we probably don't need to bother checking again if the
state had changed? */
}
if (ret <= 0) {
if (ret < 0)
return 0;
}
/* looks like there are some changes. now lock the list index and do
the whole thing all over again while locked. this guarantees
that we'll always write the latest state of the mailbox. */
&list_view, &list_trans, 0) < 0) {
return -1;
}
/* refresh to latest state of the mailbox now that we're locked */
return -1;
}
else {
}
}
if (mail_index_sync_commit(&list_sync_ctx) < 0) {
return -1;
}
return 0;
}
const struct mailbox_update *update)
{
struct mail_index_view *list_view;
struct mail_index_transaction *list_trans;
struct index_list_changes changes;
struct mailbox_status status;
bool guid_changed = FALSE;
int ret;
return;
if (update->uid_validity != 0) {
}
guid_changed = TRUE;
}
if (guid_changed ||
update->uid_validity != 0 ||
update->min_next_uid != 0 ||
update->min_first_recent_uid != 0 ||
update->min_highest_modseq != 0) {
/* reset status counters to 0. let the syncing later figure out
their correct values. */
}
(void)mail_index_transaction_commit(&list_trans);
}
struct mailbox_sync_status *status_r)
{
return -1;
(void)index_list_update_mailbox(box);
return 0;
}
static int
struct mail_transaction_commit_changes *changes_r)
{
return -1;
t = NULL;
(void)index_list_update_mailbox(box);
return 0;
}
enum mailbox_info_flags *flags)
{
struct mail_index_view *view;
struct mailbox_status status;
int ret;
/* our in-memory tree is out of sync */
ret = 1;
} else T_BEGIN {
} T_END;
if (ret != 0) {
/* error / not up to date. don't waste time with it. */
return;
}
*flags |= MAILBOX_MARKED;
else
*flags |= MAILBOX_UNMARKED;
}
{
}
{
sizeof(struct mailbox_list_index_msgs_record),
sizeof(uint32_t));
}