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