From d841fb9699c61f1fc82b8fdd084f9e4404c5aa44 Mon Sep 17 00:00:00 2001 From: Tor Egge Date: Fri, 5 May 2023 10:33:12 +0200 Subject: Add SearchEnvironmentSnapshot for streaming search. --- .../src/tests/searchvisitor/searchvisitor_test.cpp | 8 +++-- .../src/vespa/searchvisitor/CMakeLists.txt | 1 + .../src/vespa/searchvisitor/rankmanager.h | 7 ++-- .../src/vespa/searchvisitor/rankprocessor.cpp | 8 ++--- .../src/vespa/searchvisitor/rankprocessor.h | 4 +-- .../searchvisitor/search_environment_snapshot.cpp | 16 +++++++++ .../searchvisitor/search_environment_snapshot.h | 28 +++++++++++++++ .../src/vespa/searchvisitor/searchenvironment.cpp | 20 ++++++++++- .../src/vespa/searchvisitor/searchenvironment.h | 11 +++--- .../src/vespa/searchvisitor/searchvisitor.cpp | 41 ++++++++++++++-------- .../src/vespa/searchvisitor/searchvisitor.h | 10 +++--- streamingvisitors/src/vespa/vsm/vsm/vsm-adapter.h | 2 +- 12 files changed, 119 insertions(+), 37 deletions(-) create mode 100644 streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.cpp create mode 100644 streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.h (limited to 'streamingvisitors') diff --git a/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp b/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp index 0004e253aff..43309e9fe70 100644 --- a/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp +++ b/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -177,8 +178,11 @@ SearchVisitorTest::~SearchVisitorTest() TEST_F(SearchVisitorTest, search_environment_is_configured) { - EXPECT_TRUE(_env.getVSMAdapter("mycl") != nullptr); - EXPECT_TRUE(_env.getRankManager("mycl") != nullptr); + auto env = _env.get_snapshot("mycl"); + ASSERT_TRUE(env); + EXPECT_TRUE(env->get_rank_manager_snapshot()); + EXPECT_TRUE(env->get_vsm_fields_config()); + EXPECT_TRUE(env->get_docsum_tools()); } HitVector diff --git a/streamingvisitors/src/vespa/searchvisitor/CMakeLists.txt b/streamingvisitors/src/vespa/searchvisitor/CMakeLists.txt index 8a3bd92f5a8..06caf080923 100644 --- a/streamingvisitors/src/vespa/searchvisitor/CMakeLists.txt +++ b/streamingvisitors/src/vespa/searchvisitor/CMakeLists.txt @@ -9,6 +9,7 @@ vespa_add_library(streamingvisitors querywrapper.cpp rankmanager.cpp rankprocessor.cpp + search_environment_snapshot.cpp searchenvironment.cpp searchvisitor.cpp $ diff --git a/streamingvisitors/src/vespa/searchvisitor/rankmanager.h b/streamingvisitors/src/vespa/searchvisitor/rankmanager.h index d600d905328..ad437bf3bb3 100644 --- a/streamingvisitors/src/vespa/searchvisitor/rankmanager.h +++ b/streamingvisitors/src/vespa/searchvisitor/rankmanager.h @@ -33,7 +33,7 @@ public: IndexEnvironment _protoEnv; std::vector _properties; // property set per rank profile std::vector _indexEnv; // index environment per rank profile - std::vector _rankSetup; // rank setup per rank profile + std::vector> _rankSetup; // rank setup per rank profile Map _rpmap; ViewMap _views; @@ -48,7 +48,6 @@ public: } public: - using SP = std::shared_ptr; Snapshot(); ~Snapshot(); const std::vector & getProperties() const { return _properties; } @@ -71,7 +70,7 @@ public: private: search::fef::BlueprintFactory _blueprintFactory; - vespalib::PtrHolder _snapshot; + vespalib::PtrHolder _snapshot; const vsm::VSMAdapter * _vsmAdapter; void configureRankProfiles(const vespa::config::search::RankProfilesConfig & cfg); @@ -86,7 +85,7 @@ public: /** * Retrieves the current snapshot of the rank-profiles config. **/ - Snapshot::SP getSnapshot() const { return _snapshot.get(); } + std::shared_ptr getSnapshot() const { return _snapshot.get(); } }; } // namespace streaming diff --git a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp index 55638c3ec44..92e1ff0e460 100644 --- a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp +++ b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp @@ -143,17 +143,17 @@ RankProcessor::init(bool forRanking, size_t wantedHitCount) initHitCollector(wantedHitCount); } -RankProcessor::RankProcessor(RankManager::Snapshot::SP snapshot, +RankProcessor::RankProcessor(std::shared_ptr snapshot, const vespalib::string &rankProfile, Query & query, const vespalib::string & location, Properties & queryProperties, const search::IAttributeManager * attrMgr) : - _rankManagerSnapshot(snapshot), - _rankSetup(snapshot->getRankSetup(rankProfile)), + _rankManagerSnapshot(std::move(snapshot)), + _rankSetup(_rankManagerSnapshot->getRankSetup(rankProfile)), _query(query), - _queryEnv(location, snapshot->getIndexEnvironment(rankProfile), queryProperties, attrMgr), + _queryEnv(location, _rankManagerSnapshot->getIndexEnvironment(rankProfile), queryProperties, attrMgr), _mdLayout(), _match_data(), _rankProgram(), diff --git a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h index 5307b66e1d5..443a2626bf7 100644 --- a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h +++ b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h @@ -26,7 +26,7 @@ private: using RankProgram = search::fef::RankProgram; using FeatureSet = vespalib::FeatureSet; using FeatureValues = vespalib::FeatureValues; - RankManager::Snapshot::SP _rankManagerSnapshot; + std::shared_ptr _rankManagerSnapshot; const search::fef::RankSetup & _rankSetup; QueryWrapper _query; @@ -58,7 +58,7 @@ private: public: using UP = std::unique_ptr; - RankProcessor(RankManager::Snapshot::SP snapshot, + RankProcessor(std::shared_ptr snapshot, const vespalib::string &rankProfile, search::streaming::Query & query, const vespalib::string & location, diff --git a/streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.cpp b/streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.cpp new file mode 100644 index 00000000000..fc115b647b5 --- /dev/null +++ b/streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.cpp @@ -0,0 +1,16 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "search_environment_snapshot.h" + +namespace streaming { + +SearchEnvironmentSnapshot::SearchEnvironmentSnapshot(const RankManager& rank_manager, const vsm::VSMAdapter& vsm_adapter) + : _rank_manager_snapshot(rank_manager.getSnapshot()), + _vsm_fields_cfg(vsm_adapter.getFieldsConfig()), + _docsum_tools(vsm_adapter.getDocsumTools()) +{ +} + +SearchEnvironmentSnapshot::~SearchEnvironmentSnapshot() = default; + +} diff --git a/streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.h b/streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.h new file mode 100644 index 00000000000..69968f2b9d2 --- /dev/null +++ b/streamingvisitors/src/vespa/searchvisitor/search_environment_snapshot.h @@ -0,0 +1,28 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "rankmanager.h" + +namespace streaming { + +/* + * Snapshot of searchEnvironment used by SearchVisitor. The snapshot + * is created as part of applying config to the search environment and + * references classes based on the same config snapshot. + */ +class SearchEnvironmentSnapshot +{ + std::shared_ptr _rank_manager_snapshot; + std::shared_ptr _vsm_fields_cfg; + std::shared_ptr _docsum_tools; + +public: + SearchEnvironmentSnapshot(const RankManager& rank_manager, const vsm::VSMAdapter& vsm_adapter); + ~SearchEnvironmentSnapshot(); + const std::shared_ptr& get_rank_manager_snapshot() const noexcept { return _rank_manager_snapshot; } + const std::shared_ptr& get_vsm_fields_config() const noexcept { return _vsm_fields_cfg; } + const std::shared_ptr& get_docsum_tools() const noexcept { return _docsum_tools; } +}; + +} diff --git a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp index 096f9ab4c50..5f4db0fe2d9 100644 --- a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp +++ b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "searchenvironment.h" +#include "search_environment_snapshot.h" #include #include @@ -18,7 +19,8 @@ SearchEnvironment::Env::Env(const config::ConfigUri& configUri, const Fast_Norma : _configId(configUri.getConfigId()), _configurer(std::make_unique(createKeySet(configUri.getConfigId()), configUri.getContext()), this), _vsmAdapter(std::make_unique(_configId, wf)), - _rankManager(std::make_unique(_vsmAdapter.get())) + _rankManager(std::make_unique(_vsmAdapter.get())), + _snapshot() { _configurer.start(); @@ -42,6 +44,16 @@ SearchEnvironment::Env::configure(const config::ConfigSnapshot & snapshot) vsm::VSMConfigSnapshot snap(_configId, snapshot); _vsmAdapter->configure(snap); _rankManager->configure(snap); + auto se_snapshot = std::make_shared(*_rankManager, *_vsmAdapter); + std::lock_guard guard(_lock); + std::swap(se_snapshot, _snapshot); +} + +std::shared_ptr +SearchEnvironment::Env::get_snapshot() +{ + std::lock_guard guard(_lock); + return _snapshot; } SearchEnvironment::Env::~Env() @@ -95,4 +107,10 @@ SearchEnvironment::clear_thread_local_env_map() _localEnvMap = nullptr; } +std::shared_ptr +SearchEnvironment::get_snapshot(const vespalib::string& search_cluster) +{ + return getEnv(search_cluster).get_snapshot(); +} + } diff --git a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h index 15a6edd667d..2fdd11d6a77 100644 --- a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h +++ b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h @@ -9,9 +9,12 @@ #include #include #include +#include namespace streaming { +class SearchEnvironmentSnapshot; + class SearchEnvironment : public storage::VisitorEnvironment { private: @@ -20,16 +23,17 @@ private: using SP = std::shared_ptr; Env(const config::ConfigUri& configUri, const Fast_NormalizeWordFolder& wf); ~Env() override; - const vsm::VSMAdapter * getVSMAdapter() const { return _vsmAdapter.get(); } - const RankManager * getRankManager() const { return _rankManager.get(); } void configure(const config::ConfigSnapshot & snapshot) override; static config::ConfigKeySet createKeySet(const vespalib::string & configId); + std::shared_ptr get_snapshot(); private: const vespalib::string _configId; config::SimpleConfigurer _configurer; std::unique_ptr _vsmAdapter; std::unique_ptr _rankManager; + std::shared_ptr _snapshot; + std::mutex _lock; }; using EnvMap = vespalib::hash_map; using EnvMapUP = std::unique_ptr; @@ -47,8 +51,7 @@ private: public: SearchEnvironment(const config::ConfigUri & configUri); ~SearchEnvironment(); - const vsm::VSMAdapter * getVSMAdapter(const vespalib::string & searchcluster) { return getEnv(searchcluster).getVSMAdapter(); } - const RankManager * getRankManager(const vespalib::string & searchcluster) { return getEnv(searchcluster).getRankManager(); } + std::shared_ptr get_snapshot(const vespalib::string& search_cluster); // Should only be used by unit tests to simulate that the calling thread is finished. void clear_thread_local_env_map(); }; diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp index 7a987a39d0e..a7fb80f1749 100644 --- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp +++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp @@ -2,6 +2,7 @@ #include "querytermdata.h" #include "searchenvironment.h" +#include "search_environment_snapshot.h" #include "searchvisitor.h" #include "matching_elements_filler.h" #include @@ -56,11 +57,23 @@ extract_search_cluster(const vdslib::Parameters& params) { Parameters::ValueRef searchClusterBlob; if (params.lookup("searchcluster", searchClusterBlob)) { + LOG(spam, "Received searchcluster blob of %zd bytes", searchClusterBlob.size()); return {{searchClusterBlob.data(), searchClusterBlob.size()}}; } return std::nullopt; } +std::shared_ptr +get_search_environment_snapshot(VisitorEnvironment& v_env, const Parameters& params) +{ + auto& env = dynamic_cast(v_env); + auto search_cluster = extract_search_cluster(params); + if (search_cluster.has_value()) { + return env.get_snapshot(search_cluster.value()); + } + return {}; +} + } class ForceWordfolderInit @@ -263,9 +276,9 @@ SearchVisitor::SearchVisitor(StorageComponent& component, VisitorEnvironment& vEnv, const Parameters& params) : Visitor(component), - _env(dynamic_cast(vEnv)), + _env(get_search_environment_snapshot(vEnv, params)), _params(params), - _vsmAdapter(nullptr), + _init_called(false), _docSearchedCount(0), _hitCount(0), _hitsRejectedCount(0), @@ -369,10 +382,8 @@ void SearchVisitor::init(const Parameters & params) _summaryGenerator.set_location(valueRef); } - auto search_cluster = extract_search_cluster(params); - if (search_cluster.has_value()) { - LOG(spam, "Received searchcluster blob of %zd bytes", search_cluster.value().size()); - _vsmAdapter = _env.getVSMAdapter(search_cluster.value()); + if (_env) { + _init_called = true; if ( params.lookup("sort", valueRef) ) { search::uca::UcaConverterFactory ucaFactory; @@ -396,7 +407,7 @@ void SearchVisitor::init(const Parameters & params) } std::vector additionalFields; - registerAdditionalFields(_vsmAdapter->getDocsumTools()->getFieldSpecs(), additionalFields); + registerAdditionalFields(_env->get_docsum_tools()->getFieldSpecs(), additionalFields); StringFieldIdTMap fieldsInQuery; setupFieldSearchers(additionalFields, fieldsInQuery); @@ -410,8 +421,7 @@ void SearchVisitor::init(const Parameters & params) setupAttributeVectorsForSorting(_sortSpec); - const RankManager * rm = _env.getRankManager(search_cluster.value()); - _rankController.setRankManagerSnapshot(rm->getSnapshot()); + _rankController.setRankManagerSnapshot(_env->get_rank_manager_snapshot()); _rankController.setupRankProcessors(_query, location, wantedSummaryCount, _attrMan, _attributeFields); // This depends on _fieldPathMap (from setupScratchDocument), @@ -743,7 +753,7 @@ SearchVisitor::setupFieldSearchers(const std::vector & additio { // Create mapping from field name to field id, from field id to search spec, // and from index name to list of field ids - _fieldSearchSpecMap.buildFromConfig(_vsmAdapter->getFieldsConfig()); + _fieldSearchSpecMap.buildFromConfig(_env->get_vsm_fields_config()); // Add extra elements to mapping from field name to field id _fieldSearchSpecMap.buildFromConfig(additionalFields); @@ -800,13 +810,14 @@ SearchVisitor::setupScratchDocument(const StringFieldIdTMap & fieldsInQuery) void SearchVisitor::setupDocsumObjects() { - auto docsumFilter = std::make_unique(_vsmAdapter->getDocsumTools(), + auto docsumFilter = std::make_unique(_env->get_docsum_tools(), _rankController.getRankProcessor()->getHitCollector()); docsumFilter->init(_fieldSearchSpecMap.nameIdMap(), *_fieldPathMap); docsumFilter->setSnippetModifiers(_snippetModifierManager.getModifiers()); _summaryGenerator.setFilter(std::move(docsumFilter)); - if (_vsmAdapter->getDocsumTools().get()) { - _summaryGenerator.setDocsumWriter(*_vsmAdapter->getDocsumTools()->getDocsumWriter()); + auto& docsum_tools = _env->get_docsum_tools(); + if (docsum_tools) { + _summaryGenerator.setDocsumWriter(*docsum_tools->getDocsumWriter()); } else { LOG(warning, "No docsum tools available"); } @@ -962,7 +973,7 @@ SearchVisitor::handleDocuments(const document::BucketId&, HitCounter& hitCounter) { (void) hitCounter; - if (_vsmAdapter == nullptr) { + if (!_init_called) { init(_params); } if ( ! _rankController.valid() ) { @@ -1149,7 +1160,7 @@ SearchVisitor::generate_query_result(HitCounter& counter) void SearchVisitor::completedVisitingInternal(HitCounter& hitCounter) { - if (_vsmAdapter == nullptr) { + if (!_init_called) { init(_params); } LOG(debug, "Completed visiting"); diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h index d7c68162246..d0684cd4421 100644 --- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h +++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h @@ -34,6 +34,8 @@ using namespace search::aggregation; namespace streaming { +class SearchEnvironmentSnapshot; + /** * @class storage::SearchVisitor * @@ -122,7 +124,7 @@ private: class RankController { private: vespalib::string _rankProfile; - RankManager::Snapshot::SP _rankManagerSnapshot; + std::shared_ptr _rankManagerSnapshot; const search::fef::RankSetup * _rankSetup; search::fef::Properties _queryProperties; bool _hasRanking; @@ -143,7 +145,7 @@ private: bool valid() const { return _rankProcessor.get() != nullptr; } void setRankProfile(const vespalib::string &rankProfile) { _rankProfile = rankProfile; } const vespalib::string &getRankProfile() const { return _rankProfile; } - void setRankManagerSnapshot(const RankManager::Snapshot::SP & snapshot) { _rankManagerSnapshot = snapshot; } + void setRankManagerSnapshot(const std::shared_ptr& snapshot) { _rankManagerSnapshot = snapshot; } search::fef::Properties & getQueryProperties() { return _queryProperties; } RankProcessor * getRankProcessor() { return _rankProcessor.get(); } void setDumpFeatures(bool dumpFeatures) { _dumpFeatures = dumpFeatures; } @@ -450,9 +452,9 @@ private: }; void init(const vdslib::Parameters & params); - SearchEnvironment & _env; + std::shared_ptr _env; vdslib::Parameters _params; - const vsm::VSMAdapter * _vsmAdapter; + bool _init_called; size_t _docSearchedCount; size_t _hitCount; size_t _hitsRejectedCount; diff --git a/streamingvisitors/src/vespa/vsm/vsm/vsm-adapter.h b/streamingvisitors/src/vespa/vsm/vsm/vsm-adapter.h index 2ca627c837b..975df673afe 100644 --- a/streamingvisitors/src/vespa/vsm/vsm/vsm-adapter.h +++ b/streamingvisitors/src/vespa/vsm/vsm/vsm-adapter.h @@ -87,7 +87,7 @@ public: const juniper::Juniper * getJuniper() const override { return _juniper.get(); } }; -using DocsumToolsPtr = std::shared_ptr; +using DocsumToolsPtr = std::shared_ptr; class VSMConfigSnapshot { private: -- cgit v1.2.3