mail-index-transaction.c revision 4253a4a66323bc5ff1103af7d7f77fe7c78b9b2b
/* Copyright (c) 2003-2012 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "bsearch-insert-pos.h"
#include "mail-index-private.h"
#include "mail-transaction-log-private.h"
#include "mail-index-transaction-private.h"
#include <stdlib.h>
(struct mail_index_transaction *t) = NULL;
struct mail_index_view *
{
return t->view;
}
bool mail_index_transaction_is_expunged(struct mail_index_transaction *t,
{
struct mail_transaction_expunge_guid key;
if (!array_is_created(&t->expunges))
return FALSE;
if (t->expunges_nonsorted)
}
void mail_index_transaction_ref(struct mail_index_transaction *t)
{
t->refcount++;
}
{
struct mail_index_transaction *t = *_t;
if (--t->refcount > 0)
return;
array_free(&t->module_contexts);
if (t->latest_view != NULL)
mail_index_view_close(&t->view);
i_free(t);
}
{
unsigned int offset;
/* get next_uid from appends if they have UIDs. it's possible
that some appends have too low UIDs, they'll be caught
later. */
if (next_uid <= t->highest_append_uid)
}
if (t->post_hdr_mask[offset] != 0) {
hdr = (const void *)t->post_hdr_change;
}
if (t->pre_hdr_mask[offset] != 0) {
hdr = (const void *)t->pre_hdr_change;
}
return next_uid;
}
void mail_index_transaction_lookup_latest_keywords(struct mail_index_transaction *t,
{
/* seq points to the transaction's primary view */
/* get the latest keywords from the updated index, or fallback to the
primary view if the message is already expunged */
if (t->latest_view == NULL) {
}
else
}
static int
struct mail_transaction_log_append_ctx *ctx)
{
struct mail_transaction_log_file *file;
if (t->reset) {
/* Reset the whole index, preserving only indexid. Begin by
rotating the log. We don't care if we skip some non-synced
transactions. */
return -1;
if (!MAIL_INDEX_TRANSACTION_HAS_CHANGES(t)) {
/* we only wanted to reset */
return 0;
}
}
/* make sure we have everything mapped */
return -1;
return 1;
}
static int
{
struct mail_transaction_log_append_ctx *ctx;
enum mail_transaction_type trans_flags = 0;
int ret;
if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_SYNC) != 0)
return -1;
} T_END;
return -1;
if (t->reset) {
/* get rid of the old index. it might just confuse readers,
especially if it's broken. */
}
if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_HIDE) != 0 &&
log_offset1 != log_offset2) {
/* mark the area covered by this transaction hidden */
}
return 0;
}
static int mail_index_transaction_commit_v(struct mail_index_transaction *t,
{
bool changed;
int ret;
i_assert(t->first_new_seq >
/* if we're committing a normal transaction, we want to
have those changes in the index mapping immediately. this
is especially important when committing cache offset
updates.
however if we're syncing the index now, the mapping must
be done later as MAIL_INDEX_SYNC_HANDLER_FILE so that
expunge handlers get run for the newly expunged messages
(and sync handlers that require HANDLER_FILE as well). */
}
return ret;
}
static void mail_index_transaction_rollback_v(struct mail_index_transaction *t)
{
}
int mail_index_transaction_commit(struct mail_index_transaction **t)
{
return mail_index_transaction_commit_full(t, &result);
}
{
struct mail_index_transaction *t = *_t;
bool index_undeleted = t->index_undeleted;
if (mail_index_view_is_inconsistent(t->view)) {
return -1;
}
if (!index_undeleted && !t->commit_deleted_index) {
/* no further changes allowed */
return -1;
}
}
return -1;
if (index_undeleted) {
}
return 0;
}
{
struct mail_index_transaction *t = *_t;
t->v.rollback(t);
}
static struct mail_index_transaction_vfuncs trans_vfuncs = {
};
struct mail_index_transaction *
{
struct mail_index_transaction *t;
/* don't allow syncing view while there's ongoing transactions */
t->refcount = 1;
t->v = trans_vfuncs;
/* transaction view cannot work if new records are being added
in two places. make sure it doesn't happen. */
t->no_appends = TRUE;
} else {
t->first_new_seq =
}
return t;
}