index-sync.c revision 53cc097d3f8cd789f3c8fa0dfdd02bcda776230e
/* Copyright (c) 2002-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "seq-range-array.h"
#include "ioloop.h"
#include "array.h"
#include "index-sync-private.h"
struct index_storage_list_index_record {
};
{
enum mail_index_sync_flags sync_flags = 0;
return sync_flags;
}
enum mailbox_sync_flags flags)
{
if ((flags & MAILBOX_SYNC_FLAG_FAST) != 0 &&
return FALSE;
if ((flags & MAILBOX_SYNC_FLAG_FAST) != 0 &&
/* lib-lda is syncing the mailbox after saving a mail.
it only wants to find the new mail for potentially copying
to other mailboxes. that's mainly an optimization, and since
the mail was most likely already added to index we don't
need to do a full sync to find it. the main benefit here is
return FALSE;
}
return TRUE;
}
{
return;
"Recent flags state corrupted for mailbox %s",
ibox->recent_flags_count = 0;
}
}
struct mail_index_view *view,
{
}
}
{
}
{
/* can't trust the currently cached recent flags anymore */
ibox->recent_flags_count = 0;
ibox->recent_flags_prev_uid = 0;
}
{
const struct mail_index_header *hdr;
unsigned int i, count, recent_count;
return 0;
for (i = count; i > 0; ) {
i--;
break;
/* completely invisible to this view */
} else {
/* partially invisible */
break;
}
}
return recent_count;
}
static void
{
return;
}
}
{
struct mail_index_view_sync_rec sync_rec;
break;
} else {
}
break;
}
}
}
static void
{
/* remove expunged messages from flag updates */
}
/* remove flag updates from hidden updates */
&ctx->flag_updates);
}
struct mailbox_sync_context *
bool failed)
{
struct index_mailbox_sync_context *ctx;
struct index_mailbox_sync_pvt_context *pvt_ctx;
enum mail_index_view_sync_flags sync_flags = 0;
if (failed) {
}
if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
if ((flags & MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) != 0) {
ctx->messages_count = 0;
} else {
}
if ((flags & MAILBOX_SYNC_FLAG_FAST) != 0) {
/* we most likely did a fast sync. refresh the index anyway in
case there were some new changes. */
}
if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) {
}
/* sync private index if needed. it doesn't use box->view, so it
doesn't matter if it's called at _sync_init() or _sync_deinit().
however we also need to know if any private flags have changed
since last sync, so we need to call it before _sync_next() calls. */
&ctx->hidden_updates);
}
}
static bool
struct mailbox_sync_rec *sync_rec_r)
{
if (ctx->expunge_pos == 0)
return FALSE;
/* expunges is a sorted array of sequences. it's easiest for
us to print them from end to beginning. */
ctx->expunge_pos--;
return TRUE;
}
struct mailbox_sync_rec *sync_rec_r)
{
struct index_mailbox_sync_context *ctx =
(struct index_mailbox_sync_context *)_ctx;
unsigned int count;
return FALSE;
ctx->flag_update_idx++;
return TRUE;
}
/* hidden flag changes' MODSEQs still need to be returned */
ctx->hidden_update_idx++;
return TRUE;
}
}
}
static void
{
struct index_mailbox_context *ibox =
const struct mail_index_header *hdr;
return;
/* expunges array contained expunges for the messages that were already
visible in this view, but append+expunge would be invisible.
recent_flags may however contain the append UID, so we'll have to
remove it separately */
if (ctx->messages_count == 0)
uid = 0;
else {
return;
}
continue;
}
uid + 1,
}
#ifdef DEBUG
if (!mail_index_view_is_inconsistent(view)) {
unsigned int i, count;
for (i = 0; i < count; i++) {
break;
}
}
}
#endif
}
{
const struct mail_index_header *hdr;
}
}
}
struct mailbox_sync_status *status_r)
{
struct index_mailbox_sync_context *ctx =
(struct index_mailbox_sync_context *)_ctx;
struct mailbox_sync_rec sync_rec;
bool delayed_expunges = FALSE;
/* finish handling expunges, so we don't break when updating
recent flags */
/* convert sequences to uids before syncing view */
&delayed_expunges) < 0) {
ret = -1;
}
}
/* mailbox syncing didn't necessarily update our recent state */
}
/* update search results after private index is updated */
return ret;
}
{
if (!array_is_created(k1))
if (!array_is_created(k2))
return array_count(k1) == 0;
/* The arrays may not be sorted, but they usually are. Optimize for
the assumption that they are */
return FALSE;
for (i = 0; i < count1; i++) {
/* not found / unsorted array. check. */
for (j = 0; j < count1; j++) {
break;
}
if (j == count1)
return FALSE;
}
}
return TRUE;
}
{
enum mailbox_sync_type ret = 0;
if ((type & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0)
if ((type & (MAIL_INDEX_SYNC_TYPE_FLAGS |
return ret;
}
static uint32_t
{
"index sync", 0,
sizeof(struct index_storage_list_index_record),
sizeof(uint32_t));
}
return ibox->list_index_sync_ext_id;
}
struct mail_index_view *list_view,
{
const struct index_storage_list_index_record *rec;
const void *data;
bool expunged;
int ret;
return 1;
/* doesn't exist / not synced */
return 1;
}
return 0;
if (ret < 0)
return -1;
return 1;
"stat(%s) failed: %m", path);
return -1;
}
return 1;
return 0;
}
struct mail_index_transaction *trans,
{
struct mail_index_view *list_view;
const struct index_storage_list_index_record *old_rec;
const void *data;
bool expunged;
int ret;
return;
/* get the current record */
if (expunged)
return;
if (ret < 0)
return;
"stat(%s) failed: %m", path);
return;
}
}