query: filter out docs without query-matches
This avoid including unwanted messages in threaded results. Also some cleanups.
This commit is contained in:
@ -102,7 +102,7 @@ private:
|
||||
} MU_XAPIAN_CATCH_BLOCK_RETURN (Nothing);
|
||||
};
|
||||
|
||||
struct MatchDeciderLeader: public MatchDecider {
|
||||
struct MatchDeciderLeader final: public MatchDecider {
|
||||
MatchDeciderLeader (QueryFlags qflags, DeciderInfo& info):
|
||||
MatchDecider(qflags, info)
|
||||
{}
|
||||
@ -155,7 +155,7 @@ Mu::make_leader_decider (QueryFlags qflags, DeciderInfo& info)
|
||||
return std::make_unique<MatchDeciderLeader>(qflags, info);
|
||||
}
|
||||
|
||||
struct MatchDeciderRelated: public MatchDecider {
|
||||
struct MatchDeciderRelated final: public MatchDecider {
|
||||
MatchDeciderRelated(QueryFlags qflags, DeciderInfo& info):
|
||||
MatchDecider(qflags, info) {}
|
||||
/**
|
||||
@ -200,8 +200,8 @@ Mu::make_related_decider (QueryFlags qflags, DeciderInfo& info)
|
||||
return std::make_unique<MatchDeciderRelated>(qflags, info);
|
||||
}
|
||||
|
||||
struct MatchDeciderFinal: public MatchDecider {
|
||||
MatchDeciderFinal(QueryFlags qflags, DeciderInfo& info):
|
||||
struct MatchDeciderThread final: public MatchDecider {
|
||||
MatchDeciderThread(QueryFlags qflags, DeciderInfo& info):
|
||||
MatchDecider{qflags, info} {}
|
||||
/**
|
||||
* operator()
|
||||
@ -219,16 +219,13 @@ struct MatchDeciderFinal: public MatchDecider {
|
||||
// we may have seen this match in the "Leader" query,
|
||||
// or in the second (unbuounded) related query;
|
||||
const auto it{decider_info_.matches.find(doc.get_docid())};
|
||||
if (it == decider_info_.matches.end())
|
||||
return false;
|
||||
else
|
||||
return should_include(it->second);
|
||||
return it != decider_info_.matches.end() && !it->second.thread_path.empty();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
std::unique_ptr<Xapian::MatchDecider>
|
||||
Mu::make_final_decider (QueryFlags qflags, DeciderInfo& info)
|
||||
Mu::make_thread_decider (QueryFlags qflags, DeciderInfo& info)
|
||||
{
|
||||
return std::make_unique<MatchDeciderFinal>(qflags, info);
|
||||
return std::make_unique<MatchDeciderThread>(qflags, info);
|
||||
}
|
||||
|
||||
@ -68,15 +68,15 @@ std::unique_ptr<Xapian::MatchDecider> make_related_decider(QueryFlags qflags,
|
||||
|
||||
|
||||
/**
|
||||
* Make a "final" decider, that is, a MatchDecider that removes all but
|
||||
* the document excepts for the ones included earlier.
|
||||
* Make a "thread" decider, that is, a MatchDecider that removes all but the
|
||||
* document excepts for the ones found during initial/related searches.
|
||||
*
|
||||
* @param qflags query flags
|
||||
* @param match_info receives information about the matches.
|
||||
*
|
||||
* @return a unique_ptr to a match decider.
|
||||
*/
|
||||
std::unique_ptr<Xapian::MatchDecider> make_final_decider (QueryFlags qflags,
|
||||
std::unique_ptr<Xapian::MatchDecider> make_thread_decider (QueryFlags qflags,
|
||||
DeciderInfo& info);
|
||||
|
||||
|
||||
|
||||
@ -122,7 +122,6 @@ operator<<(std::ostream& os, const Container& container)
|
||||
|
||||
using IdTable = std::unordered_map<std::string, Container>;
|
||||
using DupTable = std::multimap<std::string, Container>;
|
||||
//template <typename QueryResultsType> using DupsVec = std::vector<decltype(QueryResultsType::value_type)>;
|
||||
|
||||
static void
|
||||
handle_duplicates (IdTable& id_table, DupTable& dup_table)
|
||||
@ -165,7 +164,7 @@ determine_id_table (QueryResultsType& qres)
|
||||
auto c_it = id_table.find(msgid);
|
||||
auto& container = [&]()->Container& {
|
||||
if (c_it != id_table.end()) {
|
||||
assert(!c_it->second.query_match);
|
||||
if (!c_it->second.query_match) // hmm, dup?
|
||||
c_it->second.query_match = mi.query_match();
|
||||
return c_it->second;
|
||||
} else {
|
||||
|
||||
@ -49,7 +49,7 @@ struct Query::Private {
|
||||
const StringSet& thread_ids,
|
||||
MuMsgFieldId sortfieldid, QueryFlags qflags) const;
|
||||
|
||||
Option<QueryResults> run_threaded (QueryResults &qres, Xapian::Enquire& enq,
|
||||
Option<QueryResults> run_threaded (QueryResults&& qres, Xapian::Enquire& enq,
|
||||
QueryFlags qflags) const;
|
||||
Option<QueryResults> run_singular (const std::string& expr, MuMsgFieldId sortfieldid,
|
||||
QueryFlags qflags, size_t maxnum) const;
|
||||
@ -118,32 +118,31 @@ Query::Private::make_related_enquire (const Xapian::Query& first_q,
|
||||
}
|
||||
|
||||
struct ThreadKeyMaker: public Xapian::KeyMaker {
|
||||
ThreadKeyMaker (const QueryMatches& matches, bool descending):
|
||||
match_info_(matches),
|
||||
not_found_key_{descending ? "#" : "z"}
|
||||
{}
|
||||
ThreadKeyMaker (const QueryMatches& matches): match_info_(matches) {}
|
||||
std::string operator()(const Xapian::Document& doc) const override {
|
||||
const auto it{match_info_.find(doc.get_docid())};
|
||||
return (it == match_info_.end()) ? not_found_key_ : it->second.thread_path;
|
||||
if (it == match_info_.end())
|
||||
g_warning ("not found! %u", doc.get_docid());
|
||||
return (it == match_info_.end()) ? "" : it->second.thread_path;
|
||||
}
|
||||
const QueryMatches& match_info_;
|
||||
const std::string not_found_key_;
|
||||
};
|
||||
|
||||
Option<QueryResults>
|
||||
Query::Private::run_threaded (QueryResults &qres, Xapian::Enquire& enq,
|
||||
Query::Private::run_threaded (QueryResults&& qres, Xapian::Enquire& enq,
|
||||
QueryFlags qflags) const
|
||||
{
|
||||
const auto descending{any_of(qflags & QueryFlags::Descending)};
|
||||
|
||||
calculate_threads(qres, descending);
|
||||
|
||||
ThreadKeyMaker key_maker{qres.query_matches(), descending};
|
||||
ThreadKeyMaker key_maker{qres.query_matches()};
|
||||
enq.set_sort_by_key(&key_maker, descending);
|
||||
|
||||
DeciderInfo minfo;
|
||||
minfo.matches = qres.query_matches();
|
||||
auto mset{enq.get_mset(0, qres.size(), {}, make_final_decider(qflags, minfo).get())};
|
||||
auto mset{enq.get_mset(0, qres.size(), {},
|
||||
make_thread_decider(qflags, minfo).get())};
|
||||
mset.fetch();
|
||||
|
||||
return QueryResults{mset, std::move(qres.query_matches())};
|
||||
@ -174,7 +173,7 @@ Query::Private::run_singular (const std::string& expr, MuMsgFieldId sortfieldid,
|
||||
|
||||
auto qres{QueryResults{mset, std::move(minfo.matches)}};
|
||||
|
||||
return threading ? run_threaded(qres, enq, qflags) : qres;
|
||||
return threading ? run_threaded(std::move(qres), enq, qflags) : qres;
|
||||
}
|
||||
|
||||
|
||||
@ -209,7 +208,7 @@ Query::Private::run_related (const std::string& expr, MuMsgFieldId sortfieldid,
|
||||
{}, make_related_decider(qflags, minfo).get())};
|
||||
auto qres{QueryResults{r_mset, std::move(minfo.matches)}};
|
||||
|
||||
return threading ? run_threaded(qres, r_enq, qflags) : qres;
|
||||
return threading ? run_threaded(std::move(qres), r_enq, qflags) : qres;
|
||||
}
|
||||
|
||||
Option<QueryResults>
|
||||
|
||||
Reference in New Issue
Block a user