diff options
author | Henning Baldersheim <balder@oath.com> | 2018-08-15 09:28:42 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@oath.com> | 2018-08-27 09:22:14 +0200 |
commit | be6729d2eadb3abe61613acb82c59a137ccf12a0 (patch) | |
tree | 7e648f022c922ce8cc700bff77089a2aa2527ce0 /searchcore | |
parent | 73ed7ad7c3cbd41d5ca44c4f2f7ae547fe4c5abe (diff) |
- Add option to increment an attribute for every doc matched.
- Add option to increment an attribute for every doc reranked.
- Add option to increment an attribute for every doc fetched.
Conflicts:
searchcore/src/vespa/searchcore/proton/matching/attribute_operation.cpp
Conflicts:
searchlib/src/vespa/searchlib/attribute/i_attribute_functor.h
Diffstat (limited to 'searchcore')
17 files changed, 199 insertions, 47 deletions
diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp index 293d87870e5..8d75c8b8d24 100644 --- a/searchcore/src/tests/proton/matching/matching_test.cpp +++ b/searchcore/src/tests/proton/matching/matching_test.cpp @@ -327,10 +327,14 @@ struct MyWorld { } }; + struct DummyAttributeExecutor : public IAttributeExecutor { + void asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override {} + }; void verify_diversity_filter(SearchRequest::SP req, bool expectDiverse) { Matcher::SP matcher = createMatcher(); search::fef::Properties overrides; - auto mtf = matcher->create_match_tools_factory(*req, searchContext, attributeContext, metaStore, overrides); + DummyAttributeExecutor attrExec; + auto mtf = matcher->create_match_tools_factory(*req, searchContext, attributeContext, attrExec, metaStore, overrides); auto diversity = mtf->createDiversifier(); EXPECT_EQUAL(expectDiverse, static_cast<bool>(diversity)); } @@ -339,8 +343,9 @@ struct MyWorld { Matcher::SP matcher = createMatcher(); SearchRequest::SP request = createSimpleRequest("f1", "spread"); search::fef::Properties overrides; + DummyAttributeExecutor attrExec; MatchToolsFactory::UP match_tools_factory = matcher->create_match_tools_factory( - *request, searchContext, attributeContext, metaStore, overrides); + *request, searchContext, attributeContext, attrExec, metaStore, overrides); MatchTools::UP match_tools = match_tools_factory->createMatchTools(); match_tools->setup_first_phase(); return match_tools->match_data().get_termwise_limit(); @@ -353,8 +358,9 @@ struct MyWorld { owned_objects.context.reset(new MatchContext(std::make_unique<MyAttributeContext>(), std::make_unique<FakeSearchContext>())); vespalib::SimpleThreadBundle threadBundle(threads); + DummyAttributeExecutor attrExec; SearchReply::UP reply = matcher->match(*req, threadBundle, searchContext, attributeContext, - *sessionManager, metaStore, std::move(owned_objects)); + attrExec, *sessionManager, metaStore, std::move(owned_objects)); matchingStats.add(matcher->getStats()); return reply; } @@ -386,12 +392,14 @@ struct MyWorld { FeatureSet::SP getSummaryFeatures(DocsumRequest::SP req) { Matcher::SP matcher = createMatcher(); - return matcher->getSummaryFeatures(*req, searchContext, attributeContext, *sessionManager); + DummyAttributeExecutor attrExec; + return matcher->getSummaryFeatures(*req, searchContext, attributeContext, attrExec, *sessionManager); } FeatureSet::SP getRankFeatures(DocsumRequest::SP req) { Matcher::SP matcher = createMatcher(); - return matcher->getRankFeatures(*req, searchContext, attributeContext, *sessionManager); + DummyAttributeExecutor attrExec; + return matcher->getRankFeatures(*req, searchContext, attributeContext, attrExec, *sessionManager); } }; diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp index d0a1e891150..f08300ba3c6 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp @@ -581,6 +581,17 @@ AttributeManager::asyncForEachAttribute(std::shared_ptr<IAttributeFunctor> func) } } +void +AttributeManager::asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const { + AttributeMap::const_iterator itr = _attributes.find(name); + if (itr == _attributes.end() || itr->second.isExtra() || !func) { + return; + } + AttributeVector::SP attrsp = itr->second.getAttribute(); + _attributeFieldWriter.execute(_attributeFieldWriter.getExecutorId(attrsp->getNamePrefix()), + [attrsp, func]() { (*func)(*attrsp); }); +} + ExclusiveAttributeReadAccessor::UP AttributeManager::getExclusiveReadAccessor(const vespalib::string &name) const { diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h index bf0258deffc..1ddba45ac46 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h @@ -176,6 +176,7 @@ public: const std::vector<search::AttributeVector *> &getWritableAttributes() const override; void asyncForEachAttribute(std::shared_ptr<IAttributeFunctor> func) const override; + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override; ExclusiveAttributeReadAccessor::UP getExclusiveReadAccessor(const vespalib::string &name) const override; @@ -185,3 +186,4 @@ public: }; } // namespace proton + diff --git a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp index 48332bedbb7..e8878b29678 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp @@ -200,6 +200,18 @@ FilterAttributeManager::asyncForEachAttribute(std::shared_ptr<IAttributeFunctor> } } +void +FilterAttributeManager::asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const { + AttributeGuard::UP attr = _mgr->getAttribute(name); + if (!attr) { return; } + search::ISequencedTaskExecutor &attributeFieldWriter = getAttributeFieldWriter(); + attributeFieldWriter.execute(attributeFieldWriter.getExecutorId((*attr)->getNamePrefix()), + [attr=std::move(attr), func]() mutable { + (*func)(dynamic_cast<const search::AttributeVector&>(*attr)); + }); + +} + ExclusiveAttributeReadAccessor::UP FilterAttributeManager::getExclusiveReadAccessor(const vespalib::string &name) const { diff --git a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h index f6a67a5ae3c..918432ddcd7 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h @@ -54,6 +54,9 @@ public: ExclusiveAttributeReadAccessor::UP getExclusiveReadAccessor(const vespalib::string &name) const override; void setImportedAttributes(std::unique_ptr<ImportedAttributesRepo> attributes) override; const ImportedAttributesRepo *getImportedAttributes() const override; + + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override; }; } // namespace proton + diff --git a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h index dd8f9a5df90..6df9b207281 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h @@ -5,6 +5,7 @@ #include "attribute_collection_spec.h" #include "exclusive_attribute_read_accessor.h" #include "i_attribute_factory.h" +#include <vespa/searchlib/attribute/i_attribute_functor.h> #include <vespa/searchcorespi/flush/iflushtarget.h> #include <vespa/searchlib/attribute/iattributemanager.h> #include <vespa/searchlib/common/serialnum.h> @@ -25,7 +26,7 @@ class ImportedAttributesRepo; * The attribute manager should handle initialization and loading of attribute vectors, * and then provide access to the attributes for feeding, searching and flushing. */ -struct IAttributeManager : public search::IAttributeManager +struct IAttributeManager : public search::IAttributeManager, public search::attribute::IAttributeExecutor { using SP = std::shared_ptr<IAttributeManager>; using OnWriteDoneType = const std::shared_ptr<search::IDestructorCallback> &; diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp index dac9753773c..908c7e887a3 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp +++ b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp @@ -137,7 +137,8 @@ DocsumContext::createSlimeReply() DocsumContext::DocsumContext(const DocsumRequest & request, IDocsumWriter & docsumWriter, IDocsumStore & docsumStore, const Matcher::SP & matcher, ISearchContext & searchCtx, IAttributeContext & attrCtx, - search::IAttributeManager & attrMgr, SessionManager & sessionMgr) : + IAttributeManager & attrMgr, const IAttributeExecutor & attrExec, + SessionManager & sessionMgr) : _request(request), _docsumWriter(docsumWriter), _docsumStore(docsumStore), @@ -145,6 +146,7 @@ DocsumContext::DocsumContext(const DocsumRequest & request, IDocsumWriter & docs _searchCtx(searchCtx), _attrCtx(attrCtx), _attrMgr(attrMgr), + _attrExec(attrExec), _docsumState(*this), _sessionMgr(sessionMgr) { @@ -165,7 +167,7 @@ DocsumContext::FillSummaryFeatures(search::docsummary::GetDocsumsState * state, { assert(&_docsumState == state); if (_matcher->canProduceSummaryFeatures()) { - state->_summaryFeatures = _matcher->getSummaryFeatures(_request, _searchCtx, _attrCtx, _sessionMgr); + state->_summaryFeatures = _matcher->getSummaryFeatures(_request, _searchCtx, _attrCtx, _attrExec, _sessionMgr); } state->_summaryFeaturesCached = false; } @@ -178,7 +180,7 @@ DocsumContext::FillRankFeatures(search::docsummary::GetDocsumsState * state, sea if ((state->_args.GetQueryFlags() & search::fs4transport::QFLAG_DUMP_FEATURES) == 0) { return; } - state->_rankFeatures = _matcher->getRankFeatures(_request, _searchCtx, _attrCtx, _sessionMgr); + state->_rankFeatures = _matcher->getRankFeatures(_request, _searchCtx, _attrCtx, _attrExec, _sessionMgr); } namespace { diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h index 239108ed075..4be67628b1f 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h +++ b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h @@ -23,6 +23,7 @@ private: matching::ISearchContext & _searchCtx; search::attribute::IAttributeContext & _attrCtx; search::IAttributeManager & _attrMgr; + const search::attribute::IAttributeExecutor & _attrExec; search::docsummary::GetDocsumsState _docsumState; matching::SessionManager & _sessionMgr; @@ -40,14 +41,15 @@ public: matching::ISearchContext & searchCtx, search::attribute::IAttributeContext & attrCtx, search::IAttributeManager & attrMgr, + const search::attribute::IAttributeExecutor & attrExec, matching::SessionManager & sessionMgr); search::engine::DocsumReply::UP getDocsums(); // Implements GetDocsumsStateCallback - virtual void FillSummaryFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override; - virtual void FillRankFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override; - virtual void ParseLocation(search::docsummary::GetDocsumsState * state) override; + void FillSummaryFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override; + void FillRankFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override; + void ParseLocation(search::docsummary::GetDocsumsState * state) override; }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp index 6bce05b6c26..a88a44130f2 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp @@ -4,6 +4,7 @@ #include "docid_range_scheduler.h" #include "match_loop_communicator.h" #include "match_thread.h" +#include <vespa/searchlib/attribute/attribute_operation.h> #include <vespa/searchlib/common/featureset.h> #include <vespa/vespalib/util/thread_bundle.h> @@ -15,6 +16,7 @@ namespace proton::matching { using namespace search::fef; using search::queryeval::SearchIterator; using search::FeatureSet; +using search::attribute::AttributeOperation; namespace { @@ -137,6 +139,10 @@ MatchMaster::getFeatureSet(const MatchToolsFactory &mtf, LOG(debug, "getFeatureSet: Did not find hit for docid '%u'. Skipping hit", docs[i]); } } + if (mtf.hasOnReRankOperation()) { + mtf.runOnReRankOperation(AttributeOperation::create(mtf.getOnSummaryAttributeType(), + mtf.getOnSummaryOperation(), docs)); + } return retval; } diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp index 9b5f898495c..2591a176e19 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp @@ -2,15 +2,17 @@ #include "match_thread.h" #include "document_scorer.h" +#include <vespa/searchlib/attribute/attribute_operation.h> +#include <vespa/searchlib/attribute/i_attribute_functor.h> +#include <vespa/searchcore/grouping/groupingmanager.h> +#include <vespa/searchcore/grouping/groupingcontext.h> +#include <vespa/searchlib/common/bitvector.h> #include <vespa/searchlib/common/featureset.h> #include <vespa/searchlib/query/base.h> #include <vespa/searchlib/queryeval/multibitvectoriterator.h> #include <vespa/searchlib/queryeval/andnotsearch.h> #include <vespa/vespalib/util/closure.h> #include <vespa/vespalib/util/thread_bundle.h> -#include <vespa/searchcore/grouping/groupingmanager.h> -#include <vespa/searchcore/grouping/groupingcontext.h> -#include <vespa/searchlib/common/bitvector.h> #include <vespa/log/log.h> LOG_SETUP(".proton.matching.match_thread"); @@ -25,6 +27,7 @@ using search::fef::FeatureResolver; using search::fef::LazyValue; using search::queryeval::HitCollector; using search::queryeval::SortedHitSequence; +using search::attribute::AttributeOperation; namespace { @@ -247,8 +250,6 @@ MatchThread::match_loop_helper(MatchTools &tools, HitCollector &hits) } } -//----------------------------------------------------------------------------- - search::ResultSet::UP MatchThread::findMatches(MatchTools &tools) { @@ -267,7 +268,8 @@ MatchThread::findMatches(MatchTools &tools) tools.setup_second_phase(); DocidRange docid_range = scheduler.total_span(thread_id); tools.search().initRange(docid_range.begin, docid_range.end); - auto sorted_hit_seq = matchToolsFactory.should_diversify() + const MatchToolsFactory & mtf = matchToolsFactory; + auto sorted_hit_seq = mtf.should_diversify() ? hits.getSortedHitSequence(matchParams.arraySize) : hits.getSortedHitSequence(matchParams.heapSize); WaitTimer select_best_timer(wait_time_s); @@ -278,6 +280,10 @@ MatchThread::findMatches(MatchTools &tools) kept_hits.clear(); } uint32_t reRanked = hits.reRank(scorer, std::move(kept_hits)); + if (mtf.hasOnReRankOperation()) { + mtf.runOnReRankOperation(AttributeOperation::create(mtf.getOnReRankAttributeType(), + mtf.getOnReRankOperation(), hits.getReRankedHits())); + } thread_stats.docsReRanked(reRanked); } { // rank scaling @@ -344,6 +350,11 @@ MatchThread::processResult(const Doom & hardDoom, } } } + const MatchToolsFactory & mtf = matchToolsFactory; + if (mtf.hasOnMatchOperation() ) { + mtf.runOnMatchOperation(AttributeOperation::create(mtf.getOnMatchAttributeType(), mtf.getOnMatchOperation(), + search::ResultSet::stealResult(std::move(*result)))); + } if (hasGrouping) { context.grouping->setDistributionKey(_distributionKey); } diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp index 055bc5fe1c2..8b289bd10eb 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp @@ -16,6 +16,7 @@ using search::attribute::diversity::DiversityFilter; using namespace search::fef; using namespace search::fef::indexproperties::matchphase; using namespace search::fef::indexproperties::matching; +using namespace search::fef::indexproperties; using search::IDocumentMetaStore; namespace proton::matching { @@ -150,6 +151,7 @@ MatchToolsFactory(QueryLimiter & queryLimiter, vespalib::stringref queryStack, const vespalib::string & location, const ViewResolver & viewResolver, + const IAttributeExecutor & attrExec, const IDocumentMetaStore & metaStore, const IIndexEnvironment & indexEnv, const RankSetup & rankSetup, @@ -162,6 +164,7 @@ MatchToolsFactory(QueryLimiter & queryLimiter, _match_limiter(), _queryEnv(indexEnv, attributeContext, rankProperties), _mdl(), + _attrExec(attrExec), _rankSetup(rankSetup), _featureOverrides(featureOverrides), _diversityParams(), @@ -199,7 +202,8 @@ MatchToolsFactory::createMatchTools() const *_match_limiter, _queryEnv, _mdl, _rankSetup, _featureOverrides); } -std::unique_ptr<IDiversifier> MatchToolsFactory::createDiversifier() const +std::unique_ptr<IDiversifier> +MatchToolsFactory::createDiversifier() const { if ( !_diversityParams.enabled() ) { return std::unique_ptr<IDiversifier>(); @@ -214,4 +218,70 @@ std::unique_ptr<IDiversifier> MatchToolsFactory::createDiversifier() const _diversityParams.cutoff_strategy == DiversityParams::CutoffStrategy::STRICT); } +bool +MatchToolsFactory::hasOnMatchOperation() const { + return ! execute::onmatch::Attribute::lookup(_queryEnv.getProperties()).empty() && + ! execute::onmatch::Operation::lookup(_queryEnv.getProperties()).empty(); +} + +vespalib::string +MatchToolsFactory::getOnMatchOperation() const { + return execute::onmatch::Operation::lookup(_queryEnv.getProperties()); +} + +void +MatchToolsFactory::runOnMatchOperation(std::shared_ptr<IAttributeFunctor> count) const { + _attrExec.asyncForAttribute(execute::onmatch::Attribute::lookup(_queryEnv.getProperties()), std::move(count)); +} + +search::attribute::BasicType +MatchToolsFactory::getOnMatchAttributeType() const { + auto attr = _requestContext.getAttribute(execute::onmatch::Attribute::lookup(_queryEnv.getProperties())); + return attr ? attr->getBasicType() : BasicType::NONE; +} + +bool +MatchToolsFactory::hasOnReRankOperation() const { + return ! execute::onrerank::Attribute::lookup(_queryEnv.getProperties()).empty() && + ! execute::onrerank::Operation::lookup(_queryEnv.getProperties()).empty(); +} + +vespalib::string +MatchToolsFactory::getOnReRankOperation() const { + return execute::onrerank::Operation::lookup(_queryEnv.getProperties()); +} + +void +MatchToolsFactory::runOnReRankOperation(std::shared_ptr<IAttributeFunctor> count) const { + _attrExec.asyncForAttribute(execute::onrerank::Attribute::lookup(_queryEnv.getProperties()), std::move(count)); +} + +search::attribute::BasicType +MatchToolsFactory::getOnReRankAttributeType() const { + auto attr = _requestContext.getAttribute(execute::onrerank::Attribute::lookup(_queryEnv.getProperties())); + return attr ? attr->getBasicType() : BasicType::NONE; +} + +bool +MatchToolsFactory::hasOnSummaryOperation() const { + return ! execute::onsummary::Attribute::lookup(_queryEnv.getProperties()).empty() && + ! execute::onsummary::Operation::lookup(_queryEnv.getProperties()).empty(); +} + +vespalib::string +MatchToolsFactory::getOnSummaryOperation() const { + return execute::onsummary::Operation::lookup(_queryEnv.getProperties()); +} + +void +MatchToolsFactory::runOnSummaryOperation(std::shared_ptr<IAttributeFunctor> count) const { + _attrExec.asyncForAttribute(execute::onsummary::Attribute::lookup(_queryEnv.getProperties()), std::move(count)); +} + +search::attribute::BasicType +MatchToolsFactory::getOnSummaryAttributeType() const { + auto attr = _requestContext.getAttribute(execute::onsummary::Attribute::lookup(_queryEnv.getProperties())); + return attr ? attr->getBasicType() : BasicType::NONE; +} + } diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h index 314dfc64a9d..9a28dc1ed05 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h +++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h @@ -6,18 +6,17 @@ #include "isearchcontext.h" #include "query.h" #include "viewresolver.h" -#include <vespa/vespalib/util/doom.h> #include "querylimiter.h" #include "match_phase_limiter.h" #include "handlerecorder.h" #include "requestcontext.h" - -#include <vespa/vespalib/util/clock.h> +#include <vespa/searchlib/attribute/i_attribute_functor.h> #include <vespa/searchlib/queryeval/blueprint.h> #include <vespa/searchlib/fef/fef.h> #include <vespa/searchlib/common/idocumentmetastore.h> #include <vespa/searchlib/queryeval/idiversifier.h> - +#include <vespa/vespalib/util/doom.h> +#include <vespa/vespalib/util/clock.h> namespace proton::matching { @@ -73,6 +72,8 @@ public: class MatchToolsFactory : public vespalib::noncopyable { private: + using IAttributeExecutor = search::attribute::IAttributeExecutor; + using IAttributeFunctor = search::attribute::IAttributeFunctor; QueryLimiter & _queryLimiter; RequestContext _requestContext; const vespalib::Doom _hardDoom; @@ -80,12 +81,14 @@ private: MaybeMatchPhaseLimiter::UP _match_limiter; QueryEnvironment _queryEnv; search::fef::MatchDataLayout _mdl; + const IAttributeExecutor & _attrExec; const search::fef::RankSetup & _rankSetup; const search::fef::Properties & _featureOverrides; DiversityParams _diversityParams; bool _valid; public: - typedef std::unique_ptr<MatchToolsFactory> UP; + using UP = std::unique_ptr<MatchToolsFactory>; + using BasicType = search::attribute::BasicType; MatchToolsFactory(QueryLimiter & queryLimiter, const vespalib::Doom & softDoom, @@ -95,6 +98,7 @@ public: vespalib::stringref queryStack, const vespalib::string &location, const ViewResolver &viewResolver, + const IAttributeExecutor & attrExec, const search::IDocumentMetaStore &metaStore, const search::fef::IIndexEnvironment &indexEnv, const search::fef::RankSetup &rankSetup, @@ -108,6 +112,19 @@ public: std::unique_ptr<search::queryeval::IDiversifier> createDiversifier() const; search::queryeval::Blueprint::HitEstimate estimate() const { return _query.estimate(); } bool has_first_phase_rank() const { return !_rankSetup.getFirstPhaseRank().empty(); } + bool hasOnMatchOperation() const; + BasicType getOnMatchAttributeType() const; + vespalib::string getOnMatchOperation() const; + void runOnMatchOperation(std::shared_ptr<IAttributeFunctor> count) const; + bool hasOnReRankOperation() const; + BasicType getOnReRankAttributeType() const; + vespalib::string getOnReRankOperation() const; + void runOnReRankOperation(std::shared_ptr<IAttributeFunctor> count) const; + bool hasOnSummaryOperation() const; + BasicType getOnSummaryAttributeType() const; + vespalib::string getOnSummaryOperation() const; + void runOnSummaryOperation(std::shared_ptr<IAttributeFunctor> count) const; + const RequestContext & requestContext() const { return _requestContext; } }; } diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp index bce13a96da7..c387d3ea4eb 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp @@ -95,7 +95,7 @@ bool willNotNeedRanking(const SearchRequest & request, const GroupingContext & g FeatureSet::SP Matcher::getFeatureSet(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx, - SessionManager & sessionMgr, bool summaryFeatures) + const IAttributeExecutor & attrExec, SessionManager & sessionMgr, bool summaryFeatures) { SessionId sessionId(&req.sessionId[0], req.sessionId.size()); if (!sessionId.empty()) { @@ -113,7 +113,7 @@ Matcher::getFeatureSet(const DocsumRequest & req, ISearchContext & searchCtx, IA } StupidMetaStore metaStore; - MatchToolsFactory::UP mtf = create_match_tools_factory(req, searchCtx, attrCtx, metaStore, + MatchToolsFactory::UP mtf = create_match_tools_factory(req, searchCtx, attrCtx, attrExec, metaStore, req.propertiesMap.featureOverrides()); if (!mtf->valid()) { LOG(warning, "getFeatureSet(%s): query execution failed (invalid query). Returning empty feature set", @@ -159,8 +159,8 @@ using search::fef::indexproperties::softtimeout::Factor; std::unique_ptr<MatchToolsFactory> Matcher::create_match_tools_factory(const search::engine::Request &request, ISearchContext &searchContext, - IAttributeContext &attrContext, const search::IDocumentMetaStore &metaStore, - const Properties &feature_overrides) const + IAttributeContext &attrContext, const IAttributeExecutor & attrExec, + const search::IDocumentMetaStore &metaStore, const Properties &feature_overrides) const { const Properties & rankProperties = request.propertiesMap.rankProperties(); bool softTimeoutEnabled = Enabled::lookup(rankProperties, _rankSetup->getSoftTimeoutEnabled()); @@ -176,7 +176,8 @@ Matcher::create_match_tools_factory(const search::engine::Request &request, ISea return std::make_unique<MatchToolsFactory>(_queryLimiter, vespalib::Doom(_clock, safeDoom), vespalib::Doom(_clock, request.getTimeOfDoom()), searchContext, attrContext, request.getStackRef(), request.location, _viewResolver, - metaStore, _indexEnv, *_rankSetup, rankProperties, feature_overrides); + attrExec, metaStore, _indexEnv, *_rankSetup, + rankProperties, feature_overrides); } SearchReply::UP @@ -205,8 +206,8 @@ Matcher::computeNumThreadsPerSearch(Blueprint::HitEstimate hits, const Propertie SearchReply::UP Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundle, ISearchContext &searchContext, IAttributeContext &attrContext, - SessionManager &sessionMgr, const search::IDocumentMetaStore &metaStore, - SearchSession::OwnershipBundle &&owned_objects) + const IAttributeExecutor & attrExec, SessionManager &sessionMgr, + const search::IDocumentMetaStore &metaStore, SearchSession::OwnershipBundle &&owned_objects) { fastos::StopWatch total_matching_time; total_matching_time.start(); @@ -236,7 +237,7 @@ Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundl feature_overrides = owned_objects.feature_overrides.get(); } MatchToolsFactory::UP mtf = create_match_tools_factory(request, searchContext, attrContext, - metaStore, *feature_overrides); + attrExec, metaStore, *feature_overrides); if (!mtf->valid()) { reply->errorCode = ECODE_QUERY_PARSE_ERROR; reply->errorMessage = "query execution failed (invalid query)"; @@ -325,17 +326,17 @@ Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundl } FeatureSet::SP -Matcher::getSummaryFeatures(const DocsumRequest & req, ISearchContext & searchCtx, - IAttributeContext & attrCtx, SessionManager &sessionMgr) +Matcher::getSummaryFeatures(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx, + const IAttributeExecutor & attrExec, SessionManager &sessionMgr) { - return getFeatureSet(req, searchCtx, attrCtx, sessionMgr, true); + return getFeatureSet(req, searchCtx, attrCtx, attrExec, sessionMgr, true); } FeatureSet::SP -Matcher::getRankFeatures(const DocsumRequest & req, ISearchContext & searchCtx, - IAttributeContext & attrCtx, SessionManager &sessionMgr) +Matcher::getRankFeatures(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx, + const IAttributeExecutor & attrExec, SessionManager &sessionMgr) { - return getFeatureSet(req, searchCtx, attrCtx, sessionMgr, false); + return getFeatureSet(req, searchCtx, attrCtx, attrExec, sessionMgr, false); } } diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.h b/searchcore/src/vespa/searchcore/proton/matching/matcher.h index 4786e9f7f7c..15df21378d2 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/matcher.h +++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.h @@ -8,6 +8,7 @@ #include "search_session.h" #include "viewresolver.h" #include <vespa/searchcore/proton/matching/querylimiter.h> +#include <vespa/searchlib/attribute/i_attribute_functor.h> #include <vespa/searchlib/common/featureset.h> #include <vespa/searchlib/common/resultset.h> #include <vespa/searchlib/queryeval/blueprint.h> @@ -44,6 +45,7 @@ class MatchToolsFactory; class Matcher { private: + using IAttributeExecutor = search::attribute::IAttributeExecutor; IndexEnvironment _indexEnv; search::fef::BlueprintFactory _blueprintFactory; search::fef::RankSetup::SP _rankSetup; @@ -57,7 +59,7 @@ private: search::FeatureSet::SP getFeatureSet(const search::engine::DocsumRequest & req, ISearchContext & searchCtx, search::attribute::IAttributeContext & attrCtx, - SessionManager &sessionMgr, bool summaryFeatures); + const IAttributeExecutor & attrExec, SessionManager &sessionMgr, bool summaryFeatures); std::unique_ptr<search::engine::SearchReply> handleGroupingSession(SessionManager &sessionMgr, search::grouping::GroupingContext & groupingContext, @@ -69,7 +71,6 @@ public: /** * Convenience typedefs. */ - typedef std::unique_ptr<Matcher> UP; typedef std::shared_ptr<Matcher> SP; @@ -104,6 +105,7 @@ public: std::unique_ptr<MatchToolsFactory> create_match_tools_factory(const search::engine::Request &request, ISearchContext &searchContext, search::attribute::IAttributeContext &attrContext, + const IAttributeExecutor & attrExec, const search::IDocumentMetaStore &metaStore, const search::fef::Properties &feature_overrides) const; @@ -121,7 +123,7 @@ public: std::unique_ptr<search::engine::SearchReply> match(const search::engine::SearchRequest &request, vespalib::ThreadBundle &threadBundle, ISearchContext &searchContext, search::attribute::IAttributeContext &attrContext, - SessionManager &sessionManager, const search::IDocumentMetaStore &metaStore, + const IAttributeExecutor & attrExec, SessionManager &sessionManager, const search::IDocumentMetaStore &metaStore, SearchSession::OwnershipBundle &&owned_objects); /** @@ -136,7 +138,8 @@ public: **/ search::FeatureSet::SP getSummaryFeatures(const search::engine::DocsumRequest & req, ISearchContext & searchCtx, - search::attribute::IAttributeContext & attrCtx, SessionManager &sessionManager); + search::attribute::IAttributeContext & attrCtx, + const IAttributeExecutor & attrExec, SessionManager &sessionManager); /** * Perform matching for the documents in the given docsum request @@ -150,7 +153,8 @@ public: **/ search::FeatureSet::SP getRankFeatures(const search::engine::DocsumRequest & req, ISearchContext & searchCtx, - search::attribute::IAttributeContext & attrCtx, SessionManager &sessionManager); + search::attribute::IAttributeContext & attrCtx, + const IAttributeExecutor & attrExec, SessionManager &sessionManager); /** * @return true if this rankprofile has summary-features enabled diff --git a/searchcore/src/vespa/searchcore/proton/server/matchview.cpp b/searchcore/src/vespa/searchcore/proton/server/matchview.cpp index 9af648917c4..ab9a4b93b5f 100644 --- a/searchcore/src/vespa/searchcore/proton/server/matchview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/matchview.cpp @@ -77,7 +77,7 @@ MatchView::match(const ISearchHandler::SP &searchHandler, const SearchRequest &r MatchContext *ctx = owned_objects.context.get(); const search::IDocumentMetaStore & dms = owned_objects.readGuard->get(); return matcher->match(req, threadBundle, ctx->getSearchContext(), ctx->getAttributeContext(), - *_sessionMgr, dms, std::move(owned_objects)); + *_attrMgr, *_sessionMgr, dms, std::move(owned_objects)); } diff --git a/searchcore/src/vespa/searchcore/proton/server/searchview.cpp b/searchcore/src/vespa/searchcore/proton/server/searchview.cpp index 232f0bdba6c..6879e106c5e 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchview.cpp @@ -147,9 +147,10 @@ SearchView::getDocsumsInternal(const DocsumRequest & req) IDocsumStore::UP store(_summarySetup->createDocsumStore(req.resultClassName)); Matcher::SP matcher = _matchView->getMatcher(req.ranking); MatchContext::UP mctx = _matchView->createContext(); - DocsumContext::UP ctx(new DocsumContext(req, _summarySetup->getDocsumWriter(), *store, matcher, - mctx->getSearchContext(), mctx->getAttributeContext(), - *_summarySetup->getAttributeManager(), *getSessionManager())); + auto ctx = std::make_unique<DocsumContext>(req, _summarySetup->getDocsumWriter(), *store, matcher, + mctx->getSearchContext(), mctx->getAttributeContext(), + *_summarySetup->getAttributeManager(), *_matchView->getAttributeManager(), + *getSessionManager()); SearchView::InternalDocsumReply reply(ctx->getDocsums(), true); uint64_t endGeneration = readGuard->get().getCurrentGeneration(); if (startGeneration != endGeneration) { diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h index 4ad3aa5fb42..9fc019a2ded 100644 --- a/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h +++ b/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h @@ -75,6 +75,7 @@ public: const ImportedAttributesRepo *getImportedAttributes() const override { return _importedAttributes.get(); } + void asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override { } }; } |