fts-search.c revision 663d4e0733c8dae3f49236cb8b50c195031f8ba9
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "lib.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "array.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "str.h"
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen#include "seq-range-array.h"
a1607f6001a9949e1cf9d49eb0aa936dbb4c77ffTimo Sirainen#include "charset-utf8.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "mail-search.h"
00d58fcfe8191d6ce7efa801d289a5c0fe88d1aeTimo Sirainen#include "mail-storage-private.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "fts-api-private.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "fts-storage.h"
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenuid_range_to_seqs(struct mailbox *box, const ARRAY_TYPE(seq_range) *uid_range,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen ARRAY_TYPE(seq_range) *seq_range)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen const struct seq_range *range;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int i, count;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen uint32_t seq1, seq2;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen range = array_get(uid_range, &count);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen i_array_init(seq_range, count);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen for (i = 0; i < count; i++) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mailbox_get_seq_range(box, range[i].seq1, range[i].seq2,
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen &seq1, &seq2);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (seq1 != 0)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen seq_range_array_add_range(seq_range, seq1, seq2);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void fts_uid_results_to_seq(struct fts_search_context *fctx)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen ARRAY_TYPE(seq_range) uid_range;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen uid_range = fctx->definite_seqs;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen uid_range_to_seqs(fctx->t->box, &uid_range, &fctx->definite_seqs);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen array_free(&uid_range);
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen uid_range = fctx->maybe_seqs;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen uid_range_to_seqs(fctx->t->box, &uid_range, &fctx->maybe_seqs);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen array_free(&uid_range);
bd63b5b860658b01b1f46f26d406e1e4a9dc019aTimo Sirainen}
f6c1297c26b355c4aec2a08978f51ec3efecb351Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic int fts_search_lookup_arg(struct fts_search_context *fctx,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mail_search_arg *arg)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen struct fts_backend *backend;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen struct fts_backend_lookup_context **lookup_ctx_p;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen enum fts_lookup_flags flags = 0;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen const char *key;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen string_t *key_utf8;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen enum charset_result result;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen int ret;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen switch (arg->type) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case SEARCH_HEADER:
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* we can filter out messages that don't have the header,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen but we can't trust definite results list. */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen flags = FTS_LOOKUP_FLAG_HEADER;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen backend = fctx->fbox->backend_substr;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen key = arg->value.str;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (*key == '\0') {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* we're only checking the existence
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen of the header. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen key = arg->hdr_field_name;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen break;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case SEARCH_TEXT:
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen case SEARCH_TEXT_FAST:
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen flags = FTS_LOOKUP_FLAG_HEADER;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case SEARCH_BODY:
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen case SEARCH_BODY_FAST:
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen flags |= FTS_LOOKUP_FLAG_BODY;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen key = arg->value.str;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen backend = fctx->fbox->backend_fast != NULL &&
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen (arg->type == SEARCH_TEXT_FAST ||
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen arg->type == SEARCH_BODY_FAST) ?
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen fctx->fbox->backend_fast : fctx->fbox->backend_substr;
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen if (backend == NULL)
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen return 0;
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen break;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen default:
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* can't filter this */
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen return 0;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen if (arg->not)
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen flags |= FTS_LOOKUP_FLAG_INVERT;
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen /* convert key to titlecase */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen key_utf8 = t_str_new(128);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (charset_to_utf8_str(fctx->args->charset,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen CHARSET_FLAG_DECOMP_TITLECASE,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen key, key_utf8, &result) < 0) {
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen /* unknown charset, can't handle this */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ret = 0;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen } else if (result != CHARSET_RET_OK) {
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen /* let the core code handle this error */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ret = 0;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen } else if (!backend->locked && fts_backend_lock(backend) <= 0)
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ret = -1;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen else {
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ret = 0;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen if (backend == fctx->fbox->backend_substr)
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen lookup_ctx_p = &fctx->lookup_ctx_substr;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen else
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen lookup_ctx_p = &fctx->lookup_ctx_fast;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen if (*lookup_ctx_p == NULL)
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen *lookup_ctx_p = fts_backend_lookup_init(backend);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen fts_backend_lookup_add(*lookup_ctx_p, str_c(key_utf8), flags);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen }
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen return ret;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenvoid fts_search_lookup(struct fts_search_context *fctx)
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct mail_search_arg *arg;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen bool have_seqs;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen int ret;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (fctx->best_arg == NULL)
d66be2bebfa96e7d3d20e2153f60e6e25dcc9a18Timo Sirainen return;
e376e08040b5f21ff79a15ae728d2532a34207f6Timo Sirainen
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen i_array_init(&fctx->definite_seqs, 64);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen i_array_init(&fctx->maybe_seqs, 64);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen i_array_init(&fctx->score_map, 64);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* start lookup with the best arg */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen T_BEGIN {
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen ret = fts_search_lookup_arg(fctx, fctx->best_arg);
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen } T_END;
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen /* filter the rest */
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen for (arg = fctx->args->args; arg != NULL && ret == 0; arg = arg->next) {
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen if (arg != fctx->best_arg) {
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen T_BEGIN {
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen ret = fts_search_lookup_arg(fctx, arg);
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen } T_END;
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen }
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen }
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen have_seqs = FALSE;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (fctx->fbox->backend_fast != NULL) {
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen if (fctx->lookup_ctx_fast != NULL) {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen have_seqs = TRUE;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen fts_backend_lookup_deinit(&fctx->lookup_ctx_fast,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen &fctx->definite_seqs,
d66be2bebfa96e7d3d20e2153f60e6e25dcc9a18Timo Sirainen &fctx->maybe_seqs,
d66be2bebfa96e7d3d20e2153f60e6e25dcc9a18Timo Sirainen &fctx->score_map);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen if (fctx->fbox->backend_fast->locked)
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen fts_backend_unlock(fctx->fbox->backend_fast);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen }
783278c012551bc2f25f065a8d3ec1a3cfc0d296Timo Sirainen if (fctx->fbox->backend_substr != NULL) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (fctx->lookup_ctx_substr == NULL) {
5d49cbcf87354f0ddf3b71bc5f0cefdc02b14f68Timo Sirainen /* no substr lookups */
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainen } else if (!have_seqs) {
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen fts_backend_lookup_deinit(&fctx->lookup_ctx_substr,
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainen &fctx->definite_seqs,
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainen &fctx->maybe_seqs,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen &fctx->score_map);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen } else {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen /* have to merge the results */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen ARRAY_TYPE(seq_range) tmp_def, tmp_maybe;
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen ARRAY_TYPE(fts_score_map) tmp_scores;
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen i_array_init(&tmp_def, 64);
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen i_array_init(&tmp_maybe, 64);
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen i_array_init(&tmp_scores, 64);
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen /* FIXME: for now we just ignore the other scores,
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen since squat doesn't support it anyway */
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen fts_backend_lookup_deinit(&fctx->lookup_ctx_substr,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen &tmp_def, &tmp_maybe,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen &tmp_scores);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen fts_filter_uids(&fctx->definite_seqs, &tmp_def,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen &fctx->maybe_seqs, &tmp_maybe);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen array_free(&tmp_def);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen array_free(&tmp_maybe);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen array_free(&tmp_scores);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen }
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen if (fctx->fbox->backend_substr->locked)
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen fts_backend_unlock(fctx->fbox->backend_substr);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen }
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen if (ret == 0) {
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen fctx->seqs_set = TRUE;
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen fts_uid_results_to_seq(fctx);
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen }
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen}
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainenstatic bool arg_is_better(const struct mail_search_arg *new_arg,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen const struct mail_search_arg *old_arg)
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (old_arg == NULL)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen return TRUE;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen if (new_arg == NULL)
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen return FALSE;
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen /* avoid NOTs */
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen if (old_arg->not && !new_arg->not)
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen return TRUE;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (!old_arg->not && new_arg->not)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return FALSE;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* prefer not to use headers. they have a larger possibility of
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen having lots of identical strings */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (old_arg->type == SEARCH_HEADER ||
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen old_arg->type == SEARCH_HEADER_COMPRESS_LWSP)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return TRUE;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen else if (new_arg->type == SEARCH_HEADER ||
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen new_arg->type == SEARCH_HEADER_COMPRESS_LWSP)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return FALSE;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return strlen(new_arg->value.str) > strlen(old_arg->value.str);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenfts_search_args_find_best(struct mail_search_arg *args,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct mail_search_arg **best_fast_arg,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct mail_search_arg **best_substr_arg)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen for (; args != NULL; args = args->next) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen switch (args->type) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case SEARCH_BODY_FAST:
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case SEARCH_TEXT_FAST:
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (arg_is_better(args, *best_fast_arg))
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen *best_fast_arg = args;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen break;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_BODY:
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case SEARCH_TEXT:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_HEADER:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen if (arg_is_better(args, *best_substr_arg))
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen *best_substr_arg = args;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen break;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen default:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen break;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen}
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenvoid fts_search_analyze(struct fts_search_context *fctx)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mail_search_arg *best_fast_arg = NULL, *best_substr_arg = NULL;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen fts_search_args_find_best(fctx->args->args, &best_fast_arg,
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen &best_substr_arg);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen if (best_fast_arg != NULL && fctx->fbox->backend_fast != NULL) {
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen /* use fast backend whenever possible */
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen fctx->best_arg = best_fast_arg;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen fctx->build_backend = fctx->fbox->backend_fast;
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen } else if (best_fast_arg != NULL || best_substr_arg != NULL) {
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen fctx->build_backend = fctx->fbox->backend_substr;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen fctx->best_arg = arg_is_better(best_substr_arg, best_fast_arg) ?
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen best_substr_arg : best_fast_arg;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen