mail-index-view-sync.c revision b032dc80e358f09893f09999f172ff12f5dbbb8e
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-view-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-sync-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-log.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-util.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_view_sync_ctx {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view;
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen enum mail_transaction_type trans_sync_mask;
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen struct mail_index_sync_map_ctx sync_map_ctx;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_t ARRAY_DEFINE(expunges, struct mail_transaction_expunge);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const void *data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t data_offset;
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen unsigned int skipped_some:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int last_read:1;
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen unsigned int sync_map_update:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainenstruct mail_index_view_log_sync_pos {
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen uint32_t log_file_seq;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen uoff_t log_file_offset;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen};
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainenstatic void
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainenmail_transaction_log_sort_expunges(array_t *expunges,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen const struct mail_transaction_expunge *src,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen size_t src_size)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen{
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen ARRAY_SET_TYPE(expunges, struct mail_transaction_expunge);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen const struct mail_transaction_expunge *src_end;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen struct mail_transaction_expunge *dest;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen struct mail_transaction_expunge new_exp;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen unsigned int first, i, dest_count;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i_assert(src_size % sizeof(*src) == 0);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* @UNSAFE */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest = array_get_modifyable(expunges, &dest_count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (dest_count == 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_append(expunges, src, src_size / sizeof(*src));
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen src_end = CONST_PTR_OFFSET(src, src_size);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (i = 0; src != src_end; src++) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* src[] must be sorted. */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i_assert(src+1 == src_end || src->uid2 < src[1].uid1);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i_assert(src->uid1 <= src->uid2);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (; i < dest_count; i++) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (src->uid1 < dest[i].uid1)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen break;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen new_exp = *src;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen first = i;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen while (i < dest_count && src->uid2 >= dest[i].uid1-1) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* we can/must merge with next record */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (new_exp.uid2 < dest[i].uid2)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen new_exp.uid2 = dest[i].uid2;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i++;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (first > 0 && new_exp.uid1 <= dest[first-1].uid2+1) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* continue previous record */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (dest[first-1].uid2 < new_exp.uid2)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest[first-1].uid2 = new_exp.uid2;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen } else if (i == first) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_insert(expunges, i, &new_exp, 1);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i++; first++;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest = array_get_modifyable(expunges, &dest_count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen } else {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* use next record */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest[first] = new_exp;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen first++;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (i > first) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_delete(expunges, first, i - first);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest = array_get_modifyable(expunges, &dest_count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i = first;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen}
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainenview_sync_get_expunges(struct mail_index_view *view, array_t *expunges_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen ARRAY_SET_TYPE(expunges_r, struct mail_transaction_expunge);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen const struct mail_transaction_header *hdr;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct mail_transaction_expunge *src, *src_end, *dest;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen const void *data;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen unsigned int count;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen int ret;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_file_seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_file_offset,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->index->hdr->log_file_seq,
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen view->index->hdr->log_file_int_offset,
659fe5d24825b160cae512538088020d97a60239Timo Sirainen MAIL_TRANSACTION_EXPUNGE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen ARRAY_CREATE(expunges_r, default_pool,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen struct mail_transaction_expunge, 64);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
659fe5d24825b160cae512538088020d97a60239Timo Sirainen &hdr, &data, NULL)) > 0) {
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen mail_transaction_log_sort_expunges(expunges_r, data, hdr->size);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen if (ret < 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_free(expunges_r);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen /* convert to sequences */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen src = dest = array_get_modifyable(expunges_r, &count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen src_end = src + count;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen for (; src != src_end; src++) {
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen ret = mail_index_lookup_uid_range(view, src->uid1,
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen src->uid2,
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen &dest->uid1,
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen &dest->uid2);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen i_assert(ret == 0);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen if (dest->uid1 == 0)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen count--;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen else
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen dest++;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_delete(expunges_r, count, array_count(expunges_r) - count);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d6f50f100ce17fa4b3a89e9567a5ff993b38b872Timo Sirainen#define MAIL_INDEX_VIEW_VISIBLE_SYNC_MASK \
d6f50f100ce17fa4b3a89e9567a5ff993b38b872Timo Sirainen (MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE | \
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen MAIL_TRANSACTION_KEYWORD_RESET)
d6f50f100ce17fa4b3a89e9567a5ff993b38b872Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_index_sync_type sync_mask,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view_sync_ctx **ctx_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view_sync_ctx *ctx;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct mail_index_map *map;
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen enum mail_transaction_type mask, want_mask;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_t expunges = { 0, 0 };
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* We must sync flags as long as view is mmap()ed, as the flags may
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen have already changed under us. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert((sync_mask & MAIL_INDEX_SYNC_TYPE_FLAGS) != 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(!view->syncing);
d39c0e195c67be5f2b0a15f25a8d6039bef02711Timo Sirainen i_assert(view->transactions == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (mail_index_view_lock_head(view, TRUE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen hdr = view->index->hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* get list of all expunges first */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_sync_get_expunges(view, &expunges) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen /* only flags, appends and expunges can be left to be synced later */
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen want_mask = mail_transaction_type_mask_get(sync_mask);
d6f50f100ce17fa4b3a89e9567a5ff993b38b872Timo Sirainen i_assert((want_mask & ~MAIL_INDEX_VIEW_VISIBLE_SYNC_MASK) == 0);
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen mask = want_mask |
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen (MAIL_TRANSACTION_TYPE_MASK ^
d6f50f100ce17fa4b3a89e9567a5ff993b38b872Timo Sirainen MAIL_INDEX_VIEW_VISIBLE_SYNC_MASK);
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_file_seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_file_offset,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen hdr->log_file_seq,
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen hdr->log_file_int_offset, mask) < 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (array_is_created(&expunges))
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_free(&expunges);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->view = view;
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen ctx->trans_sync_mask = want_mask;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->expunges = expunges;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen MAIL_INDEX_SYNC_HANDLER_VIEW);
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0 &&
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen (sync_mask & MAIL_INDEX_SYNC_TYPE_APPEND) != 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->new_map = view->index->map;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->new_map->refcount++;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* keep the old mapping without expunges until we're
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen fully synced */
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen } else {
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen /* we need a private copy of the map if we don't want to
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen sync expunges. we need to sync mapping only if we're not
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen using the latest one. */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen uint32_t old_records_count = view->map->records_count;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (view->map != view->index->map) {
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen i_assert(view->map->records_count >=
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen view->hdr.messages_count);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen view->map->records_count = view->hdr.messages_count;
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen ctx->sync_map_update = TRUE;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen map = mail_index_map_clone(view->map,
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen view->map->hdr.record_size);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->map->records_count = old_records_count;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_index_unmap(view->index, view->map);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->map = map;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (ctx->sync_map_update) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (map->hdr_base != map->hdr_copy_buf->data) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen buffer_reset(map->hdr_copy_buf);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen buffer_append(map->hdr_copy_buf, map->hdr_base,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen map->hdr.header_size);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen map->hdr_base = map->hdr_copy_buf->data;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* start from our old view's header. */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen buffer_write(map->hdr_copy_buf, 0,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen &view->hdr, sizeof(view->hdr));
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen map->hdr = view->hdr;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
20c26f4fcf9ef87434761829cc209c2f84ff5716Timo Sirainen
20c26f4fcf9ef87434761829cc209c2f84ff5716Timo Sirainen i_assert(map->records_count == map->hdr.messages_count);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen }
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen mail_index_view_unref_maps(view);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen view->syncing = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *ctx_r = ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int view_is_transaction_synced(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq, uoff_t offset)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen const struct mail_index_view_log_sync_pos *pos, *end;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->log_syncs == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen pos = buffer_get_data(view->log_syncs, &size);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen end = CONST_PTR_OFFSET(pos, size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen for (; pos != end; pos++) {
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen if (pos->log_file_offset == offset && pos->log_file_seq == seq)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t *seq_r, uoff_t *offset_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view = ctx->view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret, skipped;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr, &ctx->data,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen &skipped);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret <= 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d6f50f100ce17fa4b3a89e9567a5ff993b38b872Timo Sirainen ctx->hdr = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->last_read = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (skipped)
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen ctx->skipped_some = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, seq_r, offset_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* skip flag changes that we committed ourself or have already synced */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_is_transaction_synced(view, *seq_r, *offset_r))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* expunges have to be synced afterwards so that caller can still get
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen information of the messages. otherwise caller most likely wants to
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen see only updated information. */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (ctx->sync_map_update &&
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen (ctx->hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0) {
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx, ctx->hdr,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ctx->data) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen if ((ctx->hdr->type & ctx->trans_sync_mask) == 0)
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen return 0;
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#define FLAG_UPDATE_IS_INTERNAL(u) \
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen ((((u)->add_flags | (u)->remove_flags) & \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ~(MAIL_INDEX_MAIL_FLAG_DIRTY | MAIL_RECENT)) == 0)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainenstatic int
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainenmail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen struct mail_index_sync_rec *rec)
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen{
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_header *hdr = ctx->hdr;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const void *data = ctx->data;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen case MAIL_TRANSACTION_APPEND: {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen rec->uid1 = rec->uid2 = 0;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen ctx->data_offset += hdr->size;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen break;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen case MAIL_TRANSACTION_EXPUNGE: {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_expunge *exp =
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen ctx->data_offset += sizeof(*exp);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen mail_index_sync_get_expunge(rec, exp);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen break;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen case MAIL_TRANSACTION_FLAG_UPDATE: {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_flag_update *update =
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen for (;;) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ctx->data_offset += sizeof(*update);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (!FLAG_UPDATE_IS_INTERNAL(update))
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen break;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ctx->data_offset == ctx->hdr->size)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return 0;
d0143523a87b41eae0b118ff03aad539903b3555Timo Sirainen
d0143523a87b41eae0b118ff03aad539903b3555Timo Sirainen update = CONST_PTR_OFFSET(data, ctx->data_offset);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen mail_index_sync_get_update(rec, update);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen break;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen case MAIL_TRANSACTION_KEYWORD_UPDATE: {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const struct mail_transaction_keyword_update *update = data;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const uint32_t *uids;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (ctx->data_offset == 0) {
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen ctx->data_offset = sizeof(*update) + update->name_size;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if ((ctx->data_offset % 4) != 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->data_offset += 4 - (ctx->data_offset % 4);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uids = CONST_PTR_OFFSET(data, ctx->data_offset);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* FIXME: this isn't exactly correct.. but no-one cares? */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen rec->uid1 = uids[0];
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen rec->uid2 = uids[1];
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->data_offset += sizeof(uint32_t) * 2;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen break;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen case MAIL_TRANSACTION_KEYWORD_RESET: {
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen const struct mail_transaction_keyword_reset *reset =
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->uid1 = reset->uid1;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->uid2 = reset->uid2;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen ctx->data_offset += sizeof(*reset);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen break;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen }
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen default:
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen i_unreached();
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return 1;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen}
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_sync_rec *sync_rec)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view = ctx->view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen do {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ctx->hdr == NULL || ctx->data_offset == ctx->hdr->size) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ctx->data_offset = 0;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen do {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ret = mail_index_view_sync_next_trans(ctx, &seq,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen &offset);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ret < 0)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return -1;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ctx->last_read)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return 0;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen if (!ctx->skipped_some) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen view->log_file_seq = seq;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen view->log_file_offset = offset +
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen sizeof(*ctx->hdr) +
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ctx->hdr->size;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen } while (ret == 0);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen if (ctx->skipped_some) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen mail_index_view_add_synced_transaction(view,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen seq,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen offset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen } while (!mail_index_view_sync_get_rec(ctx, sync_rec));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst uint32_t *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
9d3ccd79130199ffdb19a688027d49bf20a4aaaaTimo Sirainen unsigned int *count_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen const struct mail_transaction_expunge *data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen data = array_get(&ctx->expunges, count_r);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return (const uint32_t *)data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view = ctx->view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(view->syncing);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if (ctx->sync_map_update)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen mail_index_sync_map_deinit(&ctx->sync_map_ctx);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen if (view->log_syncs != NULL && !ctx->skipped_some)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_set_used_size(view->log_syncs, 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!ctx->last_read && ctx->hdr != NULL &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->data_offset != ctx->hdr->size) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we didn't sync everything */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->inconsistent = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (view->new_map != NULL) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_index_unmap(view->index, view->map);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->map = view->new_map;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->new_map = NULL;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->hdr = view->map->hdr;
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen (void)mail_transaction_log_view_set(view->log_view,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen view->log_file_seq,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen view->log_file_offset,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen view->log_file_seq,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen view->log_file_offset,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen MAIL_TRANSACTION_TYPE_MASK);
7888a9d2008eab9985096c46e1da9ee985c22a2aTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (array_is_created(&ctx->expunges))
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_free(&ctx->expunges);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->syncing = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_add_synced_transaction(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t log_file_seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t log_file_offset)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen struct mail_index_view_log_sync_pos pos;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen memset(&pos, 0, sizeof(pos));
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen pos.log_file_seq = log_file_seq;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen pos.log_file_offset = log_file_offset;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen if (view->log_syncs == NULL)
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen view->log_syncs = buffer_create_dynamic(default_pool, 128);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen buffer_append(view->log_syncs, &pos, sizeof(pos));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}