mail-index-view-sync.c revision d0143523a87b41eae0b118ff03aad539903b3555
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenview_sync_get_expunges(struct mail_index_view *view, buffer_t **expunges_r)
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct mail_transaction_expunge *src, *src_end, *dest;
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen *expunges_r = buffer_create_dynamic(default_pool, 512);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* with mask 0 we don't get anything, we'll just read the expunges
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while seeking to end */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
659fe5d24825b160cae512538088020d97a60239Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
659fe5d24825b160cae512538088020d97a60239Timo Sirainen mail_transaction_log_sort_expunges(*expunges_r,
659fe5d24825b160cae512538088020d97a60239Timo Sirainen /* convert to sequences */
659fe5d24825b160cae512538088020d97a60239Timo Sirainen src = dest = buffer_get_modifyable_data(*expunges_r, &size);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen ret = mail_index_lookup_uid_range(view, src->uid1,
d6f50f100ce17fa4b3a89e9567a5ff993b38b872Timo Sirainen (MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
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);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (mail_index_view_lock_head(view, TRUE) < 0)
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)
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);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0 &&
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen (sync_mask & MAIL_INDEX_SYNC_TYPE_APPEND) != 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* keep the old mapping without expunges until we're
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen fully synced */
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;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen view->map->records_count = view->hdr.messages_count;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (map->hdr_base != map->hdr_copy_buf->data) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen buffer_append(map->hdr_copy_buf, map->hdr_base,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* start from our old view's header. */
20c26f4fcf9ef87434761829cc209c2f84ff5716Timo Sirainen i_assert(map->records_count == map->hdr.messages_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int view_is_transaction_synced(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data = buffer_get_data(view->log_syncs, &size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *((const uint32_t *)(data + sizeof(uoff_t))) == seq)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr, &ctx->data,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, seq_r, offset_r);
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))
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 (ctx->hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0) {
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx, ctx->hdr,
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen if ((ctx->hdr->type & ctx->trans_sync_mask) == 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ~(MAIL_INDEX_MAIL_FLAG_DIRTY | MAIL_RECENT)) == 0)
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainenmail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_header *hdr = ctx->hdr;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_flag_update *update =
d0143523a87b41eae0b118ff03aad539903b3555Timo Sirainen update = CONST_PTR_OFFSET(data, ctx->data_offset);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const struct mail_transaction_keyword_update *update = data;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const unsigned char *p;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen p = (const unsigned char *)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->data_offset = p - (const unsigned char *)update;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->data_offset += 4 - (ctx->data_offset % 4);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uids = CONST_PTR_OFFSET(data, ctx->data_offset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ctx->hdr == NULL || ctx->data_offset == ctx->hdr->size) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ret = mail_index_view_sync_next_trans(ctx, &seq,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen } while (ret == 0);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen } while (!mail_index_view_sync_get_rec(ctx, sync_rec));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen mail_index_sync_map_deinit(&ctx->sync_map_ctx);
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen if (view->log_syncs != NULL && !ctx->skipped_some)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we didn't sync everything */
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen (void)mail_transaction_log_view_set(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_add_synced_transaction(struct mail_index_view *view,
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen view->log_syncs = buffer_create_dynamic(default_pool, 128);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(view->log_syncs, &log_file_offset,