From ee4bf5664a532acf3698fa0590f56938f4998918 Mon Sep 17 00:00:00 2001 From: Nicolas Avrutin Date: Sun, 11 Jul 2021 16:10:52 -0400 Subject: [PATCH] query: fix include-related. mu-query.cc: - make_related_enquire: don't include first query in qvec, we already have all thread IDs we need to query in thread_ds. - run_related: always sort first query by date, explained by the comment. - run_related: include qflags (in particular ascending vs descending) in leader_qflags. - run_theaded: don't limit results to maxnum, that results in threads potentially being cut off. mu-server.cc: - output_sexp: don't limit results to maxnum so as to match the behaviour of mu find (and avoid cuttong off threads). Fixes #1924 and #1911. --- lib/mu-query.cc | 25 +++++++++++-------------- lib/mu-server.cc | 11 ++++------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/lib/mu-query.cc b/lib/mu-query.cc index 5e4b0e82..59e99734 100644 --- a/lib/mu-query.cc +++ b/lib/mu-query.cc @@ -45,12 +45,11 @@ struct Query::Private { Xapian::Enquire make_enquire (const std::string& expr, MuMsgFieldId sortfieldid, QueryFlags qflags) const; - Xapian::Enquire make_related_enquire (const Xapian::Query& first_q, - const StringSet& thread_ids, + Xapian::Enquire make_related_enquire (const StringSet& thread_ids, MuMsgFieldId sortfieldid, QueryFlags qflags) const; Option run_threaded (QueryResults&& qres, Xapian::Enquire& enq, - QueryFlags qflags, size_t max_size) const; + QueryFlags qflags) const; Option run_singular (const std::string& expr, MuMsgFieldId sortfieldid, QueryFlags qflags, size_t maxnum) const; Option run_related (const std::string& expr, MuMsgFieldId sortfieldid, @@ -101,14 +100,13 @@ Query::Private::make_enquire (const std::string& expr, } Xapian::Enquire -Query::Private::make_related_enquire (const Xapian::Query& first_q, - const StringSet& thread_ids, +Query::Private::make_related_enquire (const StringSet& thread_ids, MuMsgFieldId sortfieldid, QueryFlags qflags) const { Xapian::Enquire enq{store_.database()}; static std::string pfx (1, mu_msg_field_xapian_prefix(MU_MSG_FIELD_ID_THREAD_ID)); - std::vector qvec{first_q}; + std::vector qvec; for (auto&& t: thread_ids) qvec.emplace_back(pfx + t); Xapian::Query qr{Xapian::Query::OP_OR, qvec.begin(), qvec.end()}; @@ -129,7 +127,7 @@ struct ThreadKeyMaker: public Xapian::KeyMaker { Option Query::Private::run_threaded (QueryResults&& qres, Xapian::Enquire& enq, - QueryFlags qflags, size_t max_size) const + QueryFlags qflags) const { const auto descending{any_of(qflags & QueryFlags::Descending)}; @@ -140,7 +138,7 @@ Query::Private::run_threaded (QueryResults&& qres, Xapian::Enquire& enq, DeciderInfo minfo; minfo.matches = qres.query_matches(); - auto mset{enq.get_mset(0, max_size, {}, + auto mset{enq.get_mset(0, store_.size(), {}, make_thread_decider(qflags, minfo).get())}; mset.fetch(); @@ -172,7 +170,7 @@ Query::Private::run_singular (const std::string& expr, MuMsgFieldId sortfieldid, auto qres{QueryResults{mset, std::move(minfo.matches)}}; - return threading ? run_threaded(std::move(qres), enq, qflags, maxnum) : qres; + return threading ? run_threaded(std::move(qres), enq, qflags) : qres; } static Option @@ -192,12 +190,12 @@ Query::Private::run_related (const std::string& expr, MuMsgFieldId sortfieldid, // moreover, in either threaded or non-threaded case, we sort the first // ("leader") query by date, i.e, we prefer the newest or oldest // (descending) messages. - const auto leader_qflags{QueryFlags::Leader}; + const auto leader_qflags{QueryFlags::Leader | qflags}; const auto threading{any_of(qflags & QueryFlags::Threading)}; // Run our first, "leader" query DeciderInfo minfo{}; - auto enq{make_enquire(expr, sortfieldid, leader_qflags)}; + auto enq{make_enquire(expr, MU_MSG_FIELD_ID_DATE, leader_qflags)}; const auto mset{enq.get_mset(0, maxnum, {}, make_leader_decider(leader_qflags, minfo).get())}; @@ -214,13 +212,12 @@ Query::Private::run_related (const std::string& expr, MuMsgFieldId sortfieldid, // In the threaded-case, we search among _all_ messages, since complete // threads are preferred; no need to sort in that case since the search // is unlimited and the sorting happens during threading. - auto r_enq{make_related_enquire(enq.get_query(), minfo.thread_ids, + auto r_enq{make_related_enquire(minfo.thread_ids, threading ? MU_MSG_FIELD_ID_NONE : sortfieldid, qflags)}; const auto r_mset{r_enq.get_mset(0, threading ? store_.size() : maxnum, {}, make_related_decider(qflags, minfo).get())}; auto qres{QueryResults{r_mset, std::move(minfo.matches)}}; - - return threading ? run_threaded(std::move(qres), r_enq, qflags, maxnum) : qres; + return threading ? run_threaded(std::move(qres), r_enq, qflags) : qres; } diff --git a/lib/mu-server.cc b/lib/mu-server.cc index 32bac340..e418f667 100644 --- a/lib/mu-server.cc +++ b/lib/mu-server.cc @@ -86,7 +86,7 @@ struct Server::Private { void output_sexp(Sexp::List&& lst) const { output_sexp(Sexp::make_list(std::move(lst))); } - size_t output_sexp (const QueryResults& qres, unsigned maxnum); + size_t output_sexp (const QueryResults& qres); // // handlers for various commands. @@ -731,13 +731,10 @@ determine_docids (const Query& q, const Parameters& params) size_t -Server::Private::output_sexp (const QueryResults& qres, unsigned maxnum) +Server::Private::output_sexp (const QueryResults& qres) { size_t n{}; for (auto&& mi: qres) { - - if (n >= maxnum) - break; ++n; auto msg{mi.floating_msg()}; if (!msg) @@ -745,7 +742,7 @@ Server::Private::output_sexp (const QueryResults& qres, unsigned maxnum) auto qm{mi.query_match()}; output_sexp(build_message_sexp(msg, mi.doc_id(), - qm, MU_MSG_OPTION_HEADERS_ONLY)); + qm, MU_MSG_OPTION_HEADERS_ONLY)); } return n; @@ -796,7 +793,7 @@ Server::Private::find_handler (const Parameters& params) } { - const auto foundnum{output_sexp (*qres, maxnum)}; + const auto foundnum{output_sexp (*qres)}; Sexp::List lst; lst.add_prop(":found", Sexp::make_number(foundnum)); output_sexp(std::move(lst));