struct index_transaction_context *t =
(struct index_transaction_context *)_t;
struct index_search_context *ctx;
+ const struct mail_index_header *hdr;
ctx = i_new(struct index_search_context, 1);
ctx->mail_ctx.transaction = _t;
ctx->mail_ctx.args = args;
ctx->mail_ctx.sort_program = index_sort_program_init(_t, sort_program);
+ hdr = mail_index_get_header(t->ibox->view);
+ ctx->mail_ctx.progress_max = hdr->messages_count;
+
i_array_init(&ctx->mail_ctx.results, 5);
array_create(&ctx->mail_ctx.module_contexts, default_pool,
sizeof(void *), 5);
static void index_storage_search_notify(struct mailbox *box,
struct index_search_context *ctx)
{
- const struct mail_index_header *hdr;
float percentage;
unsigned int msecs, secs;
already spent some time indexing the mailbox */
ctx->search_start_time = ioloop_timeval;
} else if (box->storage->callbacks->notify_ok != NULL) {
- hdr = mail_index_get_header(ctx->ibox->view);
-
- percentage = ctx->mail->seq * 100.0 / hdr->messages_count;
+ percentage = ctx->mail_ctx.progress_cur * 100.0 /
+ ctx->mail_ctx.progress_max;
msecs = (ioloop_timeval.tv_sec -
ctx->search_start_time.tv_sec) * 1000 +
(ioloop_timeval.tv_usec -
}
if (!ctx->have_seqsets && !ctx->have_index_args &&
- _ctx->update_result == NULL)
+ _ctx->update_result == NULL) {
+ ctx->mail_ctx.progress_cur = _ctx->seq;
return _ctx->seq <= ctx->seq2;
+ }
ret = 0;
while (_ctx->seq <= ctx->seq2) {
search_set_static_matches(_ctx->args->args);
}
}
+ ctx->mail_ctx.progress_cur = _ctx->seq;
return ret != 0;
}
return 1;
}
-static bool fts_try_build_init(struct fts_search_context *fctx)
+static void fts_search_init_lookup(struct mail_search_context *ctx,
+ struct fts_search_context *fctx)
+{
+ fts_search_lookup(fctx);
+
+ if (fctx->seqs_set &&
+ strcmp(ctx->transaction->box->storage->name, "virtual") != 0) {
+ ctx->progress_max = array_count(&fctx->definite_seqs) +
+ array_count(&fctx->maybe_seqs);
+ }
+}
+
+static bool fts_try_build_init(struct mail_search_context *ctx,
+ struct fts_search_context *fctx)
{
if (fctx->build_backend == NULL) {
fctx->build_initialized = TRUE;
if (fctx->build_ctx == NULL) {
/* the index was up to date */
- fts_search_lookup(fctx);
+ fts_search_init_lookup(ctx, fctx);
}
return TRUE;
}
ft->score_map = &fctx->score_map;
fts_search_analyze(fctx);
- (void)fts_try_build_init(fctx);
+ (void)fts_try_build_init(ctx, fctx);
return ctx;
}
if (!fctx->build_initialized) {
/* we're still waiting for this process (but another command)
to finish building the indexes */
- if (!fts_try_build_init(fctx)) {
+ if (!fts_try_build_init(ctx, fctx)) {
*tryagain_r = TRUE;
return 0;
}
if (ret > 0) {
if (fts_build_init_virtual_next(fctx) == 0) {
/* all finished */
- fts_search_lookup(fctx);
+ fts_search_init_lookup(ctx, fctx);
}
}
}
switch (arg->type) {
case SEARCH_TEXT:
case SEARCH_BODY:
+ if (fctx->fbox->backend_substr == NULL) {
+ /* we're marking only fast args */
+ break;
+ }
case SEARCH_BODY_FAST:
case SEARCH_TEXT_FAST:
arg->result = 1;
}
}
+static bool search_nonindexed(struct mail_search_context *ctx)
+{
+ struct fts_search_context *fctx = FTS_CONTEXT(ctx);
+ struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
+ struct mailbox_status status;
+
+ mailbox_get_status(ctx->transaction->box, STATUS_MESSAGES, &status);
+
+ fctx->seqs_set = FALSE;
+ ctx->seq = fctx->first_nonindexed_seq - 1;
+ ctx->progress_cur = ctx->seq;
+ ctx->progress_max = status.messages;
+ return fbox->module_ctx.super.search_next_update_seq(ctx);
+}
+
static bool fts_mailbox_search_next_update_seq(struct mail_search_context *ctx)
{
struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
/* look for the non-indexed mails */
if (fctx->first_nonindexed_seq == (uint32_t)-1)
return FALSE;
- fctx->seqs_set = FALSE;
- ctx->seq = fctx->first_nonindexed_seq - 1;
- return fts_mailbox_search_next_update_seq(ctx);
+ return search_nonindexed(ctx);
}
use_maybe = TRUE;
} else if (fctx->maybe_idx == maybe_count) {
to avoid duplicates or jumping around, ignore the rest of
the search results and just go through the messages in
order. */
- fctx->seqs_set = FALSE;
- ctx->seq = fctx->first_nonindexed_seq - 1;
- return fts_mailbox_search_next_update_seq(ctx);
+ return search_nonindexed(ctx);
}
+ ctx->progress_cur = fctx->definite_idx + fctx->maybe_idx;
return ret;
}
}
srecs = array_get_modifiable(&vctx->records, &count);
qsort(srecs, count, sizeof(*srecs), virtual_search_record_cmp);
+
+ ctx->progress_max = count;
return ret;
}
recs = array_get(&vctx->records, &count);
if (vctx->next_record_idx < count) {
+ /* go through potential results first */
ctx->seq = recs[vctx->next_record_idx++].virtual_seq - 1;
if (!index_storage_search_next_update_seq(ctx))
i_unreached();
+ ctx->progress_cur = vctx->next_record_idx;
return TRUE;
}
if (ctx->sort_program != NULL &&
seq_range_array_iter_nth(&vctx->result_iter,
vctx->next_result_n, &ctx->seq)) {
+ /* this is known to match fully */
search_args_set_full_match(ctx->args->args);
vctx->next_result_n++;
return TRUE;