mail-index-transaction.c revision 07e80e04c8876b6bf3f95266f48b41e1a681e445
/* Copyright (c) 2003-2010 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);
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;
}
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;
}
}
/* update sync_offset */
(uoff_t)-1) <= 0)
return -1;
}
return 1;
}
static int
{
struct mail_transaction_log_append_ctx *ctx;
int ret;
return -1;
if (ret > 0) {
if (ret == 0)
}
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). */
(void)mail_index_refresh(index);
}
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) {
/* 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;
}