mail-index-view-sync.c revision d6f50f100ce17fa4b3a89e9567a5ff993b38b872
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (C) 2003-2004 Timo Sirainen */
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainenview_sync_get_expunges(struct mail_index_view *view, buffer_t **expunges_r)
ef2b2ef2e6a6eb5e4667f2e63faae8a3b646e8baTimo Sirainen struct mail_transaction_expunge *src, *src_end, *dest;
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen *expunges_r = buffer_create_dynamic(default_pool, 512, (size_t)-1);
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainen /* with mask 0 we don't get anything, we'll just read the expunges
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainen while seeking to end */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainen mail_transaction_log_sort_expunges(*expunges_r,
4ea6c43a08b37f270bd54b5809142246fd118263Timo Sirainen /* convert to sequences */
bf9ea5404a0094a8fb8199b677d81f803512c44eTimo Sirainen src = dest = buffer_get_modifyable_data(*expunges_r, &size);
2e07e3182f355cf04a1461dd7f893d0ebc818764Timo Sirainen ret = mail_index_lookup_uid_range(view, src->uid1,
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen (MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
7d87a87b360ecac47fe10e7ca5c7e1433dd63004Timo Sirainen /* We must sync flags as long as view is mmap()ed, as the flags may
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen have already changed under us. */
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_assert((sync_mask & MAIL_INDEX_SYNC_TYPE_FLAGS) != 0);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (mail_index_view_lock_head(view, TRUE) < 0)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
10ccd0e45768923d69be459e87ef6cd2574cec60Timo Sirainen /* get list of all expunges first */
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen if (view_sync_get_expunges(view, &expunges) < 0)
4145cbac82bfc0c8bfeceeca0ef841700117930cTimo Sirainen /* only flags, appends and expunges can be left to be synced later */
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen want_mask = mail_transaction_type_mask_get(sync_mask);
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainen i_assert((want_mask & ~MAIL_INDEX_VIEW_VISIBLE_SYNC_MASK) == 0);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
f4e66312c54f8f21df984e3b17c0cc752e019ec5Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
f4e66312c54f8f21df984e3b17c0cc752e019ec5Timo Sirainen /* keep the old mapping without expunges until we're
d337f4291d9ea9cd1adee0f468bc0c3baeabb4feTimo Sirainen fully synced */
d337f4291d9ea9cd1adee0f468bc0c3baeabb4feTimo Sirainen /* we need a private copy of the map if we don't want to
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen sync expunges */
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainenstatic int view_is_transaction_synced(struct mail_index_view *view,
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen data = buffer_get_data(view->log_syncs, &size);
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen *((const uint32_t *)(data + sizeof(uoff_t))) == seq)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstatic int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
f4e66312c54f8f21df984e3b17c0cc752e019ec5Timo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr, &ctx->data,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, seq_r, offset_r);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* skip flag changes that we committed ourself or have already synced */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (view_is_transaction_synced(view, *seq_r, *offset_r))
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* expunges have to be synced afterwards so that caller can still get
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen information of the messages. otherwise caller most likely wants to
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen see only updated information. */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen (ctx->hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0) {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen memset(&sync_map_ctx, 0, sizeof(sync_map_ctx));
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (mail_transaction_map(view->index, ctx->hdr, ctx->data,
2521fd0986302cdabc8b0711eef63ac188f32cd6Timo Sirainen if ((ctx->hdr->type & ctx->trans_sync_mask) == 0)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen (((u)->add_flags | (u)->remove_flags) == MAIL_INDEX_MAIL_FLAG_DIRTY && \
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen memcmp((u)->add_keywords, empty, INDEX_KEYWORDS_BYTE_COUNT) == 0 && \
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen memcmp((u)->add_keywords, empty, INDEX_KEYWORDS_BYTE_COUNT) == 0)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenmail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen static keywords_mask_t empty_keywords = { 0, };
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen const struct mail_transaction_header *hdr = ctx->hdr;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
cd2cd224d3216a243d55c71c298a5b7684de0ac4Timo Sirainen const struct mail_transaction_flag_update *update =
f8da06de93e28b5d3e039a427cdde7e1e15daec8Timo Sirainen if (!FLAG_UPDATE_IS_INTERNAL(update, empty_keywords))
int ret;
&offset);
if (ret < 0)
} while (ret == 0);
seq,
offset);
const uint32_t *
return data;
sizeof(log_file_offset));