]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Search result update handling code cleanups.
authorTimo Sirainen <tss@iki.fi>
Wed, 18 Jun 2008 01:34:46 +0000 (04:34 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 18 Jun 2008 01:34:46 +0000 (04:34 +0300)
--HG--
branch : HEAD

src/lib-storage/index/index-sync-private.h
src/lib-storage/index/index-sync-search.c
src/lib-storage/index/index-sync.c

index ab8639ccb20b545aa447f58543b0b30f14fd0da1..f6700836c87b35839fc347c2c5227bd4ebde94a5 100644 (file)
@@ -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;
 };
index 274061a87cbac54a8052e5e7899696481af8ce84..914caa490a626fe550628e8447e83d59d459061e 100644 (file)
@@ -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)
index 908272ea50f44524e5367a8b577c417c1ae99421..74fe234b08247b6b0bc064110e8a167044f69bf9 100644 (file)
@@ -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;
 }