mail-index-view-sync.c revision 8afec4d1a32b78f540257a27769b372aad753384
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi/* Copyright (C) 2003-2004 Timo Sirainen */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi enum mail_transaction_type visible_sync_mask;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi array_t ARRAY_DEFINE(expunges, struct mail_transaction_expunge);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const struct mail_transaction_header *hdr;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvimail_transaction_log_sort_expunges(array_t *expunges,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const struct mail_transaction_expunge *src,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi ARRAY_SET_TYPE(expunges, struct mail_transaction_expunge);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const struct mail_transaction_expunge *src_end;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi dest = array_get_modifyable(expunges, &dest_count);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi array_append(expunges, src, src_size / sizeof(*src));
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi src_end = CONST_PTR_OFFSET(src, src_size);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* src[] must be sorted. */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi i_assert(src+1 == src_end || src->uid2 < src[1].uid1);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi for (; i < dest_count; i++) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi while (i < dest_count && src->uid2 >= dest[i].uid1-1) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* we can/must merge with next record */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (first > 0 && new_exp.uid1 <= dest[first-1].uid2+1) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* continue previous record */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi } else if (i == first) {
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi dest = array_get_modifyable(expunges, &dest_count);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen /* use next record */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi dest = array_get_modifyable(expunges, &dest_count);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomiview_sync_get_expunges(struct mail_index_view *view, array_t *expunges_r)
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi ARRAY_SET_TYPE(expunges_r, struct mail_transaction_expunge);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const struct mail_transaction_header *hdr;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi struct mail_transaction_expunge *src, *src_end, *dest;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (mail_transaction_log_view_set(view->log_view,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi while ((ret = mail_transaction_log_view_next(view->log_view,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi mail_transaction_log_sort_expunges(expunges_r, data, hdr->size);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi /* convert to sequences */
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi src = dest = array_get_modifyable(expunges_r, &count);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi ret = mail_index_lookup_uid_range(view, src->uid1,
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi array_delete(expunges_r, count, array_count(expunges_r) - count);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD | MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE)
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi (MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE | \
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomiint mail_index_view_sync_begin(struct mail_index_view *view,
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi enum mail_transaction_type log_get_mask, visible_mask;
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi /* We must sync flags as long as view is mmap()ed, as the flags may
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen have already changed under us. */
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen i_assert((sync_mask & MAIL_INDEX_VIEW_VISIBLE_FLAGS_MASK) ==
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen /* Currently we're not handling correctly expunges + no-appends case */
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen i_assert((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) == 0 ||
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen (sync_mask & MAIL_INDEX_SYNC_TYPE_APPEND) != 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (mail_index_view_lock_head(view, TRUE) < 0)
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen /* get list of all expunges first */
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen if (view_sync_get_expunges(view, &expunges) < 0)
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* only flags, appends and expunges can be left to be synced later */
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen visible_mask = mail_transaction_type_mask_get(sync_mask);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi i_assert((visible_mask & ~MAIL_TRANSACTION_VISIBLE_SYNC_MASK) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* we want to also get non-visible changes. especially because we use
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi the returned skipped-flag in mail_transaction_log_view_next() to
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi tell us if any visible changes were skipped. */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi log_get_mask = visible_mask | (MAIL_TRANSACTION_TYPE_MASK ^
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (mail_transaction_log_view_set(view->log_view,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi ctx = i_new(struct mail_index_view_sync_ctx, 1);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi mail_index_sync_map_init(&ctx->sync_map_ctx, view,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0 &&
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* keep the old mapping without expunges until we're
unsigned int i, count;
return FALSE;
for (i = 0; i < count; i++) {
return TRUE;
return FALSE;
if (ret <= 0) {
if (ret < 0)
if (skipped) {
MAIL_TRANSACTION_EXPUNGE) == 0);
#define FLAG_UPDATE_IS_INTERNAL(u) \
case MAIL_TRANSACTION_APPEND: {
case MAIL_TRANSACTION_EXPUNGE: {
case MAIL_TRANSACTION_FLAG_UPDATE: {
case MAIL_TRANSACTION_KEYWORD_UPDATE: {
case MAIL_TRANSACTION_KEYWORD_RESET: {
i_unreached();
int ret;
if (ret <= 0)
return ret;
const uint32_t *
unsigned int *count_r)
unsigned int i, count;
for (i = 0; i < count; i++) {