index-sync.c revision d998335307d31d41ba996a6b34be28aa56047bad
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainenenum mail_index_sync_flags index_storage_get_sync_flags(struct mailbox *box)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if ((box->flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_DELETING_INDEX;
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainenbool index_mailbox_want_full_sync(struct mailbox *box,
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen ioloop_time < ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL)
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainenvoid index_mailbox_set_recent_uid(struct mailbox *box, uint32_t uid)
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen if (seq_range_exists(&ibox->recent_flags, uid))
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen "Recent flags state corrupted for mailbox %s",
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen seq_range_array_add(&ibox->recent_flags, 64, uid);
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainenvoid index_mailbox_set_recent_seq(struct mailbox *box,
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainenbool index_mailbox_is_recent(struct mailbox *box, uint32_t uid)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return array_is_created(&ibox->recent_flags) &&
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainenvoid index_mailbox_reset_uidvalidity(struct mailbox *box)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* can't trust the currently cached recent flags anymore */
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainenunsigned int index_mailbox_get_recent_count(struct mailbox *box)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen range = array_get(&ibox->recent_flags, &count);
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen for (i = count; i > 0; ) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* completely invisible to this view */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen recent_count -= range[i].seq2 - range[i].seq1 + 1;
0cea9b1f4fa0495a48f5f097e40492517d67e1baTimo Sirainen /* partially invisible */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen recent_count -= range[i].seq2 - hdr->next_uid + 1;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenindex_mailbox_expunge_recent(struct mailbox *box, uint32_t seq1, uint32_t seq2)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (seq_range_array_remove(&ibox->recent_flags, uid))
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen while (mail_index_view_sync_next(ctx->sync_ctx, &sync_rec)) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (!mail_index_lookup_seq_range(ctx->ctx.box->view,
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen } else if (array_is_created(&ctx->hidden_updates)) {
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen seq_range_array_add_range(&ctx->hidden_updates,
ea4ca37ec14913354f3a0deebc0df96097eb9468Timo Sirainen /* remove expunged messages from flag updates */
ea4ca37ec14913354f3a0deebc0df96097eb9468Timo Sirainen seq_range_array_remove_seq_range(&ctx->flag_updates,
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen seq_range_array_remove_seq_range(&ctx->hidden_updates,
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen /* remove flag updates from hidden updates */
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen seq_range_array_remove_seq_range(&ctx->hidden_updates,
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainenindex_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen enum mail_index_view_sync_flags sync_flags = 0;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen ctx = i_new(struct index_mailbox_sync_context, 1);
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES;
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) != 0) {
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_index_view_get_messages_count(box->view);
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen ctx->sync_ctx = mail_index_view_sync_begin(box->view, sync_flags);
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) {
c4cfee078c4a185b5ba8f0c55f51275b7e885b2cTimo Sirainen mail_index_view_sync_get_expunges(ctx->sync_ctx,
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen ctx->expunge_pos = array_count(ctx->expunges);
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainenindex_mailbox_sync_next_expunge(struct index_mailbox_sync_context *ctx,
114a0f74e0f825c6bd8aeadfafb248a030762a1fTimo Sirainen /* expunges is a sorted array of sequences. it's easiest for
c4cfee078c4a185b5ba8f0c55f51275b7e885b2cTimo Sirainen us to print them from end to beginning. */
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen range = array_idx(ctx->expunges, ctx->expunge_pos);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen index_mailbox_expunge_recent(ctx->ctx.box, range->seq1, range->seq2);
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen ctx->messages_count -= range->seq2 - range->seq1 + 1;
abb83d133dd082527d500916fca66a72fbbbaa8dTimo Sirainenbool index_mailbox_sync_next(struct mailbox_sync_context *_ctx,
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen unsigned int count;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen range = array_get(&ctx->flag_updates, &count);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen sync_rec_r->seq1 = range[ctx->flag_update_idx].seq1;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen sync_rec_r->seq2 = range[ctx->flag_update_idx].seq2;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if ((_ctx->box->enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* hidden flag changes' MODSEQs still need to be returned */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen range = array_get(&ctx->hidden_updates, &count);
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen sync_rec_r->seq1 = range[ctx->hidden_update_idx].seq1;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen sync_rec_r->seq2 = range[ctx->hidden_update_idx].seq2;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return index_mailbox_sync_next_expunge(ctx, sync_rec_r);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenindex_mailbox_expunge_unseen_recent(struct index_mailbox_sync_context *ctx)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct mail_index_view *view = ctx->ctx.box->view;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* expunges array contained expunges for the messages that were already
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen visible in this view, but append+expunge would be invisible.
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen recent_flags may however contain the append UID, so we'll have to
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen remove it separately */
11768c622a8e5aaf0e5d9b3c9a872867b62b4830Timo Sirainen else if (ctx->messages_count <= hdr->messages_count)
265e9d8457aa5ce01b7aad954632aed8c36deeb8Timo Sirainen mail_index_lookup_uid(view, ctx->messages_count, &uid);
265e9d8457aa5ce01b7aad954632aed8c36deeb8Timo Sirainen i_assert(mail_index_view_is_inconsistent(view));
265e9d8457aa5ce01b7aad954632aed8c36deeb8Timo Sirainen for (seq = ctx->messages_count + 1; seq <= hdr->messages_count; seq++) {
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen seq_range_array_remove_range(&ibox->recent_flags,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen seq_range_array_remove_range(&ibox->recent_flags,
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen unsigned int i, count;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen range = array_get(&ibox->recent_flags, &count);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen for (i = 0; i < count; i++) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen for (uid = range[i].seq1; uid <= range[i].seq2; uid++) {
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainenint index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(_ctx->box);
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen /* finish handling expunges, so we don't break when updating
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen recent flags */
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen while (index_mailbox_sync_next_expunge(ctx, &sync_rec) > 0) ;
7bb939ef70752f2731d27b18c944ea94e5b23eb5Timo Sirainen /* convert sequences to uids before syncing view */
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen if (mail_index_view_sync_commit(&ctx->sync_ctx,
8e574a603c2c02105b073906a7ca91904271b80eTimo Sirainen if ((_ctx->box->flags & MAILBOX_FLAG_KEEP_RECENT) != 0 &&
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen /* mailbox syncing didn't necessarily update our recent state */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (hdr->first_recent_uid > ibox->recent_flags_prev_uid) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen status_r->sync_delayed_expunges = delayed_expunges;
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen if (array_is_created(&ctx->all_flag_update_uids))
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainenbool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainen return !array_is_created(k2) || array_count(k2) == 0;
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen /* The arrays may not be sorted, but they usually are. Optimize for
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen the assumption that they are */
e96fb85799dc95603bb1a6b4d3685df2d042a2f8Timo Sirainen for (i = 0; i < count1; i++) {
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainen /* not found / unsorted array. check. */
e96fb85799dc95603bb1a6b4d3685df2d042a2f8Timo Sirainen for (j = 0; j < count1; j++) {
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainenenum mailbox_sync_type index_sync_type_convert(enum mail_index_sync_type type)