From: Timo Sirainen Date: Wed, 18 Jun 2008 01:34:46 +0000 (+0300) Subject: Search result update handling code cleanups. X-Git-Tag: 1.2.alpha1~274 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5cbab0cb665cd982855d9d87573c35706e4d992c;p=thirdparty%2Fdovecot%2Fcore.git Search result update handling code cleanups. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/index-sync-private.h b/src/lib-storage/index/index-sync-private.h index ab8639ccb2..f6700836c8 100644 --- a/src/lib-storage/index/index-sync-private.h +++ b/src/lib-storage/index/index-sync-private.h @@ -10,9 +10,9 @@ struct index_mailbox_sync_context { uint32_t messages_count; ARRAY_TYPE(seq_range) flag_updates; - ARRAY_TYPE(seq_range) modseq_updates; + ARRAY_TYPE(seq_range) hidden_updates; const ARRAY_TYPE(seq_range) *expunges; - unsigned int flag_update_idx, modseq_update_idx, expunge_pos; + unsigned int flag_update_idx, hidden_update_idx, expunge_pos; bool failed; }; diff --git a/src/lib-storage/index/index-sync-search.c b/src/lib-storage/index/index-sync-search.c index 274061a87c..914caa490a 100644 --- a/src/lib-storage/index/index-sync-search.c +++ b/src/lib-storage/index/index-sync-search.c @@ -112,52 +112,56 @@ search_result_update_search(struct mail_search_result *result, return ret; } -static int -search_result_update_existing(struct index_mailbox_sync_context *ctx, - struct mail_search_result *result) +static bool +search_result_merge_changes(struct index_mailbox_sync_context *ctx, + struct mail_search_result *result, + ARRAY_TYPE(seq_range) *changes) { /* @UNSAFE */ - const ARRAY_TYPE(seq_range) *merge_ranges[2]; - ARRAY_TYPE(seq_range) changes; - struct mail_search_arg search_arg; - unsigned int i, count, merge_count = 0; - int ret; - - /* get the changes we're interested in */ - if ((result->args_have_flags || result->args_have_keywords) && - array_is_created(&ctx->flag_updates)) - merge_ranges[merge_count++] = &ctx->flag_updates; - if (result->args_have_modseq && array_is_created(&ctx->modseq_updates)) - merge_ranges[merge_count++] = &ctx->modseq_updates; - i_assert(merge_count < N_ELEMENTS(merge_ranges)); + unsigned int count; - for (i = 0, count = 0; i < merge_count; i++) - count += array_count(merge_ranges[i]); + if (!result->args_have_flags && !result->args_have_keywords && + !result->args_have_modseq) { + /* search result doesn't care about flag changes */ + return FALSE; + } + count = array_count(&ctx->flag_updates) + + array_count(&ctx->hidden_updates); if (count == 0) { /* no changes */ - return 0; + return FALSE; } /* merge the changed sequences */ - t_array_init(&changes, count); - for (i = 0; i < merge_count; i++) - seq_range_array_merge(&changes, merge_ranges[i]); + t_array_init(changes, count); + seq_range_array_merge(changes, &ctx->flag_updates); + seq_range_array_merge(changes, &ctx->hidden_updates); + return TRUE; +} + +static int +search_result_update_existing(struct mail_search_result *result, + const ARRAY_TYPE(seq_range) *changes) +{ + struct mail_search_arg search_arg; + int ret; /* add a temporary search parameter to limit the search only to the changed messages */ memset(&search_arg, 0, sizeof(search_arg)); search_arg.type = SEARCH_SEQSET; - search_arg.value.seqset = changes; + search_arg.value.seqset = *changes; search_arg.next = result->search_args->args; result->search_args->args = &search_arg; - ret = search_result_update_search(result, &changes); + ret = search_result_update_search(result, changes); i_assert(result->search_args->args == &search_arg); result->search_args->args = search_arg.next; return ret; } static int -search_result_update_appends(struct index_mailbox_sync_context *ctx, +search_result_update_appends(struct mail_index_view *view, + unsigned int old_messages_count, struct mail_search_result *result) { struct mailbox_transaction_context *t; @@ -167,8 +171,8 @@ search_result_update_appends(struct index_mailbox_sync_context *ctx, uint32_t message_count; int ret; - message_count = mail_index_view_get_messages_count(ctx->ibox->view); - if (ctx->messages_count == message_count) { + message_count = mail_index_view_get_messages_count(view); + if (old_messages_count == message_count) { /* no new messages */ return 0; } @@ -179,7 +183,7 @@ search_result_update_appends(struct index_mailbox_sync_context *ctx, search_arg.type = SEARCH_SEQSET; t_array_init(&search_arg.value.seqset, 1); seq_range_array_add_range(&search_arg.value.seqset, - ctx->messages_count + 1, message_count); + old_messages_count + 1, message_count); search_arg.next = result->search_args->args; result->search_args->args = &search_arg; @@ -205,13 +209,19 @@ static void search_result_update(struct index_mailbox_sync_context *ctx, struct mail_search_result *result) { - if ((result->flags & MAILBOX_SEARCH_RESULT_FLAG_UPDATE) == 0) + if ((result->flags & MAILBOX_SEARCH_RESULT_FLAG_UPDATE) == 0) { + /* not an updateable search result */ return; + } T_BEGIN { - (void)search_result_update_existing(ctx, result); + ARRAY_TYPE(seq_range) changes; + + if (search_result_merge_changes(ctx, result, &changes)) + (void)search_result_update_existing(result, &changes); } T_END; - (void)search_result_update_appends(ctx, result); + (void)search_result_update_appends(ctx->ibox->view, ctx->messages_count, + result); } void index_sync_search_results_update(struct index_mailbox_sync_context *ctx) diff --git a/src/lib-storage/index/index-sync.c b/src/lib-storage/index/index-sync.c index 908272ea50..74fe234b08 100644 --- a/src/lib-storage/index/index-sync.c +++ b/src/lib-storage/index/index-sync.c @@ -108,8 +108,7 @@ static void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx) uint32_t seq1, seq2; i_array_init(&ctx->flag_updates, 128); - if ((ctx->ibox->box.enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0) - i_array_init(&ctx->modseq_updates, 32); + i_array_init(&ctx->hidden_updates, 32); while (mail_index_view_sync_next(ctx->sync_ctx, &sync_rec)) { switch (sync_rec.type) { case MAIL_INDEX_VIEW_SYNC_TYPE_FLAGS: @@ -122,28 +121,24 @@ static void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx) if (!sync_rec.hidden) { seq_range_array_add_range(&ctx->flag_updates, seq1, seq2); - } else if (array_is_created(&ctx->modseq_updates)) { - seq_range_array_add_range(&ctx->modseq_updates, + } else if (array_is_created(&ctx->hidden_updates)) { + seq_range_array_add_range(&ctx->hidden_updates, seq1, seq2); } break; } } - /* remove expunged messages from flag/modseq updates */ + /* remove expunged messages from flag updates */ if (ctx->expunges != NULL) { seq_range_array_remove_seq_range(&ctx->flag_updates, ctx->expunges); - if (array_is_created(&ctx->modseq_updates)) { - seq_range_array_remove_seq_range(&ctx->modseq_updates, - ctx->expunges); - } - } - /* remove flag updates from modseq updates */ - if (array_is_created(&ctx->modseq_updates)) { - seq_range_array_remove_seq_range(&ctx->modseq_updates, - &ctx->flag_updates); + seq_range_array_remove_seq_range(&ctx->hidden_updates, + ctx->expunges); } + /* remove flag updates from hidden updates */ + seq_range_array_remove_seq_range(&ctx->hidden_updates, + &ctx->flag_updates); } struct mailbox_sync_context * @@ -228,13 +223,14 @@ bool index_mailbox_sync_next(struct mailbox_sync_context *_ctx, ctx->flag_update_idx++; return TRUE; } - if (array_is_created(&ctx->modseq_updates)) { - range = array_get(&ctx->modseq_updates, &count); - if (ctx->modseq_update_idx < count) { + 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->modseq_update_idx].seq1; - sync_rec_r->seq2 = range[ctx->modseq_update_idx].seq2; - ctx->modseq_update_idx++; + 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; } } @@ -351,8 +347,8 @@ int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx, if (array_is_created(&ctx->flag_updates)) array_free(&ctx->flag_updates); - if (array_is_created(&ctx->modseq_updates)) - array_free(&ctx->modseq_updates); + if (array_is_created(&ctx->hidden_updates)) + array_free(&ctx->hidden_updates); i_free(ctx); return ret; }