index-sync.c revision ff635a8e19fa52bad48adf4e8fd2b6839b906a47
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "lib.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "seq-range-array.h"
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#include "ioloop.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "array.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "index-sync-private.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenbool index_mailbox_want_full_sync(struct index_mailbox *ibox,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen enum mailbox_sync_flags flags)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen{
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FAST) != 0 &&
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen ioloop_time < ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL)
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen return FALSE;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen if (ibox->notify_to != NULL)
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen timeout_reset(ibox->notify_to);
5be5d875996999585de785ac33f96ff1569f1a0eTimo Sirainen ibox->sync_last_check = ioloop_time;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen return TRUE;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen}
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainenvoid index_mailbox_set_recent_uid(struct index_mailbox *ibox, uint32_t uid)
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen{
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen if (uid <= ibox->recent_flags_prev_uid) {
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen i_assert(seq_range_exists(&ibox->recent_flags, uid));
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen return;
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen }
b87436ebb957a9eb182be72ba00e2c8eae59a2e4Timo Sirainen ibox->recent_flags_prev_uid = uid;
fc84f8af4794f4bb6caf6e5ec3fb1f8cebd0462aTimo Sirainen
b8a4aab1f117f6760184ad50b1af41ba810b51f9Timo Sirainen seq_range_array_add(&ibox->recent_flags, 64, uid);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen ibox->recent_flags_count++;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen}
12dc81583d1958cb301a617e19fbd40e8d376397Timo Sirainen
81e4bda7d481c57cd049a0a68daab733b1ca9c44Timo Sirainenvoid index_mailbox_set_recent_seq(struct index_mailbox *ibox,
12dc81583d1958cb301a617e19fbd40e8d376397Timo Sirainen struct mail_index_view *view,
12dc81583d1958cb301a617e19fbd40e8d376397Timo Sirainen uint32_t seq1, uint32_t seq2)
3851ad9fcb25635f02b46d44586742ef1081876bTimo Sirainen{
d7babe048f9ae1afa5357973b8de8c929753a216Timo Sirainen uint32_t uid;
2b682d8d3661800f16aceaa45fa4de9b6b140a59Timo Sirainen
2b682d8d3661800f16aceaa45fa4de9b6b140a59Timo Sirainen for (; seq1 <= seq2; seq1++) {
2b682d8d3661800f16aceaa45fa4de9b6b140a59Timo Sirainen mail_index_lookup_uid(view, seq1, &uid);
12dc81583d1958cb301a617e19fbd40e8d376397Timo Sirainen index_mailbox_set_recent_uid(ibox, uid);
12dc81583d1958cb301a617e19fbd40e8d376397Timo Sirainen }
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainen}
3851ad9fcb25635f02b46d44586742ef1081876bTimo Sirainen
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainenbool index_mailbox_is_recent(struct index_mailbox *ibox, uint32_t uid)
ad4f1b0666975c57dd2d8d3492b223ec814791cdTimo Sirainen{
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainen return array_is_created(&ibox->recent_flags) &&
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainen seq_range_exists(&ibox->recent_flags, uid);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainenvoid index_mailbox_reset_uidvalidity(struct index_mailbox *ibox)
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen{
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen /* can't trust the currently cached recent flags anymore */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (array_is_created(&ibox->recent_flags))
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen array_clear(&ibox->recent_flags);
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen ibox->recent_flags_count = 0;
12dc81583d1958cb301a617e19fbd40e8d376397Timo Sirainen ibox->recent_flags_prev_uid = 0;
cb931f84e3ec8e3deda253a1c0ae0409023de096Timo Sirainen}
12dc81583d1958cb301a617e19fbd40e8d376397Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenunsigned int index_mailbox_get_recent_count(struct index_mailbox *ibox)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const struct mail_index_header *hdr;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen const struct seq_range *range;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen unsigned int i, count, recent_count;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen if (!array_is_created(&ibox->recent_flags))
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return 0;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen hdr = mail_index_get_header(ibox->view);
6d6bbe8787354bbb69d0c03187adfe0f497d70b8Timo Sirainen recent_count = ibox->recent_flags_count;
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen range = array_get(&ibox->recent_flags, &count);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen for (i = count; i > 0; ) {
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen i--;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen if (range[i].seq2 < hdr->next_uid)
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen break;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen if (range[i].seq1 >= hdr->next_uid) {
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen /* completely invisible to this view */
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen recent_count -= range[i].seq2 - range[i].seq1 + 1;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen } else {
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen /* partially invisible */
73583cff4f0ca9ee87204256ca1994adf17cb94cTimo Sirainen recent_count -= range[i].seq2 - hdr->next_uid + 1;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen break;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen }
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return recent_count;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenstatic void index_mailbox_expunge_recent(struct index_mailbox *ibox,
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen uint32_t seq1, uint32_t seq2)
2521fd0986302cdabc8b0711eef63ac188f32cd6Timo Sirainen{
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen uint32_t uid;
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen if (!array_is_created(&ibox->recent_flags))
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen return;
ad0fe438255666726723a93f3112df6e103028afTimo Sirainen
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen for (; seq1 <= seq2; seq1++) {
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen mail_index_lookup_uid(ibox->view, seq1, &uid);
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen if (seq_range_array_remove(&ibox->recent_flags, uid))
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen ibox->recent_flags_count--;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen }
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen}
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainenstatic void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx)
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen{
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen struct mail_index_view_sync_rec sync_rec;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen uint32_t seq1, seq2;
2521fd0986302cdabc8b0711eef63ac188f32cd6Timo Sirainen
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen i_array_init(&ctx->flag_updates, 128);
2d8b23805db6f06b8b38174fb6e135386694f429Timo Sirainen i_array_init(&ctx->hidden_updates, 32);
2d8b23805db6f06b8b38174fb6e135386694f429Timo Sirainen while (mail_index_view_sync_next(ctx->sync_ctx, &sync_rec)) {
2d8b23805db6f06b8b38174fb6e135386694f429Timo Sirainen switch (sync_rec.type) {
766115d2b2e6dbcf59f90d3b3866851cf6f740feTimo Sirainen case MAIL_INDEX_VIEW_SYNC_TYPE_FLAGS:
766115d2b2e6dbcf59f90d3b3866851cf6f740feTimo Sirainen if (!mail_index_lookup_seq_range(ctx->ibox->view,
766115d2b2e6dbcf59f90d3b3866851cf6f740feTimo Sirainen sync_rec.uid1,
766115d2b2e6dbcf59f90d3b3866851cf6f740feTimo Sirainen sync_rec.uid2,
2d8b23805db6f06b8b38174fb6e135386694f429Timo Sirainen &seq1, &seq2))
2d8b23805db6f06b8b38174fb6e135386694f429Timo Sirainen break;
b1678954f83e1059b981e2def52a70054fa71399Timo Sirainen
b1678954f83e1059b981e2def52a70054fa71399Timo Sirainen if (!sync_rec.hidden) {
b1678954f83e1059b981e2def52a70054fa71399Timo Sirainen seq_range_array_add_range(&ctx->flag_updates,
b1678954f83e1059b981e2def52a70054fa71399Timo Sirainen seq1, seq2);
0e5819a061034f1636b124c03a89f67d37c852b1Timo Sirainen } else if (array_is_created(&ctx->hidden_updates)) {
0e5819a061034f1636b124c03a89f67d37c852b1Timo Sirainen seq_range_array_add_range(&ctx->hidden_updates,
0e5819a061034f1636b124c03a89f67d37c852b1Timo Sirainen seq1, seq2);
b1678954f83e1059b981e2def52a70054fa71399Timo Sirainen }
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen break;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen }
d5d23d5ff8b7a06d2ead489ddcf55ee8fb5ca7b6Timo Sirainen }
d5d23d5ff8b7a06d2ead489ddcf55ee8fb5ca7b6Timo Sirainen
d5d23d5ff8b7a06d2ead489ddcf55ee8fb5ca7b6Timo Sirainen /* remove expunged messages from flag updates */
d19d3aa4eafa34b48b7d7d311c9db31e1898576aTimo Sirainen if (ctx->expunges != NULL) {
d19d3aa4eafa34b48b7d7d311c9db31e1898576aTimo Sirainen seq_range_array_remove_seq_range(&ctx->flag_updates,
8eb223b84389a7b75a39d46484f5166d221305ebTimo Sirainen ctx->expunges);
8eb223b84389a7b75a39d46484f5166d221305ebTimo Sirainen seq_range_array_remove_seq_range(&ctx->hidden_updates,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen ctx->expunges);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen }
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* remove flag updates from hidden updates */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen seq_range_array_remove_seq_range(&ctx->hidden_updates,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen &ctx->flag_updates);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstruct mailbox_sync_context *
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenindex_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags,
30ad2b0309119501efad06c72ec9b1561b90d4afTimo Sirainen bool failed)
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen{
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)box;
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen struct index_mailbox_sync_context *ctx;
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen enum mail_index_view_sync_flags sync_flags = 0;
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen ctx = i_new(struct index_mailbox_sync_context, 1);
bc7a4cf2c06702ebaedba9a7c15ce657d5856f63Timo Sirainen ctx->ctx.box = box;
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen ctx->ibox = ibox;
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen if (failed) {
269370f66e320a071700e33d9f2584eb46d96a90Timo Sirainen ctx->failed = TRUE;
fbdd091ef000e3ec4db34c054736c91ef9bc48ceTimo Sirainen return &ctx->ctx;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
6800c6607013d4fdef5a4f764bae407301c6cce8Timo Sirainen
b2e181e33889f0a4a3ba9dc23d676cbfe1bf7782Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES;
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen
aaebcf0da12df7216be69961204fa64ec24c54b9Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) != 0) {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen ctx->messages_count = 0;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen } else {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen ctx->messages_count =
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_view_get_messages_count(ibox->view);
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen }
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen ctx->sync_ctx = mail_index_view_sync_begin(ibox->view, sync_flags);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_view_sync_get_expunges(ctx->sync_ctx,
2b682d8d3661800f16aceaa45fa4de9b6b140a59Timo Sirainen &ctx->expunges);
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen ctx->expunge_pos = array_count(ctx->expunges);
2b682d8d3661800f16aceaa45fa4de9b6b140a59Timo Sirainen }
d761c26f2bbf514e0fc0c6ed9bc52627a4179eabTimo Sirainen index_view_sync_recs_get(ctx);
d761c26f2bbf514e0fc0c6ed9bc52627a4179eabTimo Sirainen index_sync_search_results_expunge(ctx);
d761c26f2bbf514e0fc0c6ed9bc52627a4179eabTimo Sirainen return &ctx->ctx;
2b682d8d3661800f16aceaa45fa4de9b6b140a59Timo Sirainen}
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainenstatic bool
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainenindex_mailbox_sync_next_expunge(struct index_mailbox_sync_context *ctx,
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen struct mailbox_sync_rec *sync_rec_r)
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen{
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen const struct seq_range *range;
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen
b863b7e3fccf75f90f613b875f02fd1781e14e5eTimo Sirainen if (ctx->expunge_pos == 0)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return FALSE;
/* expunges is a sorted array of sequences. it's easiest for
us to print them from end to beginning. */
ctx->expunge_pos--;
range = array_idx(ctx->expunges, ctx->expunge_pos);
i_assert(range->seq2 <= ctx->messages_count);
index_mailbox_expunge_recent(ctx->ibox, range->seq1, range->seq2);
ctx->messages_count -= range->seq2 - range->seq1 + 1;
sync_rec_r->seq1 = range->seq1;
sync_rec_r->seq2 = range->seq2;
sync_rec_r->type = MAILBOX_SYNC_TYPE_EXPUNGE;
return TRUE;
}
bool index_mailbox_sync_next(struct mailbox_sync_context *_ctx,
struct mailbox_sync_rec *sync_rec_r)
{
struct index_mailbox_sync_context *ctx =
(struct index_mailbox_sync_context *)_ctx;
const struct seq_range *range;
unsigned int count;
if (ctx->failed)
return FALSE;
range = array_get(&ctx->flag_updates, &count);
if (ctx->flag_update_idx < count) {
sync_rec_r->type = MAILBOX_SYNC_TYPE_FLAGS;
sync_rec_r->seq1 = range[ctx->flag_update_idx].seq1;
sync_rec_r->seq2 = range[ctx->flag_update_idx].seq2;
ctx->flag_update_idx++;
return TRUE;
}
if ((_ctx->box->enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0) {
/* hidden flag changes' MODSEQs still need to be returned */
range = array_get(&ctx->hidden_updates, &count);
if (ctx->hidden_update_idx < count) {
sync_rec_r->type = MAILBOX_SYNC_TYPE_MODSEQ;
sync_rec_r->seq1 = range[ctx->hidden_update_idx].seq1;
sync_rec_r->seq2 = range[ctx->hidden_update_idx].seq2;
ctx->hidden_update_idx++;
return TRUE;
}
}
return index_mailbox_sync_next_expunge(ctx, sync_rec_r);
}
static void
index_mailbox_expunge_unseen_recent(struct index_mailbox_sync_context *ctx)
{
struct index_mailbox *ibox = ctx->ibox;
const struct mail_index_header *hdr;
uint32_t seq, start_uid, uid;
if (!array_is_created(&ibox->recent_flags))
return;
/* expunges array contained expunges for the messages that were already
visible in this view, but append+expunge would be invisible.
recent_flags may however contain the append UID, so we'll have to
remove it separately */
hdr = mail_index_get_header(ibox->view);
if (ctx->messages_count == 0)
uid = 0;
else if (ctx->messages_count <= hdr->messages_count)
mail_index_lookup_uid(ibox->view, ctx->messages_count, &uid);
else {
i_assert(mail_index_view_is_inconsistent(ibox->view));
return;
}
for (seq = ctx->messages_count + 1; seq <= hdr->messages_count; seq++) {
start_uid = uid;
mail_index_lookup_uid(ibox->view, seq, &uid);
if (start_uid + 1 > uid - 1)
continue;
ibox->recent_flags_count -=
seq_range_array_remove_range(&ibox->recent_flags,
start_uid + 1, uid - 1);
}
if (uid + 1 < hdr->next_uid) {
ibox->recent_flags_count -=
seq_range_array_remove_range(&ibox->recent_flags,
uid + 1,
hdr->next_uid - 1);
}
#ifdef DEBUG
{
const struct seq_range *range;
unsigned int i, count;
range = array_get(&ibox->recent_flags, &count);
for (i = 0; i < count; i++) {
for (uid = range[i].seq1; uid <= range[i].seq2; uid++) {
if (uid >= hdr->next_uid)
break;
mail_index_lookup_seq(ibox->view, uid, &seq);
i_assert(seq != 0);
}
}
}
#endif
}
int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
enum mailbox_status_items status_items,
struct mailbox_status *status_r)
{
struct index_mailbox_sync_context *ctx =
(struct index_mailbox_sync_context *)_ctx;
struct index_mailbox *ibox = ctx->ibox;
struct mailbox_sync_rec sync_rec;
const struct mail_index_header *hdr;
uint32_t seq1, seq2;
bool delayed_expunges = FALSE;
int ret = ctx->failed ? -1 : 0;
/* finish handling expunges, so we don't break when updating
recent flags */
while (index_mailbox_sync_next_expunge(ctx, &sync_rec) > 0) ;
if (ctx->sync_ctx != NULL) {
if (mail_index_view_sync_commit(&ctx->sync_ctx,
&delayed_expunges) < 0) {
mail_storage_set_index_error(ibox);
ret = -1;
}
}
index_mailbox_expunge_unseen_recent(ctx);
if (ibox->keep_recent) {
/* mailbox syncing didn't necessarily update our recent state */
hdr = mail_index_get_header(ibox->view);
if (hdr->first_recent_uid > ibox->recent_flags_prev_uid) {
mail_index_lookup_seq_range(ibox->view,
hdr->first_recent_uid,
hdr->next_uid,
&seq1, &seq2);
if (seq1 != 0) {
index_mailbox_set_recent_seq(ibox, ibox->view,
seq1, seq2);
}
}
}
if (ret == 0 && status_items != 0) {
mailbox_get_status(_ctx->box, status_items, status_r);
status_r->sync_delayed_expunges = delayed_expunges;
}
index_sync_search_results_update(ctx);
if (array_is_created(&ctx->flag_updates))
array_free(&ctx->flag_updates);
if (array_is_created(&ctx->hidden_updates))
array_free(&ctx->hidden_updates);
if (array_is_created(&ctx->all_flag_updates_merge))
array_free(&ctx->all_flag_updates_merge);
i_free(ctx);
return ret;
}
bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
const ARRAY_TYPE(keyword_indexes) *k2)
{
const unsigned int *idx1, *idx2;
unsigned int i, j, count1, count2;
if (!array_is_created(k1))
return !array_is_created(k2) || array_count(k2) == 0;
if (!array_is_created(k2))
return array_count(k1) == 0;
/* The arrays may not be sorted, but they usually are. Optimize for
the assumption that they are */
idx1 = array_get(k1, &count1);
idx2 = array_get(k2, &count2);
if (count1 != count2)
return FALSE;
for (i = 0; i < count1; i++) {
if (idx1[i] != idx2[i]) {
/* not found / unsorted array. check. */
for (j = 0; j < count1; j++) {
if (idx1[i] == idx2[j])
break;
}
if (j == count1)
return FALSE;
}
}
return TRUE;
}
enum mailbox_sync_type index_sync_type_convert(enum mail_index_sync_type type)
{
enum mailbox_sync_type ret = 0;
if ((type & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0)
ret |= MAILBOX_SYNC_TYPE_EXPUNGE;
if ((type & (MAIL_INDEX_SYNC_TYPE_FLAGS |
MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD |
MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE |
MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET)) != 0)
ret |= MAILBOX_SYNC_TYPE_FLAGS;
return ret;
}