diff options
51 files changed, 463 insertions, 469 deletions
diff --git a/searchlib/src/vespa/searchlib/attribute/i_attribute_functor.h b/searchcommon/src/vespa/searchcommon/attribute/i_attribute_functor.h index 2761f0785f4..3ef9d2abf1a 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_attribute_functor.h +++ b/searchcommon/src/vespa/searchcommon/attribute/i_attribute_functor.h @@ -4,10 +4,10 @@ #include <vespa/vespalib/stllike/string.h> -namespace search { class AttributeVector; } - namespace search::attribute { +class IAttributeVector; + /* * Interface class for access attribute in correct attribute write * thread as async callback from asyncForEachAttribute() call on @@ -16,7 +16,7 @@ namespace search::attribute { class IAttributeFunctor { public: - virtual void operator()(const search::AttributeVector &attributeVector) = 0; + virtual void operator()(const IAttributeVector &attributeVector) = 0; virtual ~IAttributeFunctor() { } }; diff --git a/searchcommon/src/vespa/searchcommon/attribute/iattributecontext.h b/searchcommon/src/vespa/searchcommon/attribute/iattributecontext.h index c283abf3ced..b80711a2e76 100644 --- a/searchcommon/src/vespa/searchcommon/attribute/iattributecontext.h +++ b/searchcommon/src/vespa/searchcommon/attribute/iattributecontext.h @@ -2,6 +2,7 @@ #pragma once +#include "i_attribute_functor.h" #include "iattributevector.h" namespace search::attribute { @@ -9,7 +10,7 @@ namespace search::attribute { /** * This is an interface used to access all registered attribute vectors. **/ -class IAttributeContext { +class IAttributeContext : public IAttributeExecutor { public: typedef vespalib::string string; /** Convenience typedefs **/ diff --git a/searchcore/src/tests/grouping/CMakeLists.txt b/searchcore/src/tests/grouping/CMakeLists.txt index 8108028c717..781f0cab66f 100644 --- a/searchcore/src/tests/grouping/CMakeLists.txt +++ b/searchcore/src/tests/grouping/CMakeLists.txt @@ -5,5 +5,6 @@ vespa_add_executable(searchcore_grouping_test_app TEST DEPENDS searchcore_grouping searchcore_matching + searchlib_test ) vespa_add_test(NAME searchcore_grouping_test_app COMMAND searchcore_grouping_test_app) diff --git a/searchcore/src/tests/grouping/grouping.cpp b/searchcore/src/tests/grouping/grouping.cpp index 7e21fffe9fd..3f166ee9723 100644 --- a/searchcore/src/tests/grouping/grouping.cpp +++ b/searchcore/src/tests/grouping/grouping.cpp @@ -10,6 +10,7 @@ #include <vespa/searchcore/grouping/groupingmanager.h> #include <vespa/searchcore/grouping/groupingsession.h> #include <vespa/searchcore/proton/matching/sessionmanager.h> +#include <vespa/searchlib/test/mock_attribute_context.h> #include <iostream> #include <vespa/log/log.h> @@ -20,7 +21,7 @@ using namespace search::aggregation; using namespace search::expression; using namespace search::grouping; using namespace search; - +using search::attribute::test::MockAttributeContext; using proton::matching::SessionManager; @@ -30,55 +31,8 @@ const uint32_t NUM_DOCS = 1000; //----------------------------------------------------------------------------- -class MyAttributeContext : public IAttributeContext -{ -private: - typedef std::map<string, IAttributeVector *> Map; - Map _vectors; - -public: - const IAttributeVector *get(const string &name) const { - if (_vectors.find(name) == _vectors.end()) { - return 0; - } - return _vectors.find(name)->second; - } - virtual const IAttributeVector * - getAttribute(const string &name) const override { - return get(name); - } - virtual const IAttributeVector * - getAttributeStableEnum(const string &name) const override { - return get(name); - } - virtual void - getAttributeList(std::vector<const IAttributeVector *> & list) const override { - Map::const_iterator pos = _vectors.begin(); - Map::const_iterator end = _vectors.end(); - for (; pos != end; ++pos) { - list.push_back(pos->second); - } - } - ~MyAttributeContext() { - Map::iterator pos = _vectors.begin(); - Map::iterator end = _vectors.end(); - for (; pos != end; ++pos) { - delete pos->second; - } - } - - //------------------------------------------------------------------------- - - void add(IAttributeVector *attr) { - _vectors[attr->getName()] = attr; - } -}; - - -//----------------------------------------------------------------------------- - struct MyWorld { - MyAttributeContext attributeContext; + MockAttributeContext attributeContext; void basicSetup() { // attribute context diff --git a/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp b/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp index bd539999b5d..b0bf905ba75 100644 --- a/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp +++ b/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp @@ -19,7 +19,7 @@ #include <vespa/searchcore/proton/test/attribute_utils.h> #include <vespa/searchcore/proton/test/attribute_vectors.h> #include <vespa/searchlib/attribute/attributefactory.h> -#include <vespa/searchlib/attribute/i_attribute_functor.h> +#include <vespa/searchcommon/attribute/i_attribute_functor.h> #include <vespa/searchlib/attribute/attributevector.hpp> #include <vespa/searchlib/attribute/attribute_read_guard.h> #include <vespa/searchlib/attribute/imported_attribute_vector.h> @@ -85,7 +85,7 @@ class MyAttributeFunctor : public search::attribute::IAttributeFunctor public: void - operator()(const search::AttributeVector &attributeVector) override { + operator()(const search::attribute::IAttributeVector &attributeVector) override { _names.push_back(attributeVector.getName()); } diff --git a/searchcore/src/tests/proton/common/CMakeLists.txt b/searchcore/src/tests/proton/common/CMakeLists.txt index 751314791a0..da0bc9b5b10 100644 --- a/searchcore/src/tests/proton/common/CMakeLists.txt +++ b/searchcore/src/tests/proton/common/CMakeLists.txt @@ -4,6 +4,7 @@ vespa_add_executable(searchcore_selectpruner_test_app TEST selectpruner_test.cpp DEPENDS searchcore_pcommon + searchlib_test ) vespa_add_test(NAME searchcore_selectpruner_test_app COMMAND searchcore_selectpruner_test_app) vespa_add_executable(searchcore_cachedselect_test_app TEST @@ -11,5 +12,6 @@ vespa_add_executable(searchcore_cachedselect_test_app TEST cachedselect_test.cpp DEPENDS searchcore_pcommon + searchlib_test ) vespa_add_test(NAME searchcore_cachedselect_test_app COMMAND searchcore_cachedselect_test_app) diff --git a/searchcore/src/tests/proton/document_iterator/CMakeLists.txt b/searchcore/src/tests/proton/document_iterator/CMakeLists.txt index 729bf09446f..27bd4cef68d 100644 --- a/searchcore/src/tests/proton/document_iterator/CMakeLists.txt +++ b/searchcore/src/tests/proton/document_iterator/CMakeLists.txt @@ -5,5 +5,6 @@ vespa_add_executable(searchcore_document_iterator_test_app TEST DEPENDS searchcore_persistenceengine searchcore_pcommon + searchlib_test ) vespa_add_test(NAME searchcore_document_iterator_test_app COMMAND searchcore_document_iterator_test_app) diff --git a/searchcore/src/tests/proton/documentdb/maintenancecontroller/CMakeLists.txt b/searchcore/src/tests/proton/documentdb/maintenancecontroller/CMakeLists.txt index 6769c964959..6b25971df83 100644 --- a/searchcore/src/tests/proton/documentdb/maintenancecontroller/CMakeLists.txt +++ b/searchcore/src/tests/proton/documentdb/maintenancecontroller/CMakeLists.txt @@ -16,6 +16,7 @@ vespa_add_executable(searchcore_maintenancecontroller_test_app TEST searchcore_proton_metrics searchcore_util searchcore_fconfig + searchlib_test ) vespa_add_test(NAME searchcore_maintenancecontroller_test_app COMMAND searchcore_maintenancecontroller_test_app) vespa_add_executable(searchcore_frozenbucketsmap_test_app TEST diff --git a/searchcore/src/tests/proton/matching/CMakeLists.txt b/searchcore/src/tests/proton/matching/CMakeLists.txt index 14f3960c43e..0fce2f6aca2 100644 --- a/searchcore/src/tests/proton/matching/CMakeLists.txt +++ b/searchcore/src/tests/proton/matching/CMakeLists.txt @@ -14,6 +14,7 @@ vespa_add_executable(searchcore_matching_test_app TEST searchcore_grouping searchcore_util searchlib_searchlib_uca + searchlib_test ) vespa_add_test(NAME searchcore_matching_test_app COMMAND searchcore_matching_test_app) vespa_add_executable(searchcore_sessionmanager_test_app TEST diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp index 8d75c8b8d24..de6a452baf3 100644 --- a/searchcore/src/tests/proton/matching/matching_test.cpp +++ b/searchcore/src/tests/proton/matching/matching_test.cpp @@ -24,6 +24,7 @@ #include <vespa/searchlib/engine/searchrequest.h> #include <vespa/searchlib/engine/docsumreply.h> #include <vespa/searchlib/engine/searchreply.h> +#include <vespa/searchlib/test/mock_attribute_context.h> #include <vespa/searchlib/fef/properties.h> #include <vespa/searchlib/query/tree/querybuilder.h> #include <vespa/searchlib/query/tree/stackdumpcreator.h> @@ -49,6 +50,7 @@ using namespace search::query; using namespace search::queryeval; using namespace search; +using search::attribute::test::MockAttributeContext; using search::index::schema::DataType; using storage::spi::Timestamp; @@ -93,52 +95,6 @@ vespalib::string make_same_element_stack_dump(const vespalib::string &a1_term, c const uint32_t NUM_DOCS = 1000; -//----------------------------------------------------------------------------- - -class MyAttributeContext : public IAttributeContext -{ -private: - typedef std::map<string, IAttributeVector *> Map; - Map _vectors; - -public: - const IAttributeVector *get(const string &name) const { - if (_vectors.find(name) == _vectors.end()) { - return 0; - } - return _vectors.find(name)->second; - } - const IAttributeVector * - getAttribute(const string &name) const override { - return get(name); - } - const IAttributeVector * - getAttributeStableEnum(const string &name) const override { - return get(name); - } - void - getAttributeList(std::vector<const IAttributeVector *> & list) const override { - Map::const_iterator pos = _vectors.begin(); - Map::const_iterator end = _vectors.end(); - for (; pos != end; ++pos) { - list.push_back(pos->second); - } - } - ~MyAttributeContext() override { - Map::iterator pos = _vectors.begin(); - Map::iterator end = _vectors.end(); - for (; pos != end; ++pos) { - delete pos->second; - } - } - - //------------------------------------------------------------------------- - - void add(IAttributeVector *attr) { - _vectors[attr->getName()] = attr; - } -}; - struct EmptyConstantValueRepo : public proton::matching::IConstantValueRepo { virtual vespalib::eval::ConstantValue::UP getConstant(const vespalib::string &) const override { return std::make_unique<proton::matching::ErrorConstantValue>(); @@ -151,7 +107,7 @@ struct MyWorld { Schema schema; Properties config; FakeSearchContext searchContext; - MyAttributeContext attributeContext; + MockAttributeContext attributeContext; SessionManager::SP sessionManager; DocumentMetaStore metaStore; MatchingStats matchingStats; @@ -327,14 +283,10 @@ 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; - DummyAttributeExecutor attrExec; - auto mtf = matcher->create_match_tools_factory(*req, searchContext, attributeContext, attrExec, metaStore, overrides); + auto mtf = matcher->create_match_tools_factory(*req, searchContext, attributeContext, metaStore, overrides); auto diversity = mtf->createDiversifier(); EXPECT_EQUAL(expectDiverse, static_cast<bool>(diversity)); } @@ -343,9 +295,8 @@ 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, attrExec, metaStore, overrides); + *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(); @@ -354,13 +305,12 @@ struct MyWorld { SearchReply::UP performSearch(SearchRequest::SP req, size_t threads) { Matcher::SP matcher = createMatcher(); SearchSession::OwnershipBundle owned_objects; - owned_objects.search_handler.reset(new MySearchHandler(matcher)); - owned_objects.context.reset(new MatchContext(std::make_unique<MyAttributeContext>(), - std::make_unique<FakeSearchContext>())); + owned_objects.search_handler = std::make_shared<MySearchHandler>(matcher); + owned_objects.context = std::make_unique<MatchContext>(std::make_unique<MockAttributeContext>(), + std::make_unique<FakeSearchContext>()); vespalib::SimpleThreadBundle threadBundle(threads); - DummyAttributeExecutor attrExec; SearchReply::UP reply = matcher->match(*req, threadBundle, searchContext, attributeContext, - attrExec, *sessionManager, metaStore, std::move(owned_objects)); + *sessionManager, metaStore, std::move(owned_objects)); matchingStats.add(matcher->getStats()); return reply; } @@ -392,14 +342,12 @@ struct MyWorld { FeatureSet::SP getSummaryFeatures(DocsumRequest::SP req) { Matcher::SP matcher = createMatcher(); - DummyAttributeExecutor attrExec; - return matcher->getSummaryFeatures(*req, searchContext, attributeContext, attrExec, *sessionManager); + return matcher->getSummaryFeatures(*req, searchContext, attributeContext, *sessionManager); } FeatureSet::SP getRankFeatures(DocsumRequest::SP req) { Matcher::SP matcher = createMatcher(); - DummyAttributeExecutor attrExec; - return matcher->getRankFeatures(*req, searchContext, attributeContext, attrExec, *sessionManager); + return matcher->getRankFeatures(*req, searchContext, attributeContext, *sessionManager); } }; diff --git a/searchcore/src/tests/proton/reference/document_db_reference/CMakeLists.txt b/searchcore/src/tests/proton/reference/document_db_reference/CMakeLists.txt index 00826843d9e..5dbe031d6aa 100644 --- a/searchcore/src/tests/proton/reference/document_db_reference/CMakeLists.txt +++ b/searchcore/src/tests/proton/reference/document_db_reference/CMakeLists.txt @@ -5,5 +5,6 @@ vespa_add_executable(searchcore_document_db_reference_test_app TEST DEPENDS searchcore_reference searchcore_attribute + searchlib_test ) vespa_add_test(NAME searchcore_document_db_reference_test_app COMMAND searchcore_document_db_reference_test_app) diff --git a/searchcore/src/tests/proton/reference/document_db_reference_resolver/CMakeLists.txt b/searchcore/src/tests/proton/reference/document_db_reference_resolver/CMakeLists.txt index 1db6f2118b3..46fe9ac0781 100644 --- a/searchcore/src/tests/proton/reference/document_db_reference_resolver/CMakeLists.txt +++ b/searchcore/src/tests/proton/reference/document_db_reference_resolver/CMakeLists.txt @@ -5,5 +5,6 @@ vespa_add_executable(searchcore_document_db_reference_resolver_test_app TEST DEPENDS searchcore_reference searchcore_attribute + searchlib_test ) vespa_add_test(NAME searchcore_document_db_reference_resolver_test_app COMMAND searchcore_document_db_reference_resolver_test_app) diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.cpp index e271f2f0bef..a1a8409e93b 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.cpp @@ -17,9 +17,10 @@ AttributeUsageSamplerFunctor::AttributeUsageSamplerFunctor( AttributeUsageSamplerFunctor::~AttributeUsageSamplerFunctor() = default; void -AttributeUsageSamplerFunctor::operator()(const search::AttributeVector & attributeVector) +AttributeUsageSamplerFunctor::operator()(const search::attribute::IAttributeVector & iAttributeVector) { // Executed by attribute writer thread + const auto & attributeVector = dynamic_cast<const search::AttributeVector &>(iAttributeVector); search::AddressSpaceUsage usage = attributeVector.getAddressSpaceUsage(); vespalib::string attributeName = attributeVector.getName(); _samplerContext->merge(usage, attributeName, _subDbName); diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.h b/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.h index 1b06e1dff45..12461af0d27 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_usage_sampler_functor.h @@ -2,7 +2,7 @@ #pragma once -#include <vespa/searchlib/attribute/i_attribute_functor.h> +#include <vespa/searchcommon/attribute/i_attribute_functor.h> #include <memory> namespace proton { @@ -21,7 +21,7 @@ public: AttributeUsageSamplerFunctor(std::shared_ptr<AttributeUsageSamplerContext> samplerContext, const std::string &subDbname); ~AttributeUsageSamplerFunctor() override; - void operator()(const search::AttributeVector &attributeVector) override; + void operator()(const search::attribute::IAttributeVector &attributeVector) override; }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp index f08300ba3c6..2ca4fd0a20d 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp @@ -11,7 +11,7 @@ #include <vespa/searchcore/proton/flushengine/shrink_lid_space_flush_target.h> #include <vespa/searchlib/attribute/attributecontext.h> #include <vespa/searchlib/attribute/attribute_read_guard.h> -#include <vespa/searchlib/attribute/i_attribute_functor.h> +#include <vespa/searchcommon/attribute/i_attribute_functor.h> #include <vespa/searchlib/attribute/interlock.h> #include <vespa/searchlib/common/isequencedtaskexecutor.h> #include <vespa/searchlib/common/threaded_compactable_lid_space.h> @@ -423,6 +423,7 @@ namespace { class CombinedAttributeContext : public IAttributeContext { private: + using IAttributeFunctor = search::attribute::IAttributeFunctor; AttributeContext _ctx; ImportedAttributesContext _importedCtx; @@ -433,28 +434,31 @@ public: _importedCtx(importedAttributes) { } - virtual const IAttributeVector *getAttribute(const vespalib::string &name) const override { + const IAttributeVector *getAttribute(const vespalib::string &name) const override { const IAttributeVector *result = _ctx.getAttribute(name); if (result == nullptr) { result = _importedCtx.getAttribute(name); } return result; } - virtual const IAttributeVector *getAttributeStableEnum(const vespalib::string &name) const override { + const IAttributeVector *getAttributeStableEnum(const vespalib::string &name) const override { const IAttributeVector *result = _ctx.getAttributeStableEnum(name); if (result == nullptr) { result = _importedCtx.getAttributeStableEnum(name); } return result; } - virtual void getAttributeList(std::vector<const IAttributeVector *> &list) const override { + void getAttributeList(std::vector<const IAttributeVector *> &list) const override { _ctx.getAttributeList(list); _importedCtx.getAttributeList(list); } - virtual void releaseEnumGuards() override { + void releaseEnumGuards() override { _ctx.releaseEnumGuards(); _importedCtx.releaseEnumGuards(); } + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override { + _ctx.asyncForAttribute(name, std::move(func)); + } }; } @@ -462,8 +466,8 @@ public: IAttributeContext::UP AttributeManager::createContext() const { - if (_importedAttributes.get() != nullptr) { - return std::make_unique<CombinedAttributeContext>(*this, *_importedAttributes.get()); + if (_importedAttributes) { + return std::make_unique<CombinedAttributeContext>(*this, *_importedAttributes); } return std::make_unique<AttributeContext>(*this); } diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h index 1ddba45ac46..78760d466e8 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h @@ -36,6 +36,7 @@ private: using ShrinkerSP = std::shared_ptr<ShrinkLidSpaceFlushTarget>; using IFlushTargetSP = std::shared_ptr<searchcorespi::IFlushTarget>; using AttributeVectorSP = std::shared_ptr<search::AttributeVector>; + using AttributeReadGuard = search::attribute::AttributeReadGuard; class AttributeWrap { @@ -80,9 +81,7 @@ private: HwInfo _hwInfo; std::unique_ptr<ImportedAttributesRepo> _importedAttributes; - AttributeVectorSP internalAddAttribute(const AttributeSpec &spec, - uint64_t serialNum, - const IAttributeFactory &factory); + AttributeVectorSP internalAddAttribute(const AttributeSpec &spec, uint64_t serialNum, const IAttributeFactory &factory); void addAttribute(const AttributeWrap &attribute, const ShrinkerSP &shrinker); @@ -90,12 +89,9 @@ private: const FlushableWrap *findFlushable(const vespalib::string &name) const; - void transferExistingAttributes(const AttributeManager &currMgr, - const Spec &newSpec, - Spec::AttributeList &toBeAdded); + void transferExistingAttributes(const AttributeManager &currMgr, const Spec &newSpec, Spec::AttributeList &toBeAdded); - void addNewAttributes(const Spec &newSpec, - const Spec::AttributeList &toBeAdded, + void addNewAttributes(const Spec &newSpec, const Spec::AttributeList &toBeAdded, IAttributeInitializerRegistry &initializerRegistry); void transferExtraAttributes(const AttributeManager &currMgr); @@ -118,8 +114,7 @@ public: const IAttributeFactory::SP &factory, const HwInfo &hwInfo); - AttributeManager(const AttributeManager &currMgr, - const Spec &newSpec, + AttributeManager(const AttributeManager &currMgr, const Spec &newSpec, IAttributeInitializerRegistry &initializerRegistry); ~AttributeManager() override; @@ -141,7 +136,7 @@ public: // Implements search::IAttributeManager search::AttributeGuard::UP getAttribute(const vespalib::string &name) const override; - std::unique_ptr<search::attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override; + std::unique_ptr<AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override; /** * Fills all regular registered attributes (not extra attributes) 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 e8878b29678..7928bc5cc27 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp @@ -4,7 +4,7 @@ #include <vespa/searchlib/common/isequencedtaskexecutor.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/searchlib/attribute/attributevector.h> -#include <vespa/searchlib/attribute/i_attribute_functor.h> +#include <vespa/searchcommon/attribute/i_attribute_functor.h> #include <vespa/searchlib/attribute/attribute_read_guard.h> using search::AttributeGuard; 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 6df9b207281..5df8cf0d0bf 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h @@ -5,7 +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/searchcommon/attribute/i_attribute_functor.h> #include <vespa/searchcorespi/flush/iflushtarget.h> #include <vespa/searchlib/attribute/iattributemanager.h> #include <vespa/searchlib/common/serialnum.h> @@ -26,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, public search::attribute::IAttributeExecutor +struct IAttributeManager : public search::IAttributeManager { using SP = std::shared_ptr<IAttributeManager>; using OnWriteDoneType = const std::shared_ptr<search::IDestructorCallback> &; diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp index 8e4714d6fa2..92b4d70893d 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp @@ -14,17 +14,15 @@ using LockGuard = std::lock_guard<std::mutex>; namespace proton { const IAttributeVector * -ImportedAttributesContext::getOrCacheAttribute(const vespalib::string &name, - AttributeCache &attributes, - bool stableEnumGuard, - const LockGuard &) const +ImportedAttributesContext::getOrCacheAttribute(const vespalib::string &name, AttributeCache &attributes, + bool stableEnumGuard, const LockGuard &) const { auto itr = attributes.find(name); if (itr != attributes.end()) { return itr->second->attribute(); } ImportedAttributeVector::SP result = _repo.get(name); - if (result.get() != nullptr) { + if (result) { auto insRes = attributes.emplace(name, result->makeReadGuard(stableEnumGuard)); return insRes.first->second->attribute(); } else { @@ -40,9 +38,7 @@ ImportedAttributesContext::ImportedAttributesContext(const ImportedAttributesRep { } -ImportedAttributesContext::~ImportedAttributesContext() -{ -} +ImportedAttributesContext::~ImportedAttributesContext() = default; const IAttributeVector * ImportedAttributesContext::getAttribute(const vespalib::string &name) const @@ -74,5 +70,10 @@ ImportedAttributesContext::releaseEnumGuards() LockGuard guard(_cacheMutex); _enumGuardedAttributes.clear(); } - + +void +ImportedAttributesContext::asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor> ) const { + throw std::runtime_error("proton::ImportedAttributesContext::asyncForAttribute should never be called."); +} + } diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h index 90f95ce6447..0c81a5c4688 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h @@ -7,13 +7,12 @@ #include <mutex> #include <unordered_map> -namespace search { -class AttributeGuard; -namespace attribute { -class AttributeReadGuard; -class IAttributeVector; -class ImportedAttributeVector; -}} +namespace search { class AttributeGuard; } +namespace search::attribute { + class AttributeReadGuard; + class IAttributeVector; + class ImportedAttributeVector; +} namespace proton { @@ -30,6 +29,7 @@ private: using AttributeReadGuard = search::attribute::AttributeReadGuard; using IAttributeVector = search::attribute::IAttributeVector; using ImportedAttributeVector = search::attribute::ImportedAttributeVector; + using IAttributeFunctor = search::attribute::IAttributeFunctor; using AttributeCache = std::unordered_map<vespalib::string, std::unique_ptr<AttributeReadGuard>, vespalib::hash<vespalib::string>>; using LockGuard = std::lock_guard<std::mutex>; @@ -39,20 +39,20 @@ private: mutable AttributeCache _enumGuardedAttributes; mutable std::mutex _cacheMutex; - const IAttributeVector *getOrCacheAttribute(const vespalib::string &name, - AttributeCache &attributes, - bool stableEnumGuard, - const LockGuard &) const; + const IAttributeVector *getOrCacheAttribute(const vespalib::string &name, AttributeCache &attributes, + bool stableEnumGuard, const LockGuard &) const; public: ImportedAttributesContext(const ImportedAttributesRepo &repo); - ~ImportedAttributesContext(); + ~ImportedAttributesContext() override; // Implements search::attribute::IAttributeContext - virtual const IAttributeVector *getAttribute(const vespalib::string &name) const override; - virtual const IAttributeVector *getAttributeStableEnum(const vespalib::string &name) const override; - virtual void getAttributeList(std::vector<const IAttributeVector *> &list) const override; - virtual void releaseEnumGuards() override; + const IAttributeVector *getAttribute(const vespalib::string &name) const override; + const IAttributeVector *getAttributeStableEnum(const vespalib::string &name) const override; + void getAttributeList(std::vector<const IAttributeVector *> &list) const override; + void releaseEnumGuards() override; + + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override; }; } diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp index 908c7e887a3..a9d599c316d 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp +++ b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp @@ -137,8 +137,7 @@ DocsumContext::createSlimeReply() DocsumContext::DocsumContext(const DocsumRequest & request, IDocsumWriter & docsumWriter, IDocsumStore & docsumStore, const Matcher::SP & matcher, ISearchContext & searchCtx, IAttributeContext & attrCtx, - IAttributeManager & attrMgr, const IAttributeExecutor & attrExec, - SessionManager & sessionMgr) : + IAttributeManager & attrMgr, SessionManager & sessionMgr) : _request(request), _docsumWriter(docsumWriter), _docsumStore(docsumStore), @@ -146,7 +145,6 @@ DocsumContext::DocsumContext(const DocsumRequest & request, IDocsumWriter & docs _searchCtx(searchCtx), _attrCtx(attrCtx), _attrMgr(attrMgr), - _attrExec(attrExec), _docsumState(*this), _sessionMgr(sessionMgr) { @@ -167,7 +165,7 @@ DocsumContext::FillSummaryFeatures(search::docsummary::GetDocsumsState * state, { assert(&_docsumState == state); if (_matcher->canProduceSummaryFeatures()) { - state->_summaryFeatures = _matcher->getSummaryFeatures(_request, _searchCtx, _attrCtx, _attrExec, _sessionMgr); + state->_summaryFeatures = _matcher->getSummaryFeatures(_request, _searchCtx, _attrCtx, _sessionMgr); } state->_summaryFeaturesCached = false; } @@ -180,7 +178,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, _attrExec, _sessionMgr); + state->_rankFeatures = _matcher->getRankFeatures(_request, _searchCtx, _attrCtx, _sessionMgr); } namespace { diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h index 4be67628b1f..45f3ca8e44f 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h +++ b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h @@ -23,7 +23,6 @@ private: matching::ISearchContext & _searchCtx; search::attribute::IAttributeContext & _attrCtx; search::IAttributeManager & _attrMgr; - const search::attribute::IAttributeExecutor & _attrExec; search::docsummary::GetDocsumsState _docsumState; matching::SessionManager & _sessionMgr; @@ -41,7 +40,6 @@ public: matching::ISearchContext & searchCtx, search::attribute::IAttributeContext & attrCtx, search::IAttributeManager & attrMgr, - const search::attribute::IAttributeExecutor & attrExec, matching::SessionManager & sessionMgr); search::engine::DocsumReply::UP getDocsums(); diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp index a88a44130f2..63c3be1aa14 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp @@ -139,9 +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)); + auto onSummaryTask = mtf.createOnSummaryTask(); + if (onSummaryTask) { + onSummaryTask->run(AttributeOperation::create(onSummaryTask->getAttributeType(), + onSummaryTask->getOperation(), 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 2591a176e19..da4e5972cd5 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp @@ -3,7 +3,7 @@ #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/searchcommon/attribute/i_attribute_functor.h> #include <vespa/searchcore/grouping/groupingmanager.h> #include <vespa/searchcore/grouping/groupingcontext.h> #include <vespa/searchlib/common/bitvector.h> @@ -280,9 +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())); + auto onReRankTask = mtf.createOnReRankTask(); + if (onReRankTask) { + onReRankTask->run(AttributeOperation::create(onReRankTask->getAttributeType(), + onReRankTask->getOperation(), hits.getReRankedHits())); } thread_stats.docsReRanked(reRanked); } @@ -351,8 +352,9 @@ MatchThread::processResult(const Doom & hardDoom, } } const MatchToolsFactory & mtf = matchToolsFactory; - if (mtf.hasOnMatchOperation() ) { - mtf.runOnMatchOperation(AttributeOperation::create(mtf.getOnMatchAttributeType(), mtf.getOnMatchOperation(), + auto onMatchTask = mtf.createOnMatchTask(); + if (onMatchTask ) { + onMatchTask->run(AttributeOperation::create(onMatchTask->getAttributeType(), onMatchTask->getOperation(), search::ResultSet::stealResult(std::move(*result)))); } if (hasGrouping) { diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp index 8b289bd10eb..f2147029458 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp @@ -12,6 +12,7 @@ using search::attribute::IAttributeContext; using search::queryeval::IRequestContext; using search::queryeval::IDiversifier; using search::attribute::diversity::DiversityFilter; +using search::attribute::BasicType; using namespace search::fef; using namespace search::fef::indexproperties::matchphase; @@ -151,7 +152,6 @@ 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, @@ -164,7 +164,6 @@ MatchToolsFactory(QueryLimiter & queryLimiter, _match_limiter(), _queryEnv(indexEnv, attributeContext, rankProperties), _mdl(), - _attrExec(attrExec), _rankSetup(rankSetup), _featureOverrides(featureOverrides), _diversityParams(), @@ -218,70 +217,45 @@ 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(); +std::unique_ptr<AttributeOperationTask> +MatchToolsFactory::createTask(vespalib::stringref attribute, vespalib::stringref operation) const { + return (!attribute.empty() && ! operation.empty()) + ? std::make_unique<AttributeOperationTask>(_requestContext, attribute, operation) + : std::unique_ptr<AttributeOperationTask>(); } - -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; +std::unique_ptr<AttributeOperationTask> +MatchToolsFactory::createOnMatchTask() const { + return createTask(execute::onmatch::Attribute::lookup(_queryEnv.getProperties()), + execute::onmatch::Operation::lookup(_queryEnv.getProperties())); } - -bool -MatchToolsFactory::hasOnReRankOperation() const { - return ! execute::onrerank::Attribute::lookup(_queryEnv.getProperties()).empty() && - ! execute::onrerank::Operation::lookup(_queryEnv.getProperties()).empty(); +std::unique_ptr<AttributeOperationTask> +MatchToolsFactory::createOnReRankTask() const { + return createTask(execute::onrerank::Attribute::lookup(_queryEnv.getProperties()), + execute::onrerank::Operation::lookup(_queryEnv.getProperties())); } - -vespalib::string -MatchToolsFactory::getOnReRankOperation() const { - return execute::onrerank::Operation::lookup(_queryEnv.getProperties()); +std::unique_ptr<AttributeOperationTask> +MatchToolsFactory::createOnSummaryTask() const { + return createTask(execute::onsummary::Attribute::lookup(_queryEnv.getProperties()), + execute::onsummary::Operation::lookup(_queryEnv.getProperties())); } -void -MatchToolsFactory::runOnReRankOperation(std::shared_ptr<IAttributeFunctor> count) const { - _attrExec.asyncForAttribute(execute::onrerank::Attribute::lookup(_queryEnv.getProperties()), std::move(count)); +AttributeOperationTask::AttributeOperationTask(const RequestContext & requestContext, + vespalib::stringref attribute, vespalib::stringref operation) + : _requestContext(requestContext), + _attribute(attribute), + _operation(operation) +{ } search::attribute::BasicType -MatchToolsFactory::getOnReRankAttributeType() const { - auto attr = _requestContext.getAttribute(execute::onrerank::Attribute::lookup(_queryEnv.getProperties())); +AttributeOperationTask::getAttributeType() const { + auto attr = _requestContext.getAttribute(_attribute); 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; +AttributeOperationTask::run(std::shared_ptr<IAttributeFunctor> func) const { + _requestContext.asyncForAttribute(_attribute, std::move(func)); } } diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h index 9a28dc1ed05..af3665c4d72 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h +++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h @@ -10,7 +10,7 @@ #include "match_phase_limiter.h" #include "handlerecorder.h" #include "requestcontext.h" -#include <vespa/searchlib/attribute/i_attribute_functor.h> +#include <vespa/searchcommon/attribute/i_attribute_functor.h> #include <vespa/searchlib/queryeval/blueprint.h> #include <vespa/searchlib/fef/fef.h> #include <vespa/searchlib/common/idocumentmetastore.h> @@ -69,10 +69,23 @@ public: void setup_dump(); }; +class AttributeOperationTask { +public: + using IAttributeFunctor = search::attribute::IAttributeFunctor; + AttributeOperationTask(const RequestContext & requestContext, + vespalib::stringref attribute, vespalib::stringref operation); + void run(std::shared_ptr<IAttributeFunctor> func) const; + search::attribute::BasicType getAttributeType() const; + const vespalib::string & getOperation() const { return _operation; } +private: + const RequestContext & _requestContext; + vespalib::string _attribute; + vespalib::string _operation; +}; + class MatchToolsFactory : public vespalib::noncopyable { private: - using IAttributeExecutor = search::attribute::IAttributeExecutor; using IAttributeFunctor = search::attribute::IAttributeFunctor; QueryLimiter & _queryLimiter; RequestContext _requestContext; @@ -81,11 +94,13 @@ 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; + + std::unique_ptr<AttributeOperationTask> + createTask(vespalib::stringref attribute, vespalib::stringref operation) const; public: using UP = std::unique_ptr<MatchToolsFactory>; using BasicType = search::attribute::BasicType; @@ -98,7 +113,6 @@ 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, @@ -112,18 +126,10 @@ 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; + std::unique_ptr<AttributeOperationTask> createOnMatchTask() const; + std::unique_ptr<AttributeOperationTask> createOnReRankTask() const; + std::unique_ptr<AttributeOperationTask> createOnSummaryTask() 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 c387d3ea4eb..be0a720f1c1 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, - const IAttributeExecutor & attrExec, SessionManager & sessionMgr, bool summaryFeatures) + 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, attrExec, metaStore, + MatchToolsFactory::UP mtf = create_match_tools_factory(req, searchCtx, attrCtx, 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 IAttributeExecutor & attrExec, - const search::IDocumentMetaStore &metaStore, const Properties &feature_overrides) const + IAttributeContext &attrContext, const search::IDocumentMetaStore &metaStore, + const Properties &feature_overrides) const { const Properties & rankProperties = request.propertiesMap.rankProperties(); bool softTimeoutEnabled = Enabled::lookup(rankProperties, _rankSetup->getSoftTimeoutEnabled()); @@ -176,8 +176,7 @@ 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, - attrExec, metaStore, _indexEnv, *_rankSetup, - rankProperties, feature_overrides); + metaStore, _indexEnv, *_rankSetup, rankProperties, feature_overrides); } SearchReply::UP @@ -205,8 +204,7 @@ Matcher::computeNumThreadsPerSearch(Blueprint::HitEstimate hits, const Propertie SearchReply::UP Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundle, - ISearchContext &searchContext, IAttributeContext &attrContext, - const IAttributeExecutor & attrExec, SessionManager &sessionMgr, + ISearchContext &searchContext, IAttributeContext &attrContext, SessionManager &sessionMgr, const search::IDocumentMetaStore &metaStore, SearchSession::OwnershipBundle &&owned_objects) { fastos::StopWatch total_matching_time; @@ -237,7 +235,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, - attrExec, metaStore, *feature_overrides); + metaStore, *feature_overrides); if (!mtf->valid()) { reply->errorCode = ECODE_QUERY_PARSE_ERROR; reply->errorMessage = "query execution failed (invalid query)"; @@ -326,17 +324,17 @@ Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundl } FeatureSet::SP -Matcher::getSummaryFeatures(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx, - const IAttributeExecutor & attrExec, SessionManager &sessionMgr) +Matcher::getSummaryFeatures(const DocsumRequest & req, ISearchContext & searchCtx, + IAttributeContext & attrCtx, SessionManager &sessionMgr) { - return getFeatureSet(req, searchCtx, attrCtx, attrExec, sessionMgr, true); + return getFeatureSet(req, searchCtx, attrCtx, sessionMgr, true); } FeatureSet::SP -Matcher::getRankFeatures(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx, - const IAttributeExecutor & attrExec, SessionManager &sessionMgr) +Matcher::getRankFeatures(const DocsumRequest & req, ISearchContext & searchCtx, + IAttributeContext & attrCtx, SessionManager &sessionMgr) { - return getFeatureSet(req, searchCtx, attrCtx, attrExec, sessionMgr, false); + return getFeatureSet(req, searchCtx, attrCtx, sessionMgr, false); } } diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.h b/searchcore/src/vespa/searchcore/proton/matching/matcher.h index 15df21378d2..0fed257f0c0 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/matcher.h +++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.h @@ -8,7 +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/searchcommon/attribute/i_attribute_functor.h> #include <vespa/searchlib/common/featureset.h> #include <vespa/searchlib/common/resultset.h> #include <vespa/searchlib/queryeval/blueprint.h> @@ -45,7 +45,9 @@ class MatchToolsFactory; class Matcher { private: - using IAttributeExecutor = search::attribute::IAttributeExecutor; + using IAttributeContext = search::attribute::IAttributeContext; + using DocsumRequest = search::engine::DocsumRequest; + using Properties = search::fef::Properties; IndexEnvironment _indexEnv; search::fef::BlueprintFactory _blueprintFactory; search::fef::RankSetup::SP _rankSetup; @@ -57,16 +59,15 @@ private: uint32_t _distributionKey; search::FeatureSet::SP - getFeatureSet(const search::engine::DocsumRequest & req, ISearchContext & searchCtx, - search::attribute::IAttributeContext & attrCtx, - const IAttributeExecutor & attrExec, SessionManager &sessionMgr, bool summaryFeatures); + getFeatureSet(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx, + SessionManager &sessionMgr, bool summaryFeatures); std::unique_ptr<search::engine::SearchReply> handleGroupingSession(SessionManager &sessionMgr, search::grouping::GroupingContext & groupingContext, std::unique_ptr<search::grouping::GroupingSession> gs); size_t computeNumThreadsPerSearch(search::queryeval::Blueprint::HitEstimate hits, - const search::fef::Properties & rankProperties) const; + const Properties & rankProperties) const; public: /** * Convenience typedefs. @@ -85,7 +86,7 @@ public: * @param props ranking configuration * @param clock used for timeout handling **/ - Matcher(const search::index::Schema &schema, const search::fef::Properties &props, + Matcher(const search::index::Schema &schema, const Properties &props, const vespalib::Clock &clock, QueryLimiter &queryLimiter, const IConstantValueRepo &constantValueRepo, uint32_t distributionKey); @@ -104,10 +105,8 @@ 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; + IAttributeContext &attrContext, const search::IDocumentMetaStore &metaStore, + const Properties &feature_overrides) const; /** * Perform a search against this matcher. @@ -122,8 +121,8 @@ public: **/ std::unique_ptr<search::engine::SearchReply> match(const search::engine::SearchRequest &request, vespalib::ThreadBundle &threadBundle, - ISearchContext &searchContext, search::attribute::IAttributeContext &attrContext, - const IAttributeExecutor & attrExec, SessionManager &sessionManager, const search::IDocumentMetaStore &metaStore, + ISearchContext &searchContext, IAttributeContext &attrContext, + SessionManager &sessionManager, const search::IDocumentMetaStore &metaStore, SearchSession::OwnershipBundle &&owned_objects); /** @@ -137,9 +136,8 @@ public: * @return calculated summary features. **/ search::FeatureSet::SP - getSummaryFeatures(const search::engine::DocsumRequest & req, ISearchContext & searchCtx, - search::attribute::IAttributeContext & attrCtx, - const IAttributeExecutor & attrExec, SessionManager &sessionManager); + getSummaryFeatures(const DocsumRequest & req, ISearchContext & searchCtx, + IAttributeContext & attrCtx, SessionManager &sessionManager); /** * Perform matching for the documents in the given docsum request @@ -152,9 +150,8 @@ public: * @return calculated rank features. **/ search::FeatureSet::SP - getRankFeatures(const search::engine::DocsumRequest & req, ISearchContext & searchCtx, - search::attribute::IAttributeContext & attrCtx, - const IAttributeExecutor & attrExec, SessionManager &sessionManager); + getRankFeatures(const DocsumRequest & req, ISearchContext & searchCtx, + IAttributeContext & attrCtx, SessionManager &sessionManager); /** * @return true if this rankprofile has summary-features enabled diff --git a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp index 8cf8a2a7807..c275337cc7e 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp @@ -23,4 +23,8 @@ RequestContext::getAttributeStableEnum(const vespalib::string &name) const return _attributeContext.getAttributeStableEnum(name); } +void RequestContext::asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const { + _attributeContext.asyncForAttribute(name, std::move(func)); +} + } diff --git a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h index 60e9c638c33..91e1e906e87 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h +++ b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h @@ -7,14 +7,19 @@ namespace proton { -class RequestContext : public search::queryeval::IRequestContext +class RequestContext : public search::queryeval::IRequestContext, + public search::attribute::IAttributeExecutor { public: using IAttributeContext = search::attribute::IAttributeContext; + using IAttributeFunctor = search::attribute::IAttributeFunctor; using Doom = vespalib::Doom; RequestContext(const Doom & softDoom, IAttributeContext & attributeContext); const Doom & getSoftDoom() const override { return _softDoom; } const search::attribute::IAttributeVector *getAttribute(const vespalib::string &name) const override; + + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override; + const search::attribute::IAttributeVector *getAttributeStableEnum(const vespalib::string &name) const override; private: const Doom _softDoom; diff --git a/searchcore/src/vespa/searchcore/proton/server/matchview.cpp b/searchcore/src/vespa/searchcore/proton/server/matchview.cpp index ab9a4b93b5f..9af648917c4 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(), - *_attrMgr, *_sessionMgr, dms, std::move(owned_objects)); + *_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 6879e106c5e..c5572923784 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchview.cpp @@ -149,8 +149,7 @@ SearchView::getDocsumsInternal(const DocsumRequest & req) MatchContext::UP mctx = _matchView->createContext(); auto ctx = std::make_unique<DocsumContext>(req, _summarySetup->getDocsumWriter(), *store, matcher, mctx->getSearchContext(), mctx->getAttributeContext(), - *_summarySetup->getAttributeManager(), *_matchView->getAttributeManager(), - *getSessionManager()); + *_summarySetup->getAttributeManager(), *getSessionManager()); SearchView::InternalDocsumReply reply(ctx->getDocsums(), true); uint64_t endGeneration = readGuard->get().getCurrentGeneration(); if (startGeneration != endGeneration) { diff --git a/searchlib/src/tests/attribute/searchable/CMakeLists.txt b/searchlib/src/tests/attribute/searchable/CMakeLists.txt index 5fd278be676..56a6921f2f3 100644 --- a/searchlib/src/tests/attribute/searchable/CMakeLists.txt +++ b/searchlib/src/tests/attribute/searchable/CMakeLists.txt @@ -11,6 +11,7 @@ vespa_add_executable(searchlib_attribute_weighted_set_blueprint_test_app TEST attribute_weighted_set_blueprint_test.cpp DEPENDS searchlib + searchlib_test ) vespa_add_test(NAME searchlib_attribute_weighted_set_blueprint_test_app COMMAND searchlib_attribute_weighted_set_blueprint_test_app) vespa_add_executable(searchlib_attribute_blueprint_test_app TEST diff --git a/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp b/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp index c7dde172b9d..f5f00993f7d 100644 --- a/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp @@ -87,7 +87,7 @@ public: explicit MyAttributeManager(AttributeVector *attr); explicit MyAttributeManager(AttributeVector::SP attr); - ~MyAttributeManager(); + ~MyAttributeManager() override; void set_other(AttributeVector::SP attr) { _other = attr; @@ -95,15 +95,16 @@ public: AttributeGuard::UP getAttribute(const string &name) const override { if (name == field) { - return AttributeGuard::UP(new AttributeGuard(_attribute_vector)); + return std::make_unique<AttributeGuard>(_attribute_vector); } else if (name == other) { - return AttributeGuard::UP(new AttributeGuard(_other)); + return std::make_unique<AttributeGuard>(_other); } else { return AttributeGuard::UP(nullptr); } } - std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override { + std::unique_ptr<attribute::AttributeReadGuard> + getAttributeReadGuard(const string &name, bool stableEnumGuard) const override { if (name == field && _attribute_vector) { return _attribute_vector->makeReadGuard(stableEnumGuard); } else if (name == other && _other) { @@ -120,6 +121,8 @@ public: assert(!"Not implemented"); return IAttributeContext::UP(); } + + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override; }; struct Result { @@ -156,7 +159,7 @@ Result::Result(size_t est_hits_in, bool est_empty_in) wand_initial_threshold(0), wand_boost_factor(0.0), hits(), iterator_dump() {} -Result::~Result() {} +Result::~Result() = default; MyAttributeManager::MyAttributeManager(MyAttributeManager && rhs) @@ -174,9 +177,14 @@ MyAttributeManager::MyAttributeManager(AttributeVector::SP attr) _other() {} -MyAttributeManager::~MyAttributeManager() {} +MyAttributeManager::~MyAttributeManager() = default; + +void +MyAttributeManager::asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const { + +} -void extract_posting_info(Result &result, const PostingInfo *postingInfo) { + void extract_posting_info(Result &result, const PostingInfo *postingInfo) { if (postingInfo != NULL) { const MinMaxPostingInfo *minMax = dynamic_cast<const MinMaxPostingInfo *>(postingInfo); if (minMax != NULL) { diff --git a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp index be64edf89f2..f6a9df54be3 100644 --- a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp @@ -13,6 +13,7 @@ #include <vespa/searchlib/queryeval/fake_result.h> #include <vespa/searchlib/queryeval/weighted_set_term_search.h> #include <vespa/searchlib/queryeval/fake_requestcontext.h> +#include <vespa/searchlib/test/mock_attribute_manager.h> #include <vespa/searchlib/attribute/enumstore.hpp> #include <vespa/log/log.h> @@ -23,93 +24,43 @@ using namespace search::query; using namespace search::fef; using namespace search::queryeval; using namespace search::attribute; +using namespace search::attribute::test; namespace { -class FakeAttributeManager : public IAttributeManager -{ -private: - typedef std::map<std::string, AttributeVector::SP> Map; - Map _map; - - AttributeVector::SP lookup(const std::string &name) const { - Map::const_iterator pos = _map.find(name); - if (pos == _map.end()) { - return AttributeVector::SP(); - } - return pos->second; - } - -public: - FakeAttributeManager() : _map() {} - - void addAttribute(AttributeVector::SP attr) { - _map[attr->getName()] = attr; - } - - virtual AttributeGuard::UP getAttribute(const vespalib::string &name) const override { - return AttributeGuard::UP(new AttributeGuard(lookup(name))); - } - - virtual std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override { - auto vector = lookup(name); - if (vector) { - return vector->makeReadGuard(stableEnumGuard); - } else { - return std::unique_ptr<attribute::AttributeReadGuard>(); - } - } - - virtual void getAttributeList(std::vector<AttributeGuard> &list) const override { - Map::const_iterator pos = _map.begin(); - for (; pos != _map.end(); ++pos) { - list.push_back(pos->second); - } - } - - virtual IAttributeContext::UP createContext() const override { - return IAttributeContext::UP(new AttributeContext(*this)); - } -}; - void -setupAttributeManager(FakeAttributeManager &manager) +setupAttributeManager(MockAttributeManager &manager) { AttributeVector::DocId docId; { - AttributeVector::SP attr_sp = AttributeFactory::createAttribute( - "integer", Config(BasicType("int64"))); + AttributeVector::SP attr_sp = AttributeFactory::createAttribute("integer", Config(BasicType("int64"))); + manager.addAttribute(attr_sp); + IntegerAttribute *attr = (IntegerAttribute*)(attr_sp.get()); - attr->addDoc(docId); - assert(0u == docId); for (size_t i = 1; i < 10; ++i) { attr->addDoc(docId); assert(i == docId); attr->update(docId, i); attr->commit(); } - manager.addAttribute(attr_sp); } { - AttributeVector::SP attr_sp = AttributeFactory::createAttribute( - "string", Config(BasicType("string"))); + AttributeVector::SP attr_sp = AttributeFactory::createAttribute("string", Config(BasicType("string"))); + manager.addAttribute(attr_sp); + StringAttribute *attr = (StringAttribute*)(attr_sp.get()); - attr->addDoc(docId); - assert(0u == docId); for (size_t i = 1; i < 10; ++i) { attr->addDoc(docId); assert(i == docId); attr->update(i, std::string(1, '1' + i - 1).c_str()); attr->commit(); } - manager.addAttribute(attr_sp); } { AttributeVector::SP attr_sp = AttributeFactory::createAttribute( "multi", Config(BasicType("int64"), search::attribute::CollectionType("array"))); + manager.addAttribute(attr_sp); IntegerAttribute *attr = (IntegerAttribute*)(attr_sp.get()); - attr->addDoc(docId); - assert(0u == docId); for (size_t i = 1; i < 10; ++i) { attr->addDoc(docId); assert(i == docId); @@ -117,7 +68,6 @@ setupAttributeManager(FakeAttributeManager &manager) attr->append(docId, i + 10, 1); attr->commit(); } - manager.addAttribute(attr_sp); } } @@ -199,7 +149,7 @@ Test::Main() { TEST_INIT("attribute_weighted_set_test"); { - FakeAttributeManager manager; + MockAttributeManager manager; setupAttributeManager(manager); AttributeBlueprintFactory adapter; diff --git a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp index dc7cf53d188..7161442df8b 100644 --- a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp @@ -48,13 +48,11 @@ const int32_t weight = 1; class MyAttributeManager : public IAttributeManager { AttributeVector::SP _attribute_vector; - AttributeVector::DocId _docid; public: MyAttributeManager(MyAttributeManager && rhs) : IAttributeManager(), - _attribute_vector(std::move(rhs._attribute_vector)), - _docid(std::move(rhs._docid)) + _attribute_vector(std::move(rhs._attribute_vector)) { } MyAttributeManager(AttributeVector *attr) @@ -64,7 +62,8 @@ public: return AttributeGuard::UP(new AttributeGuard(_attribute_vector)); } - virtual std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &, bool stableEnumGuard) const override { + std::unique_ptr<attribute::AttributeReadGuard> + getAttributeReadGuard(const string &, bool stableEnumGuard) const override { if (_attribute_vector) { return _attribute_vector->makeReadGuard(stableEnumGuard); } else { @@ -78,6 +77,10 @@ public: assert(!"Not implemented"); return IAttributeContext::UP(); } + + void asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override { + assert(!"Not implemented"); + } }; constexpr uint32_t DOCID_LIMIT = 3; diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp index 2274eaf1b41..5580fc25aef 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp @@ -84,12 +84,12 @@ struct Set { template <typename T, typename OP> struct UpdateFast { - using A = search::SingleValueNumericAttribute<T>; + using A = SingleValueNumericAttribute<T>; using F = OP; A * attr; F op; typedef typename T::LoadedValueType ValueType; - UpdateFast(search::attribute::IAttributeVector &attr_in, typename F::V operand) + UpdateFast(IAttributeVector &attr_in, typename F::V operand) : attr(dynamic_cast<A *>(&attr_in)), op(operand) {} @@ -105,12 +105,12 @@ public: _result(std::move(result)) {} - void operator()(const search::AttributeVector &attributeVector) override { - OP op(const_cast<search::AttributeVector &>(attributeVector), _operand); + void operator()(const IAttributeVector &attributeVector) override { + OP op(const_cast<IAttributeVector &>(attributeVector), _operand); if (op.valid()) { - const search::RankedHit *hits = &_result.second[0]; + const RankedHit *hits = &_result.second[0]; size_t numHits = _result.second.size(); - std::for_each(hits, hits+numHits, [&op](search::RankedHit hit) { op(hit.getDocId()); }); + std::for_each(hits, hits+numHits, [&op](RankedHit hit) { op(hit.getDocId()); }); if (_result.first) { _result.first->foreach_truebit([&op](uint32_t docId) { op(docId); }); } @@ -130,11 +130,10 @@ public: _reRanked(std::move(reRanked)) {} - void operator()(const search::AttributeVector &attributeVector) override { - OP op(const_cast<search::AttributeVector &>(attributeVector), _operand); + void operator()(const IAttributeVector &attributeVector) override { + OP op(const_cast<IAttributeVector &>(attributeVector), _operand); if (op.valid()) { - std::for_each(_reRanked.begin(), _reRanked.end(), - [&op](Hit hit) { op(hit.first); }); + std::for_each(_reRanked.begin(), _reRanked.end(), [&op](Hit hit) { op(hit.first); }); } } private: @@ -150,11 +149,10 @@ public: _docIds(std::move(docIds)) {} - void operator()(const search::AttributeVector &attributeVector) override { - OP op(const_cast<search::AttributeVector &>(attributeVector), _operand); + void operator()(const IAttributeVector &attributeVector) override { + OP op(const_cast<IAttributeVector &>(attributeVector), _operand); if (op.valid()) { - std::for_each(_docIds.begin(), _docIds.end(), - [&op](uint32_t docId) { op(docId); }); + std::for_each(_docIds.begin(), _docIds.end(), [&op](uint32_t docId) { op(docId); }); } } private: @@ -166,7 +164,7 @@ struct Operation { enum class Type { INC, DEC, ADD, SUB, MUL, DIV, MOD, SET, BAD }; Operation(Type operation_in, vespalib::stringref operand_in) : operation(operation_in), operand(operand_in) { } template <typename V> - std::unique_ptr<AttributeOperation> create(search::attribute::BasicType type, V vector) const; + std::unique_ptr<AttributeOperation> create(BasicType type, V vector) const; template <typename IT, typename V> std::unique_ptr<AttributeOperation> create(V vector) const; bool valid() const { return operation != Type::BAD; } @@ -274,26 +272,26 @@ Operation::create(V vector) const { struct Int64T { using T = int64_t; - using A = search::IntegerAttributeTemplate<int64_t>; + using A = IntegerAttributeTemplate<int64_t>; }; struct Int32T { using T = int64_t; - using A = search::IntegerAttributeTemplate<int32_t>; + using A = IntegerAttributeTemplate<int32_t>; }; struct Int8T { using T = int64_t; - using A = search::IntegerAttributeTemplate<int8_t>; + using A = IntegerAttributeTemplate<int8_t>; }; struct DoubleT { using T = double; - using A = search::FloatingPointAttributeTemplate<double>; + using A = FloatingPointAttributeTemplate<double>; }; struct FloatT { using T = double; - using A = search::FloatingPointAttributeTemplate<float>; + using A = FloatingPointAttributeTemplate<float>; }; template <typename V> diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_operation.h b/searchlib/src/vespa/searchlib/attribute/attribute_operation.h index 3d6afd75640..7a3e22fce27 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_operation.h +++ b/searchlib/src/vespa/searchlib/attribute/attribute_operation.h @@ -2,7 +2,7 @@ #pragma once -#include "i_attribute_functor.h" +#include "vespa/searchcommon/attribute/i_attribute_functor.h" #include <vespa/searchlib/common/rankedhit.h> #include <vespa/searchcommon/attribute/basictype.h> #include <vespa/vespalib/util/array.h> diff --git a/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp b/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp index 6d7d90844bc..f6ad4b75dfa 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp @@ -5,7 +5,6 @@ #include "attribute_read_guard.h" #include <vespa/vespalib/stllike/hash_map.hpp> -using namespace search; using namespace search::attribute; namespace search { @@ -69,4 +68,9 @@ AttributeContext::getAttributeList(std::vector<const IAttributeVector *> & list) } } +void +AttributeContext::asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const { + _manager.asyncForAttribute(name, func); +} + } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/attributecontext.h b/searchlib/src/vespa/searchlib/attribute/attributecontext.h index 6a158a26229..0313ef12995 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributecontext.h +++ b/searchlib/src/vespa/searchlib/attribute/attributecontext.h @@ -16,28 +16,30 @@ namespace search { class AttributeContext : public attribute::IAttributeContext { private: - typedef vespalib::hash_map<string, std::unique_ptr<attribute::AttributeReadGuard>> AttributeMap; + using AttributeMap = vespalib::hash_map<string, std::unique_ptr<attribute::AttributeReadGuard>>; + using IAttributeVector = attribute::IAttributeVector; + using IAttributeFunctor = attribute::IAttributeFunctor; - const search::IAttributeManager & _manager; + const IAttributeManager & _manager; mutable AttributeMap _attributes; mutable AttributeMap _enumAttributes; mutable std::mutex _cacheLock; - const attribute::IAttributeVector * - getAttribute(AttributeMap & map, const string & name, bool stableEnum) const; + const IAttributeVector *getAttribute(AttributeMap & map, const string & name, bool stableEnum) const; public: - AttributeContext(const search::IAttributeManager & manager); + AttributeContext(const IAttributeManager & manager); ~AttributeContext(); // Implements IAttributeContext const attribute::IAttributeVector * getAttribute(const string & name) const override; + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override; const attribute::IAttributeVector * getAttributeStableEnum(const string & name) const override; - void getAttributeList(std::vector<const attribute::IAttributeVector *> & list) const override; + void getAttributeList(std::vector<const IAttributeVector *> & list) const override; void releaseEnumGuards() override; // Give acces to the underlying manager - const search::IAttributeManager & getManager() const { return _manager; } + const IAttributeManager & getManager() const { return _manager; } }; } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp b/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp index 6e8736a535c..a28ed98c169 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp @@ -259,5 +259,10 @@ AttributeManager::addVector(const string & name, const Config & config) return retval; } +void +AttributeManager::asyncForAttribute(const vespalib::string &, std::shared_ptr<attribute::IAttributeFunctor>) const { + throw std::runtime_error("search::AttributeManager::asyncForAttribute should never be called."); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/attributemanager.h b/searchlib/src/vespa/searchlib/attribute/attributemanager.h index 03c72dcb5da..6171865c2db 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributemanager.h +++ b/searchlib/src/vespa/searchlib/attribute/attributemanager.h @@ -26,7 +26,7 @@ public: using VectorHolder = std::shared_ptr<AttributeVector>; AttributeManager(); AttributeManager(const string & base); - ~AttributeManager(); + ~AttributeManager() override; /** * This will give you a handle to an attributevector. It @@ -38,6 +38,8 @@ public: AttributeGuard::UP getAttribute(const string & name) const override; std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override; + void asyncForAttribute(const vespalib::string &name, std::shared_ptr<attribute::IAttributeFunctor> func) const override; + /** * This will load attributes in the most memory economical way by loading largest first. */ @@ -52,6 +54,8 @@ public: void setBaseDir(const string & base); bool hasReaders() const; uint64_t getMemoryFootprint() const; + + protected: typedef vespalib::hash_map<string, VectorHolder> AttributeMap; AttributeMap _attributes; diff --git a/searchlib/src/vespa/searchlib/attribute/iattributemanager.h b/searchlib/src/vespa/searchlib/attribute/iattributemanager.h index 079463dd290..ef9403e1c4b 100644 --- a/searchlib/src/vespa/searchlib/attribute/iattributemanager.h +++ b/searchlib/src/vespa/searchlib/attribute/iattributemanager.h @@ -13,7 +13,7 @@ namespace attribute { class AttributeReadGuard; } /** * This is an interface used to access all registered attribute vectors. **/ -class IAttributeManager { +class IAttributeManager : public attribute::IAttributeExecutor { public: IAttributeManager(const IAttributeManager &) = delete; IAttributeManager & operator = (const IAttributeManager &) = delete; diff --git a/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.cpp b/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.cpp index e9d45b95fd0..c7ee8501e7e 100644 --- a/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.cpp +++ b/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.cpp @@ -2,22 +2,25 @@ #include "mock_attribute_context.h" #include "attribute_map.h" -namespace search { -namespace fef { -namespace test { +namespace search::fef::test { using IAttributeVector = attribute::IAttributeVector; -const IAttributeVector * MockAttributeContext::getAttribute(const string & name) const { +const IAttributeVector * +MockAttributeContext::getAttribute(const string & name) const { return _attributes.getAttribute(name); } -const IAttributeVector * MockAttributeContext::getAttributeStableEnum(const string & name) const { +const IAttributeVector * +MockAttributeContext::getAttributeStableEnum(const string & name) const { return getAttribute(name); } -void MockAttributeContext::getAttributeList(std::vector<const IAttributeVector *> & list) const { +void +MockAttributeContext::getAttributeList(std::vector<const IAttributeVector *> & list) const { _attributes.getAttributeList(list); } -} // test -} // fef -} // search +void +MockAttributeContext::asyncForAttribute(const vespalib::string &, std::shared_ptr<attribute::IAttributeFunctor>) const { +} + +} diff --git a/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.h b/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.h index 38196d25447..b1b58086caa 100644 --- a/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.h +++ b/searchlib/src/vespa/searchlib/fef/test/mock_attribute_context.h @@ -6,9 +6,7 @@ #pragma once -namespace search { -namespace fef { -namespace test { +namespace search::fef::test { class AttributeMap; @@ -33,8 +31,9 @@ public: const IAttributeVector * getAttribute(const string & name) const override; const IAttributeVector * getAttributeStableEnum(const string & name) const override; void getAttributeList(std::vector<const IAttributeVector *> & list) const override; + + void + asyncForAttribute(const vespalib::string &name, std::shared_ptr<attribute::IAttributeFunctor> func) const override; }; -} // test -} // fef -} // search +} diff --git a/searchlib/src/vespa/searchlib/test/CMakeLists.txt b/searchlib/src/vespa/searchlib/test/CMakeLists.txt index aeaa1e1443e..b4fb895c0e2 100644 --- a/searchlib/src/vespa/searchlib/test/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/test/CMakeLists.txt @@ -3,6 +3,8 @@ vespa_add_library(searchlib_test SOURCES document_weight_attribute_helper.cpp initrange.cpp + mock_attribute_context.cpp + mock_attribute_manager.cpp searchiteratorverifier.cpp statefile.cpp statestring.cpp diff --git a/searchlib/src/vespa/searchlib/test/mock_attribute_context.cpp b/searchlib/src/vespa/searchlib/test/mock_attribute_context.cpp new file mode 100644 index 00000000000..03a11efbcbd --- /dev/null +++ b/searchlib/src/vespa/searchlib/test/mock_attribute_context.cpp @@ -0,0 +1,48 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "mock_attribute_context.h" + +namespace search::attribute::test { + +const IAttributeVector * +MockAttributeContext::get(const string &name) const { + if (_vectors.find(name) == _vectors.end()) { + return 0; + } + return _vectors.find(name)->second; +} +const IAttributeVector * +MockAttributeContext::getAttribute(const string &name) const { + return get(name); +} +const IAttributeVector * +MockAttributeContext::getAttributeStableEnum(const string &name) const { + return get(name); +} +void +MockAttributeContext::getAttributeList(std::vector<const IAttributeVector *> & list) const { + Map::const_iterator pos = _vectors.begin(); + Map::const_iterator end = _vectors.end(); + for (; pos != end; ++pos) { + list.push_back(pos->second); + } +} +MockAttributeContext::~MockAttributeContext() { + Map::iterator pos = _vectors.begin(); + Map::iterator end = _vectors.end(); + for (; pos != end; ++pos) { + delete pos->second; + } +} + +void +MockAttributeContext::add(IAttributeVector *attr) { + _vectors[attr->getName()] = attr; +} + +void +MockAttributeContext::asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const { + throw std::runtime_error("MockAttributeContext::asyncForAttribute is not implemented and should not be reached"); +} + +} diff --git a/searchlib/src/vespa/searchlib/test/mock_attribute_context.h b/searchlib/src/vespa/searchlib/test/mock_attribute_context.h new file mode 100644 index 00000000000..d12dbe34b6f --- /dev/null +++ b/searchlib/src/vespa/searchlib/test/mock_attribute_context.h @@ -0,0 +1,28 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/searchcommon/attribute/iattributecontext.h> +#include <map> + +namespace search::attribute::test { + +class MockAttributeContext : public IAttributeContext +{ +private: + typedef std::map<string, IAttributeVector *> Map; + Map _vectors; + +public: + ~MockAttributeContext() override; + void add(IAttributeVector *attr); + + const IAttributeVector *get(const string &name) const; + const IAttributeVector * getAttribute(const string &name) const override; + const IAttributeVector * getAttributeStableEnum(const string &name) const override; + void getAttributeList(std::vector<const IAttributeVector *> & list) const override; + void asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override; + +}; + +} diff --git a/searchlib/src/vespa/searchlib/test/mock_attribute_manager.cpp b/searchlib/src/vespa/searchlib/test/mock_attribute_manager.cpp new file mode 100644 index 00000000000..88a3bcc78cf --- /dev/null +++ b/searchlib/src/vespa/searchlib/test/mock_attribute_manager.cpp @@ -0,0 +1,64 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "mock_attribute_manager.h" + +namespace search::attribute::test { + +AttributeVector::SP +MockAttributeManager::findAttribute(const vespalib::string &name) const { + AttributeMap::const_iterator itr = _attributes.find(name); + if (itr != _attributes.end()) { + return itr->second; + } + return AttributeVector::SP(); +} + + +MockAttributeManager::MockAttributeManager() = default; +MockAttributeManager::~MockAttributeManager() = default; + +AttributeGuard::UP +MockAttributeManager::getAttribute(const vespalib::string &name) const { + AttributeVector::SP attr = findAttribute(name); + return AttributeGuard::UP(new AttributeGuard(attr)); +} + +void +MockAttributeManager::asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const { + throw std::runtime_error("search::MockAttributeManager::asyncForAttribute not implemented."); +} + +std::unique_ptr<AttributeReadGuard> +MockAttributeManager::getAttributeReadGuard(const vespalib::string &name, bool stableEnumGuard) const { + AttributeVector::SP attr = findAttribute(name); + if (attr) { + return attr->makeReadGuard(stableEnumGuard); + } else { + return std::unique_ptr<AttributeReadGuard>(); + } +} + +void +MockAttributeManager::getAttributeList(std::vector<AttributeGuard> &list) const { + list.reserve(_attributes.size()); + for (const auto &attr : _attributes) { + list.push_back(AttributeGuard(attr.second)); + } +} + +IAttributeContext::UP +MockAttributeManager::createContext() const { + return IAttributeContext::UP(new AttributeContext(*this)); +} + +void +MockAttributeManager::addAttribute(const vespalib::string &name, const AttributeVector::SP &attr) { + attr->addReservedDoc(); + _attributes[name] = attr; +} +void +MockAttributeManager::addAttribute(const AttributeVector::SP &attr) { + addAttribute(attr->getName(), attr); +} + +} diff --git a/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h b/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h index 1e7f546d864..b44b8480077 100644 --- a/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h +++ b/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h @@ -8,9 +8,7 @@ #include <vespa/searchlib/attribute/iattributemanager.h> #include <map> -namespace search { -namespace attribute { -namespace test { +namespace search::attribute::test { class MockAttributeManager : public search::IAttributeManager { protected: @@ -18,49 +16,18 @@ protected: AttributeMap _attributes; - AttributeVector::SP - findAttribute(const vespalib::string &name) const { - AttributeMap::const_iterator itr = _attributes.find(name); - if (itr != _attributes.end()) { - return itr->second; - } - return AttributeVector::SP(); - } - + AttributeVector::SP findAttribute(const vespalib::string &name) const; public: - MockAttributeManager() : _attributes() {} - - virtual AttributeGuard::UP getAttribute(const vespalib::string &name) const override { - AttributeVector::SP attr = findAttribute(name); - return AttributeGuard::UP(new AttributeGuard(attr)); - } - - virtual std::unique_ptr<AttributeReadGuard> getAttributeReadGuard(const vespalib::string &name, bool stableEnumGuard) const override { - AttributeVector::SP attr = findAttribute(name); - if (attr) { - return attr->makeReadGuard(stableEnumGuard); - } else { - return std::unique_ptr<AttributeReadGuard>(); - } - } - - virtual void getAttributeList(std::vector<AttributeGuard> &list) const override { - list.reserve(_attributes.size()); - for (const auto &attr : _attributes) { - list.push_back(AttributeGuard(attr.second)); - } - } - - virtual IAttributeContext::UP createContext() const override { - return IAttributeContext::UP(new AttributeContext(*this)); - } - - void addAttribute(const vespalib::string &name, const AttributeVector::SP &attr) { - attr->addReservedDoc(); - _attributes[name] = attr; - } + MockAttributeManager(); + ~MockAttributeManager() override; + + AttributeGuard::UP getAttribute(const vespalib::string &name) const override; + void asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override; + std::unique_ptr<AttributeReadGuard> getAttributeReadGuard(const vespalib::string &name, bool stableEnumGuard) const override; + void getAttributeList(std::vector<AttributeGuard> &list) const override; + IAttributeContext::UP createContext() const override; + void addAttribute(const vespalib::string &name, const AttributeVector::SP &attr); + void addAttribute(const AttributeVector::SP &attr); }; } -} -} diff --git a/searchsummary/src/tests/docsummary/positionsdfw_test.cpp b/searchsummary/src/tests/docsummary/positionsdfw_test.cpp index ce184fd328a..7c2f2f923a5 100644 --- a/searchsummary/src/tests/docsummary/positionsdfw_test.cpp +++ b/searchsummary/src/tests/docsummary/positionsdfw_test.cpp @@ -1,9 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. // Unit tests for positionsdfw. -#include <vespa/log/log.h> -LOG_SETUP("positionsdfw_test"); - #include <vespa/searchlib/attribute/extendableattributes.h> #include <vespa/searchlib/attribute/iattributemanager.h> #include <vespa/searchsummary/docsummary/docsumfieldwriter.h> @@ -15,11 +12,15 @@ LOG_SETUP("positionsdfw_test"); #include <vespa/vespalib/data/slime/slime.h> #include <vespa/juniper/rpinterface.h> +#include <vespa/log/log.h> +LOG_SETUP("positionsdfw_test"); + using search::RawBuf; using search::IAttributeManager; using search::SingleInt64ExtAttribute; using search::attribute::IAttributeContext; using search::attribute::IAttributeVector; +using search::attribute::IAttributeFunctor; using vespalib::string; using std::vector; @@ -50,22 +51,29 @@ struct MyEnvironment : IDocsumEnvironment { MyEnvironment() : attribute_man(0) {} - virtual IAttributeManager *getAttributeManager() override { return attribute_man; } - virtual string lookupIndex(const string &s) const override { return s; } - virtual juniper::Juniper *getJuniper() override { return 0; } + IAttributeManager *getAttributeManager() override { return attribute_man; } + string lookupIndex(const string &s) const override { return s; } + juniper::Juniper *getJuniper() override { return 0; } }; class MyAttributeContext : public IAttributeContext { const IAttributeVector &_attr; public: MyAttributeContext(const IAttributeVector &attr) : _attr(attr) {} - virtual const IAttributeVector *getAttribute(const string &) const override { + const IAttributeVector *getAttribute(const string &) const override { return &_attr; } - virtual const IAttributeVector * - getAttributeStableEnum(const string &) const override { LOG_ABORT("should not be reached"); } - virtual void getAttributeList(vector<const IAttributeVector *> &) const override - { LOG_ABORT("should not be reached"); } + const IAttributeVector *getAttributeStableEnum(const string &) const override { + LOG_ABORT("should not be reached"); + } + void getAttributeList(vector<const IAttributeVector *> &) const override { + LOG_ABORT("should not be reached"); + } + + void + asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override { + + } }; class MyAttributeManager : public IAttributeManager { @@ -73,16 +81,22 @@ class MyAttributeManager : public IAttributeManager { public: MyAttributeManager(const IAttributeVector &attr) : _attr(attr) {} - virtual AttributeGuard::UP getAttribute(const string &) const override { + AttributeGuard::UP getAttribute(const string &) const override { LOG_ABORT("should not be reached"); } - virtual std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &, bool) const override { + std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &, bool) const override { LOG_ABORT("should not be reached"); } - virtual void getAttributeList(vector<AttributeGuard> &) const override { + void getAttributeList(vector<AttributeGuard> &) const override { LOG_ABORT("should not be reached"); } - virtual IAttributeContext::UP createContext() const override { + + void + asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override { + LOG_ABORT("should not be reached"); + } + + IAttributeContext::UP createContext() const override { return IAttributeContext::UP(new MyAttributeContext(_attr)); } }; |