summaryrefslogtreecommitdiffstats
path: root/src/lib-storage/index/index-sync-search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-storage/index/index-sync-search.c')
-rw-r--r--src/lib-storage/index/index-sync-search.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/lib-storage/index/index-sync-search.c b/src/lib-storage/index/index-sync-search.c
new file mode 100644
index 0000000..95cb89d
--- /dev/null
+++ b/src/lib-storage/index/index-sync-search.c
@@ -0,0 +1,97 @@
+/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "seq-range-array.h"
+#include "mail-search.h"
+#include "mailbox-search-result-private.h"
+#include "index-search-result.h"
+#include "index-sync-private.h"
+
+static bool
+search_result_want_flag_updates(const struct mail_search_result *result)
+{
+ if (!result->args_have_flags && !result->args_have_keywords &&
+ !result->args_have_modseq) {
+ /* search result doesn't care about flag changes */
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void index_sync_uidify_array(struct index_mailbox_sync_context *ctx,
+ const ARRAY_TYPE(seq_range) *changes)
+{
+ const struct seq_range *range;
+ uint32_t seq, uid;
+
+ array_foreach(changes, range) {
+ for (seq = range->seq1; seq <= range->seq2; seq++) {
+ mail_index_lookup_uid(ctx->ctx.box->view, seq, &uid);
+ seq_range_array_add(&ctx->all_flag_update_uids, uid);
+ }
+ }
+}
+
+static void index_sync_uidify(struct index_mailbox_sync_context *ctx)
+{
+ unsigned int count;
+
+ count = array_count(&ctx->flag_updates) +
+ array_count(&ctx->hidden_updates);
+ i_array_init(&ctx->all_flag_update_uids, count*2);
+
+ index_sync_uidify_array(ctx, &ctx->flag_updates);
+ index_sync_uidify_array(ctx, &ctx->hidden_updates);
+}
+
+void index_sync_search_results_uidify(struct index_mailbox_sync_context *ctx)
+{
+ struct mail_search_result *const *results;
+ unsigned int i, count;
+
+ i_assert(!array_is_created(&ctx->all_flag_update_uids));
+
+ results = array_get(&ctx->ctx.box->search_results, &count);
+ for (i = 0; i < count; i++) {
+ if ((results[i]->flags & MAILBOX_SEARCH_RESULT_FLAG_UPDATE) != 0 &&
+ search_result_want_flag_updates(results[i])) {
+ index_sync_uidify(ctx);
+ break;
+ }
+ }
+}
+
+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) {
+ /* not an updateable search result */
+ return;
+ }
+
+ if (search_result_want_flag_updates(result)) {
+ (void)index_search_result_update_flags(result,
+ &ctx->all_flag_update_uids);
+ }
+ (void)index_search_result_update_appends(result, ctx->messages_count);
+}
+
+void index_sync_search_results_update(struct index_mailbox_sync_context *ctx)
+{
+ struct mail_search_result *const *results;
+ unsigned int i, count;
+
+ results = array_get(&ctx->ctx.box->search_results, &count);
+ for (i = 0; i < count; i++)
+ search_result_update(ctx, results[i]);
+}
+
+void index_sync_search_results_expunge(struct index_mailbox_sync_context *ctx)
+{
+ if (ctx->expunges != NULL) {
+ index_search_results_update_expunges(ctx->ctx.box,
+ ctx->expunges);
+ }
+}