aboutsummaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2017-09-19 21:51:54 +0200
committerGitHub <noreply@github.com>2017-09-19 21:51:54 +0200
commitd650e313d11cfe0f2f4ce07f5fc8cf616a264739 (patch)
treebdece4b85a956fe44701d6339241e15272459508 /searchcore
parentc536a7dedb8257d9a56fb350bf24b796e26712e8 (diff)
Revert "Havardpe/reuse termwise vector in second phase"
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/proton/matching/matching_test.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_master.cpp20
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp188
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_thread.h41
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp96
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_tools.h42
6 files changed, 188 insertions, 203 deletions
diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp
index 261827a1e06..fefc6f361a9 100644
--- a/searchcore/src/tests/proton/matching/matching_test.cpp
+++ b/searchcore/src/tests/proton/matching/matching_test.cpp
@@ -292,8 +292,8 @@ struct MyWorld {
MatchToolsFactory::UP match_tools_factory = matcher->create_match_tools_factory(
*request, searchContext, attributeContext, metaStore, overrides);
MatchTools::UP match_tools = match_tools_factory->createMatchTools();
- match_tools->setup_first_phase();
- return match_tools->match_data().get_termwise_limit();
+ RankProgram::UP rank_program = match_tools->first_phase_program();
+ return rank_program->match_data().get_termwise_limit();
}
SearchReply::UP performSearch(SearchRequest::SP req, size_t threads) {
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
index 370c4b930e1..0b5287fb094 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
@@ -106,15 +106,11 @@ MatchMaster::getFeatureSet(const MatchToolsFactory &matchToolsFactory,
const std::vector<uint32_t> &docs, bool summaryFeatures)
{
MatchTools::UP matchTools = matchToolsFactory.createMatchTools();
- if (summaryFeatures) {
- matchTools->setup_summary();
- } else {
- matchTools->setup_dump();
- }
- RankProgram &rankProgram = matchTools->rank_program();
+ RankProgram::UP rankProgram = summaryFeatures ? matchTools->summary_program() :
+ matchTools->dump_program();
std::vector<vespalib::string> featureNames;
- FeatureResolver resolver(rankProgram.get_seeds());
+ FeatureResolver resolver(rankProgram->get_seeds());
featureNames.reserve(resolver.num_features());
for (size_t i = 0; i < resolver.num_features(); ++i) {
featureNames.emplace_back(resolver.name_of(i));
@@ -125,12 +121,12 @@ MatchMaster::getFeatureSet(const MatchToolsFactory &matchToolsFactory,
}
FeatureSet &fs = *retval.get();
- SearchIterator &search = matchTools->search();
- search.initRange(docs.front(), docs.back()+1);
+ SearchIterator::UP search = matchTools->createSearch(rankProgram->match_data());
+ search->initRange(docs.front(), docs.back()+1);
for (uint32_t i = 0; i < docs.size(); ++i) {
- if (search.seek(docs[i])) {
- uint32_t docId = search.getDocId();
- search.unpack(docId);
+ if (search->seek(docs[i])) {
+ uint32_t docId = search->getDocId();
+ search->unpack(docId);
search::feature_t * f = fs.getFeaturesByIndex(
fs.addDocId(docId));
for (uint32_t j = 0; j < featureNames.size(); ++j) {
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp
index 73cd5ffca06..3a9f59680f9 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp
@@ -40,22 +40,39 @@ struct WaitTimer {
}
};
-// seek_next maps to SearchIterator::seekNext
-struct SimpleStrategy {
- static uint32_t seek_next(SearchIterator &search, uint32_t docid) {
- return search.seekNext(docid);
+class FastSeekWrapper
+{
+private:
+ typedef search::queryeval::SearchIterator SearchIterator;
+public:
+ FastSeekWrapper(SearchIterator::UP iterator)
+ {
+ reset(iterator.release());
}
-};
-
-// seek_next maps to OptimizedAndNotForBlackListing::seekFast
-struct FastBlackListingStrategy {
- static bool can_use(bool do_limit, SearchIterator &search) {
- return (!do_limit &&
- (dynamic_cast<OptimizedAndNotForBlackListing *>(&search) != nullptr));
+ void initRange(uint32_t begin_id, uint32_t end_id) {
+ _search->initRange(begin_id, end_id);
+ }
+ uint32_t seekFirst(uint32_t docId) {
+ return _search->seekFirst(docId);
}
- static uint32_t seek_next(SearchIterator &search, uint32_t docid) {
- return static_cast<OptimizedAndNotForBlackListing &>(search).seekFast(docid);
+ uint32_t seekNext(uint32_t docId) {
+ return _search->seekFast(docId);
}
+ vespalib::string asString() const {
+ return _search->asString();
+ }
+ void unpack(uint32_t docId) {
+ _search->unpack(docId);
+ }
+ void reset(SearchIterator * search) {
+ _search.reset(&dynamic_cast<OptimizedAndNotForBlackListing &>(*search));
+ }
+ OptimizedAndNotForBlackListing * release() {
+ return _search.release();
+ }
+ FastSeekWrapper * operator ->() { return this; }
+private:
+ std::unique_ptr<OptimizedAndNotForBlackListing> _search;
};
LazyValue get_score_feature(const RankProgram &rankProgram) {
@@ -68,17 +85,17 @@ LazyValue get_score_feature(const RankProgram &rankProgram) {
//-----------------------------------------------------------------------------
-MatchThread::Context::Context(double rankDropLimit, MatchTools &tools, HitCollector &hits,
- uint32_t num_threads)
- : matches(0),
- _matches_limit(tools.match_limiter().sample_hits_per_thread(num_threads)),
- _score_feature(get_score_feature(tools.rank_program())),
- _ranking(tools.rank_program()),
- _rankDropLimit(rankDropLimit),
- _hits(hits),
- _softDoom(tools.getSoftDoom())
-{
-}
+MatchThread::Context::Context(double rankDropLimit, MatchTools & matchTools, RankProgram & ranking, HitCollector & hits,
+ uint32_t num_threads) :
+ matches(0),
+ _matches_limit(matchTools.match_limiter().sample_hits_per_thread(num_threads)),
+ _score_feature(get_score_feature(ranking)),
+ _ranking(ranking),
+ _rankDropLimit(rankDropLimit),
+ _hits(hits),
+ _softDoom(matchTools.getSoftDoom()),
+ _limiter(matchTools.match_limiter())
+{ }
void
MatchThread::Context::rankHit(uint32_t docId) {
@@ -105,27 +122,27 @@ MatchThread::estimate_match_frequency(uint32_t matches, uint32_t searchedSoFar)
return match_freq;
}
-SearchIterator *
-MatchThread::maybe_limit(MatchTools &tools, uint32_t matches, uint32_t docId, uint32_t endId)
+template <typename IteratorT>
+void
+MatchThread::maybe_limit(MaybeMatchPhaseLimiter & limiter, IteratorT & search, uint32_t matches, uint32_t docId, uint32_t endId)
{
const uint32_t local_todo = (endId - docId - 1);
const size_t searchedSoFar = (scheduler.total_size(thread_id) - local_todo);
double match_freq = estimate_match_frequency(matches, searchedSoFar);
const size_t global_todo = scheduler.unassigned_size();
- {
- auto search = tools.borrow_search();
- search = tools.match_limiter().maybe_limit(std::move(search), match_freq, matchParams.numDocs);
- tools.give_back_search(std::move(search));
- if (tools.match_limiter().was_limited()) {
- tools.tag_search_as_changed();
- }
- }
+ search = limiter.maybe_limit(std::move(search), match_freq, matchParams.numDocs);
size_t left = local_todo + (global_todo / num_threads);
- tools.match_limiter().updateDocIdSpaceEstimate(searchedSoFar, left);
+ limiter.updateDocIdSpaceEstimate(searchedSoFar, left);
LOG(debug, "Limit=%d has been reached at docid=%d which is after %zu docs.",
matches, docId, (scheduler.total_size(thread_id) - local_todo));
- LOG(debug, "SearchIterator after limiter: %s", tools.search().asString().c_str());
- return &tools.search();
+ LOG(debug, "SearchIterator after limiter: %s", search->asString().c_str());
+}
+
+template <>
+void
+MatchThread::maybe_limit(MaybeMatchPhaseLimiter &, FastSeekWrapper &, uint32_t, uint32_t, uint32_t)
+{
+ abort(); // We cannot replace the iterator if we inline the loop.
}
bool
@@ -139,11 +156,10 @@ MatchThread::try_share(DocidRange &docid_range, uint32_t next_docid) {
return false;
}
-template <typename Strategy, bool do_rank, bool do_limit, bool do_share_work>
+template <typename IteratorT, bool do_rank, bool do_limit, bool do_share_work>
bool
-MatchThread::inner_match_loop(Context &context, MatchTools &tools, DocidRange docid_range)
+MatchThread::inner_match_loop(Context & context, IteratorT & search, DocidRange docid_range)
{
- SearchIterator *search = &tools.search();
search->initRange(docid_range.begin, docid_range.end);
uint32_t docId = search->seekFirst(docid_range.begin);
while ((docId < docid_range.end) && !context.atSoftDoom()) {
@@ -155,29 +171,30 @@ MatchThread::inner_match_loop(Context &context, MatchTools &tools, DocidRange do
}
context.matches++;
if (do_limit && context.isAtLimit()) {
- search = maybe_limit(tools, context.matches, docId, docid_range.end);
+ maybe_limit(context.limiter(), search, context.matches, docId, docid_range.end);
docId = search->seekFirst(docId + 1);
} else if (do_share_work && any_idle() && try_share(docid_range, docId + 1)) {
search->initRange(docid_range.begin, docid_range.end);
docId = search->seekFirst(docid_range.begin);
} else {
- docId = Strategy::seek_next(*search, docId + 1);
+ docId = search->seekNext(docId + 1);
}
}
return (docId < docid_range.end);
}
-template <typename Strategy, bool do_rank, bool do_limit, bool do_share_work>
+template <typename IteratorT, bool do_rank, bool do_limit, bool do_share_work>
void
-MatchThread::match_loop(MatchTools &tools, HitCollector &hits)
+MatchThread::match_loop(MatchTools &matchTools, IteratorT search,
+ RankProgram &ranking, HitCollector &hits)
{
bool softDoomed = false;
- Context context(matchParams.rankDropLimit, tools, hits, num_threads);
+ Context context(matchParams.rankDropLimit, matchTools, ranking, hits, num_threads);
for (DocidRange docid_range = scheduler.first_range(thread_id);
!docid_range.empty() && ! softDoomed;
docid_range = scheduler.next_range(thread_id))
{
- softDoomed = inner_match_loop<Strategy, do_rank, do_limit, do_share_work>(context, tools, docid_range);
+ softDoomed = inner_match_loop<IteratorT, do_rank, do_limit, do_share_work>(context, search, docid_range);
}
uint32_t matches = context.matches;
if (do_limit && context.isBelowLimit()) {
@@ -185,7 +202,7 @@ MatchThread::match_loop(MatchTools &tools, HitCollector &hits)
LOG(debug, "Limit not reached (had %d) at docid=%d which is after %zu docs.",
matches, scheduler.total_span(thread_id).end, searchedSoFar);
estimate_match_frequency(matches, searchedSoFar);
- tools.match_limiter().updateDocIdSpaceEstimate(searchedSoFar, 0);
+ context.limiter().updateDocIdSpaceEstimate(searchedSoFar, 0);
}
thread_stats.docsMatched(matches);
thread_stats.softDoomed(softDoomed);
@@ -194,77 +211,68 @@ MatchThread::match_loop(MatchTools &tools, HitCollector &hits)
}
}
-//-----------------------------------------------------------------------------
-
-template <bool do_rank, bool do_limit, bool do_share>
-void
-MatchThread::match_loop_helper_rank_limit_share(MatchTools &tools, HitCollector &hits)
-{
- if (FastBlackListingStrategy::can_use(do_limit, tools.search())) {
- match_loop<FastBlackListingStrategy, do_rank, do_limit, do_share>(tools, hits);
- } else {
- match_loop<SimpleStrategy, do_rank, do_limit, do_share>(tools, hits);
- }
-}
-
-template <bool do_rank, bool do_limit>
+template <typename IteratorT, bool do_rank, bool do_limit>
void
-MatchThread::match_loop_helper_rank_limit(MatchTools &tools, HitCollector &hits)
+MatchThread::match_loop_helper_2(MatchTools &matchTools, IteratorT search,
+ RankProgram &ranking, HitCollector &hits)
{
if (idle_observer.is_always_zero()) {
- match_loop_helper_rank_limit_share<do_rank, do_limit, false>(tools, hits);
- } else {
- match_loop_helper_rank_limit_share<do_rank, do_limit, true>(tools, hits);
- }
-}
-
-template <bool do_rank>
-void
-MatchThread::match_loop_helper_rank(MatchTools &tools, HitCollector &hits)
-{
- if (tools.match_limiter().is_enabled()) {
- match_loop_helper_rank_limit<do_rank, true>(tools, hits);
+ match_loop<IteratorT, do_rank, do_limit, false>(matchTools, std::move(search), ranking, hits);
} else {
- match_loop_helper_rank_limit<do_rank, false>(tools, hits);
+ match_loop<IteratorT, do_rank, do_limit, true>(matchTools, std::move(search), ranking, hits);
}
}
+template <typename IteratorT, bool do_rank>
void
-MatchThread::match_loop_helper(MatchTools &tools, HitCollector &hits)
+MatchThread::match_loop_helper(MatchTools &matchTools, IteratorT search,
+ RankProgram &ranking, HitCollector &hits)
{
- if (match_with_ranking) {
- match_loop_helper_rank<true>(tools, hits);
+ if (matchTools.match_limiter().is_enabled()) {
+ match_loop_helper_2<IteratorT, do_rank, true>(matchTools, std::move(search), ranking, hits);
} else {
- match_loop_helper_rank<false>(tools, hits);
+ match_loop_helper_2<IteratorT, do_rank, false>(matchTools, std::move(search), ranking, hits);
}
}
//-----------------------------------------------------------------------------
search::ResultSet::UP
-MatchThread::findMatches(MatchTools &tools)
+MatchThread::findMatches(MatchTools &matchTools)
{
- tools.setup_first_phase();
+ RankProgram::UP ranking = matchTools.first_phase_program();
+ SearchIterator::UP search = matchTools.createSearch(ranking->match_data());
if (isFirstThread()) {
- LOG(spam, "SearchIterator: %s", tools.search().asString().c_str());
+ LOG(spam, "SearchIterator: %s", search->asString().c_str());
}
- tools.give_back_search(search::queryeval::MultiBitVectorIteratorBase::optimize(tools.borrow_search()));
+ search = search::queryeval::MultiBitVectorIteratorBase::optimize(std::move(search));
if (isFirstThread()) {
- LOG(debug, "SearchIterator after MultiBitVectorIteratorBase::optimize(): %s", tools.search().asString().c_str());
+ LOG(debug, "SearchIterator after MultiBitVectorIteratorBase::optimize(): %s", search->asString().c_str());
}
HitCollector hits(matchParams.numDocs, matchParams.arraySize, matchParams.heapSize);
- match_loop_helper(tools, hits);
- if (tools.has_second_phase_rank()) {
+ if (match_with_ranking) {
+ match_loop_helper<SearchIterator::UP, true>(matchTools, std::move(search), *ranking, hits);
+ } else {
+ if ((dynamic_cast<const OptimizedAndNotForBlackListing *>(search.get()) != 0) &&
+ ! matchTools.match_limiter().is_enabled()) // We cannot replace the iterator if we inline the loop.
+ {
+ match_loop_helper_2<FastSeekWrapper, false, false>(matchTools, FastSeekWrapper(std::move(search)), *ranking, hits);
+ } else {
+ match_loop_helper<SearchIterator::UP, false>(matchTools, std::move(search), *ranking, hits);
+ }
+ }
+ if (matchTools.has_second_phase_rank()) {
{ // 2nd phase ranking
- tools.setup_second_phase();
+ ranking = matchTools.second_phase_program();
+ search = matchTools.createSearch(ranking->match_data());
DocidRange docid_range = scheduler.total_span(thread_id);
- tools.search().initRange(docid_range.begin, docid_range.end);
+ search->initRange(docid_range.begin, docid_range.end);
auto sorted_scores = hits.getSortedHeapScores();
WaitTimer select_best_timer(wait_time_s);
size_t useHits = communicator.selectBest(sorted_scores);
select_best_timer.done();
- DocumentScorer scorer(tools.rank_program(), tools.search());
- uint32_t reRanked = hits.reRank(scorer, tools.getHardDoom().doom() ? 0 : useHits);
+ DocumentScorer scorer(*ranking, *search);
+ uint32_t reRanked = hits.reRank(scorer, matchTools.getHardDoom().doom() ? 0 : useHits);
thread_stats.docsReRanked(reRanked);
}
{ // rank scaling
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_thread.h b/searchcore/src/vespa/searchcore/proton/matching/match_thread.h
index b08323fa099..a279e83f032 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_thread.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_thread.h
@@ -51,41 +51,46 @@ private:
class Context {
public:
- Context(double rankDropLimit, MatchTools &tools, HitCollector &hits,
+ Context(double rankDropLimit, MatchTools &matchTools, RankProgram & ranking, HitCollector & hits,
uint32_t num_threads) __attribute__((noinline));
void rankHit(uint32_t docId);
void addHit(uint32_t docId) { _hits.addHit(docId, search::zero_rank_value); }
bool isBelowLimit() const { return matches < _matches_limit; }
bool isAtLimit() const { return matches == _matches_limit; }
bool atSoftDoom() const { return _softDoom.doom(); }
- uint32_t matches;
+ MaybeMatchPhaseLimiter & limiter() { return _limiter; }
+ uint32_t matches;
private:
- uint32_t _matches_limit;
- LazyValue _score_feature;
- RankProgram &_ranking;
- double _rankDropLimit;
- HitCollector &_hits;
- const Doom &_softDoom;
+ uint32_t _matches_limit;
+ LazyValue _score_feature;
+ RankProgram & _ranking;
+ double _rankDropLimit;
+ HitCollector & _hits;
+ const Doom & _softDoom;
+ MaybeMatchPhaseLimiter & _limiter;
};
double estimate_match_frequency(uint32_t matches, uint32_t searchedSoFar) __attribute__((noinline));
- SearchIterator *maybe_limit(MatchTools &tools, uint32_t matches, uint32_t docId, uint32_t endId) __attribute__((noinline));
+
+ template <typename IteratorT>
+ void maybe_limit(MaybeMatchPhaseLimiter & limiter, IteratorT & search, uint32_t matches, uint32_t docId, uint32_t endId) __attribute__((noinline));
bool any_idle() const { return (idle_observer.get() > 0); }
bool try_share(DocidRange &docid_range, uint32_t next_docid) __attribute__((noinline));
- template <typename Strategy, bool do_rank, bool do_limit, bool do_share_work>
- bool inner_match_loop(Context &context, MatchTools &tools, DocidRange docid_range) __attribute__((noinline));
+ template <typename IteratorT, bool do_rank, bool do_limit, bool do_share_work>
+ bool inner_match_loop(Context & params, IteratorT & search, DocidRange docid_range) __attribute__((noinline));
+
+ template <typename IteratorT, bool do_rank, bool do_limit, bool do_share_work>
+ void match_loop(MatchTools &matchTools, IteratorT search, RankProgram &ranking, HitCollector &hits) __attribute__((noinline));
- template <typename Strategy, bool do_rank, bool do_limit, bool do_share_work>
- void match_loop(MatchTools &tools, HitCollector &hits) __attribute__((noinline));
+ template <typename IteratorT, bool do_rank, bool do_limit>
+ void match_loop_helper_2(MatchTools &matchTools, IteratorT search, RankProgram &ranking, HitCollector &hits);
- template <bool do_rank, bool do_limit, bool do_share> void match_loop_helper_rank_limit_share(MatchTools &tools, HitCollector &hits);
- template <bool do_rank, bool do_limit> void match_loop_helper_rank_limit(MatchTools &tools, HitCollector &hits);
- template <bool do_rank> void match_loop_helper_rank(MatchTools &tools, HitCollector &hits);
- void match_loop_helper(MatchTools &tools, HitCollector &hits);
+ template <typename IteratorT, bool do_rank>
+ void match_loop_helper(MatchTools &matchTools, IteratorT search, RankProgram &ranking, HitCollector &hits);
- search::ResultSet::UP findMatches(MatchTools &tools);
+ search::ResultSet::UP findMatches(MatchTools &matchTools);
void processResult(const Doom & hardDoom, search::ResultSet::UP result, ResultProcessor::Context &context);
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp
index 9044cb79220..1e429616e7e 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp
@@ -19,48 +19,33 @@ namespace proton::matching {
namespace {
-bool contains_all(const HandleRecorder::HandleSet &old_set,
- const HandleRecorder::HandleSet &new_set)
+size_t
+tagMatchData(const HandleRecorder::HandleSet & handles, MatchData & md)
{
- for (TermFieldHandle handle: new_set) {
- if (old_set.find(handle) == old_set.end()) {
- return false;
- }
- }
- return true;
-}
-
-void tag_match_data(const HandleRecorder::HandleSet &handles, MatchData &match_data) {
- for (TermFieldHandle handle = 0; handle < match_data.getNumTermFields(); ++handle) {
+ size_t ignored(0);
+ for (TermFieldHandle handle(0); handle < md.getNumTermFields(); handle++) {
if (handles.find(handle) == handles.end()) {
- match_data.resolveTermField(handle)->tagAsNotNeeded();
+ md.resolveTermField(handle)->tagAsNotNeeded();
+ ignored++;
}
}
+ return ignored;
}
-} // namespace proton::matching::<unnamed>
-
-void
-MatchTools::setup(search::fef::RankProgram::UP rank_program, double termwise_limit)
+search::fef::RankProgram::UP setup_program(search::fef::RankProgram::UP program,
+ const MatchDataLayout &mdl,
+ const QueryEnvironment &queryEnv,
+ const Properties &featureOverrides)
{
- if (_search) {
- _match_data->soft_reset();
- }
- _rank_program = std::move(rank_program);
HandleRecorder recorder;
{
HandleRecorder::Binder bind(recorder);
- _rank_program->setup(*_match_data, _queryEnv, _featureOverrides);
- }
- bool can_reuse_search = (_search && !_search_has_changed &&
- contains_all(_used_handles, recorder.getHandles()));
- if (!can_reuse_search) {
- tag_match_data(recorder.getHandles(), *_match_data);
- _match_data->set_termwise_limit(termwise_limit);
- _search = _query.createSearch(*_match_data);
- _used_handles = recorder.getHandles();
- _search_has_changed = false;
+ program->setup(mdl, queryEnv, featureOverrides);
}
+ tagMatchData(recorder.getHandles(), program->match_data());
+ return program;
+}
+
}
MatchTools::MatchTools(QueryLimiter & queryLimiter,
@@ -80,42 +65,39 @@ MatchTools::MatchTools(QueryLimiter & queryLimiter,
_queryEnv(queryEnv),
_rankSetup(rankSetup),
_featureOverrides(featureOverrides),
- _match_data(mdl.createMatchData()),
- _rank_program(),
- _search(),
- _used_handles(),
- _search_has_changed(false)
+ _mdl(mdl),
+ _handleRecorder()
{
+ HandleRecorder::Binder bind(_handleRecorder);
}
-MatchTools::~MatchTools()
-{
-}
+MatchTools::~MatchTools() {}
-void
-MatchTools::setup_first_phase()
-{
- setup(_rankSetup.create_first_phase_program(),
- TermwiseLimit::lookup(_queryEnv.getProperties(),
- _rankSetup.get_termwise_limit()));
+search::fef::RankProgram::UP
+MatchTools::first_phase_program() const {
+ auto program = setup_program(_rankSetup.create_first_phase_program(),
+ _mdl, _queryEnv, _featureOverrides);
+ program->match_data().set_termwise_limit(TermwiseLimit::lookup(_queryEnv.getProperties(),
+ _rankSetup.get_termwise_limit()));
+ return program;
}
-void
-MatchTools::setup_second_phase()
-{
- setup(_rankSetup.create_second_phase_program());
+search::fef::RankProgram::UP
+MatchTools::second_phase_program() const {
+ return setup_program(_rankSetup.create_second_phase_program(),
+ _mdl, _queryEnv, _featureOverrides);
}
-void
-MatchTools::setup_summary()
-{
- setup(_rankSetup.create_summary_program());
+search::fef::RankProgram::UP
+MatchTools::summary_program() const {
+ return setup_program(_rankSetup.create_summary_program(),
+ _mdl, _queryEnv, _featureOverrides);
}
-void
-MatchTools::setup_dump()
-{
- setup(_rankSetup.create_dump_program());
+search::fef::RankProgram::UP
+MatchTools::dump_program() const {
+ return setup_program(_rankSetup.create_dump_program(),
+ _mdl, _queryEnv, _featureOverrides);
}
//-----------------------------------------------------------------------------
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h
index f47eda16cc1..b4f1f997d32 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h
@@ -23,20 +23,16 @@ class MatchTools
{
private:
using IRequestContext = search::queryeval::IRequestContext;
- QueryLimiter &_queryLimiter;
- const vespalib::Doom &_softDoom;
- const vespalib::Doom &_hardDoom;
- const Query &_query;
- MaybeMatchPhaseLimiter &_match_limiter;
- const QueryEnvironment &_queryEnv;
- const search::fef::RankSetup &_rankSetup;
- const search::fef::Properties &_featureOverrides;
- search::fef::MatchData::UP _match_data;
- search::fef::RankProgram::UP _rank_program;
- search::queryeval::SearchIterator::UP _search;
- HandleRecorder::HandleSet _used_handles;
- bool _search_has_changed;
- void setup(search::fef::RankProgram::UP, double termwise_limit = 1.0);
+ QueryLimiter & _queryLimiter;
+ const vespalib::Doom & _softDoom;
+ const vespalib::Doom & _hardDoom;
+ const Query & _query;
+ MaybeMatchPhaseLimiter & _match_limiter;
+ const QueryEnvironment & _queryEnv;
+ const search::fef::RankSetup & _rankSetup;
+ const search::fef::Properties & _featureOverrides;
+ search::fef::MatchDataLayout _mdl;
+ HandleRecorder _handleRecorder;
public:
typedef std::unique_ptr<MatchTools> UP;
MatchTools(const MatchTools &) = delete;
@@ -55,17 +51,15 @@ public:
const vespalib::Doom &getHardDoom() const { return _hardDoom; }
QueryLimiter & getQueryLimiter() { return _queryLimiter; }
MaybeMatchPhaseLimiter &match_limiter() { return _match_limiter; }
+ search::queryeval::SearchIterator::UP
+ createSearch(search::fef::MatchData &matchData) const {
+ return _query.createSearch(matchData);
+ }
bool has_second_phase_rank() const { return !_rankSetup.getSecondPhaseRank().empty(); }
- const search::fef::MatchData &match_data() const { return *_match_data; }
- search::fef::RankProgram &rank_program() { return *_rank_program; }
- search::queryeval::SearchIterator &search() { return *_search; }
- search::queryeval::SearchIterator::UP borrow_search() { return std::move(_search); }
- void give_back_search(search::queryeval::SearchIterator::UP search_in) { _search = std::move(search_in); }
- void tag_search_as_changed() { _search_has_changed = true; }
- void setup_first_phase();
- void setup_second_phase();
- void setup_summary();
- void setup_dump();
+ search::fef::RankProgram::UP first_phase_program() const;
+ search::fef::RankProgram::UP second_phase_program() const;
+ search::fef::RankProgram::UP summary_program() const;
+ search::fef::RankProgram::UP dump_program() const;
};
class MatchToolsFactory : public vespalib::noncopyable