fts-storage.c revision ceae1acc3e3022c6b5fe52a4a34890dffdbcb77f
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct fts_backend_update_context *sync_update_ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen union mailbox_transaction_module_context module_ctx;
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_storage_module,
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_mail_module, &mail_module_register);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_mailbox_list_module,
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainenstatic void fts_scores_unref(struct fts_scores **_scores)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic bool fts_try_build_init(struct mail_search_context *ctx,
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen /* this process is already building the indexes */
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen switch (fts_build_init(fctx->backend, ctx->transaction->box, FALSE,
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen /* the index was up to date */
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen /* hide "searching" notifications while building index */
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainenstatic bool fts_want_build_args(const struct mail_search_arg *args)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* we want to update index only when searching from message body.
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen it's not worth the wait for searching only from headers, which
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen could be in cache file already */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenfts_mailbox_search_init(struct mailbox_transaction_context *t,
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(t->box->list);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen ctx = fbox->module_ctx.super.search_init(t, args, sort_program,
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen if (!fts_backend_can_lookup(flist->backend, args->args))
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen fctx->result_pool = pool_alloconly_create("fts results", 1024*32);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen fctx->orig_matches = buffer_create_dynamic(default_pool, 64);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen MODULE_CONTEXT_SET(ctx, fts_storage_module, fctx);
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen strcmp(t->box->storage->name, VIRTUAL_STORAGE_NAME) == 0;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* transaction contains the last search's scores. they can be
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen queried later with mail_get_special() */
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainenstatic bool fts_mailbox_build_continue(struct mail_search_context *ctx)
7af2a19a89c1c9da8848c570190d36570afd09e6Timo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* we're still waiting for this process (but another command)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen to finish building the indexes */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* this command is still building the indexes */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenfts_mailbox_search_next_nonblock(struct mail_search_context *ctx,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen search_next_nonblock(ctx, mail_r, tryagain_r);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenfts_search_apply_results_level(struct mail_search_context *ctx,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct mail_search_arg *args, unsigned int *idx)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (array_is_created(&level->definite_seqs) &&
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen seq_range_exists(&level->definite_seqs, ctx->seq))
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen fts_search_deserialize_add_matches(args, level->args_matches);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen else if (!array_is_created(&level->maybe_seqs) ||
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen !seq_range_exists(&level->maybe_seqs, ctx->seq))
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen fts_search_deserialize_add_nonmatches(args, level->args_matches);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (args->type != SEARCH_OR && args->type != SEARCH_SUB)
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen fts_search_apply_results_level(ctx, args->value.subargs, idx);
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainenstatic bool fts_mailbox_search_next_update_seq(struct mail_search_context *ctx)
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen unsigned int idx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (fctx == NULL || !fctx->fts_lookup_success) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* fts lookup not done for this search */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return fbox->module_ctx.super.search_next_update_seq(ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* restore original [non]matches */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen fts_search_deserialize(ctx->args->args, fctx->orig_matches);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (!fbox->module_ctx.super.search_next_update_seq(ctx))
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* we've not indexed this far */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* apply [non]matches based on the FTS lookup results */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen fts_search_apply_results_level(ctx, ctx->args->args, &idx);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstatic int fts_mailbox_search_deinit(struct mail_search_context *ctx)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen /* the search was cancelled */
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen return fbox->module_ctx.super.search_deinit(ctx);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstatic int fts_score_cmp(const uint32_t *uid, const struct fts_score_map *score)
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstatic int fts_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen const char **value_r)
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct fts_mail *fmail = FTS_MAIL_CONTEXT(mail);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen if (field != MAIL_FETCH_SEARCH_RELEVANCY || ft->scores == NULL)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen scores = array_bsearch(&ft->scores->score_map, &_mail->uid,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen i_snprintf(fmail->score, sizeof(fmail->score),
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen return fmail->module_ctx.super.get_special(_mail, field, value_r);
static struct mailbox_transaction_context *
struct mailbox_transaction_context *t;
int ret = 0;
return ret;
if (force_resync) {
if (precache) {