fts-search.c revision 663d4e0733c8dae3f49236cb8b50c195031f8ba9
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenuid_range_to_seqs(struct mailbox *box, const ARRAY_TYPE(seq_range) *uid_range,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int i, count;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen for (i = 0; i < count; i++) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mailbox_get_seq_range(box, range[i].seq1, range[i].seq2,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen seq_range_array_add_range(seq_range, seq1, seq2);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void fts_uid_results_to_seq(struct fts_search_context *fctx)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen uid_range_to_seqs(fctx->t->box, &uid_range, &fctx->definite_seqs);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen uid_range_to_seqs(fctx->t->box, &uid_range, &fctx->maybe_seqs);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic int fts_search_lookup_arg(struct fts_search_context *fctx,
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen struct fts_backend_lookup_context **lookup_ctx_p;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen const char *key;
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 /* we're only checking the existence
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen of the header. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen fctx->fbox->backend_fast : fctx->fbox->backend_substr;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* can't filter this */
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen /* convert key to titlecase */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen /* unknown charset, can't handle this */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen /* let the core code handle this error */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen } else if (!backend->locked && fts_backend_lock(backend) <= 0)
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen *lookup_ctx_p = fts_backend_lookup_init(backend);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen fts_backend_lookup_add(*lookup_ctx_p, str_c(key_utf8), flags);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenvoid fts_search_lookup(struct fts_search_context *fctx)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* start lookup with the best arg */
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen ret = fts_search_lookup_arg(fctx, fctx->best_arg);
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen /* filter the rest */
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen for (arg = fctx->args->args; arg != NULL && ret == 0; arg = arg->next) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen fts_backend_lookup_deinit(&fctx->lookup_ctx_fast,
5d49cbcf87354f0ddf3b71bc5f0cefdc02b14f68Timo Sirainen /* no substr lookups */
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainen } else if (!have_seqs) {
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen fts_backend_lookup_deinit(&fctx->lookup_ctx_substr,
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen /* have to merge the results */
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 fts_filter_uids(&fctx->definite_seqs, &tmp_def,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen fts_backend_unlock(fctx->fbox->backend_substr);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainenstatic bool arg_is_better(const struct mail_search_arg *new_arg,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen /* avoid NOTs */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* prefer not to use headers. they have a larger possibility of
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen having lots of identical strings */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return strlen(new_arg->value.str) > strlen(old_arg->value.str);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenfts_search_args_find_best(struct mail_search_arg *args,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenvoid fts_search_analyze(struct fts_search_context *fctx)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mail_search_arg *best_fast_arg = NULL, *best_substr_arg = NULL;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen fts_search_args_find_best(fctx->args->args, &best_fast_arg,
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen if (best_fast_arg != NULL && fctx->fbox->backend_fast != NULL) {
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen /* use fast backend whenever possible */
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;