diff options
Diffstat (limited to 'searchcore/src/vespa')
19 files changed, 256 insertions, 69 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt b/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt index 3717c24650d..c1f10ebd80d 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt +++ b/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt @@ -34,6 +34,7 @@ vespa_add_library(searchcore_attribute STATIC document_field_retriever.cpp filter_attribute_manager.cpp flushableattribute.cpp + imported_attribute_vector_explorer.cpp imported_attributes_context.cpp imported_attributes_repo.cpp initialized_attributes_result.cpp diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_explorer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_explorer.cpp index 0b48afe4ab8..0797ddfb6cd 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_explorer.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_explorer.cpp @@ -3,9 +3,13 @@ #include "attribute_manager_explorer.h" #include "attribute_executor.h" #include "attribute_vector_explorer.h" +#include "imported_attribute_vector_explorer.h" +#include "imported_attributes_repo.h" #include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/imported_attribute_vector.h> using search::AttributeVector; +using search::attribute::ImportedAttributeVector; using vespalib::slime::Inserter; namespace proton { @@ -32,6 +36,14 @@ AttributeManagerExplorer::get_children_names() const for (const auto &attr : attributes) { names.push_back(attr->getName()); } + auto imported = _mgr->getImportedAttributes(); + if (imported != nullptr) { + std::vector<std::shared_ptr<ImportedAttributeVector>> i_list; + imported->getAll(i_list); + for (const auto& attr : i_list) { + names.push_back(attr->getName()); + } + } return names; } @@ -39,6 +51,15 @@ std::unique_ptr<vespalib::StateExplorer> AttributeManagerExplorer::get_child(vespalib::stringref name) const { auto guard = _mgr->getAttribute(name); + if (!guard || !guard->getSP()) { + auto imported = _mgr->getImportedAttributes(); + if (imported != nullptr) { + auto& imported_attr = imported->get(name); + if (imported_attr) { + return std::make_unique<ImportedAttributeVectorExplorer>(imported_attr); + } + } + } auto attr = guard ? guard->getSP() : std::shared_ptr<AttributeVector>(); if (attr && _mgr->getWritableAttribute(name) != nullptr) { auto executor = std::make_unique<AttributeExecutor>(_mgr, std::move(attr)); diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.cpp new file mode 100644 index 00000000000..dd858b78934 --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.cpp @@ -0,0 +1,28 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "imported_attribute_vector_explorer.h" +#include <vespa/searchlib/attribute/imported_attribute_vector.h> +#include <vespa/searchlib/util/state_explorer_utils.h> +#include <vespa/vespalib/data/slime/cursor.h> +#include <vespa/vespalib/util/memoryusage.h> + +using search::StateExplorerUtils; +using search::attribute::ImportedAttributeVector; +using namespace vespalib::slime; + +namespace proton { + +ImportedAttributeVectorExplorer::ImportedAttributeVectorExplorer(std::shared_ptr<ImportedAttributeVector> attr) + : _attr(std::move(attr)) +{ +} + +void +ImportedAttributeVectorExplorer::get_state(const vespalib::slime::Inserter &inserter, bool) const +{ + Cursor &object = inserter.insertObject(); + auto memory_usage = _attr->get_memory_usage(); + StateExplorerUtils::memory_usage_to_slime(memory_usage, object.setObject("cacheMemoryUsage")); +} + +} diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.h b/searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.h new file mode 100644 index 00000000000..ce8854b03d2 --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.h @@ -0,0 +1,26 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/vespalib/net/http/state_explorer.h> + +namespace search::attribute { class ImportedAttributeVector; } + +namespace proton { + +/** + * Class used to explore the state of an imported attribute vector. + */ +class ImportedAttributeVectorExplorer : public vespalib::StateExplorer +{ +private: + std::shared_ptr<search::attribute::ImportedAttributeVector> _attr; + +public: + ImportedAttributeVectorExplorer(std::shared_ptr<search::attribute::ImportedAttributeVector> attr); + + // Implements vespalib::StateExplorer + void get_state(const vespalib::slime::Inserter &inserter, bool full) const override; +}; + +} diff --git a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp index 01dcf87db37..e6c5a17baaf 100644 --- a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp +++ b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp @@ -503,7 +503,7 @@ void AttributeUpdater::updateValue(TensorAttribute &vec, uint32_t lid, const FieldValue &val) { validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue"); - const auto &tensor = static_cast<const TensorFieldValue &>(val).getAsTensorPtr(); + const auto* tensor = static_cast<const TensorFieldValue &>(val).getAsTensorPtr(); if (tensor) { vec.setTensor(lid, *tensor); } else { @@ -558,7 +558,7 @@ std::unique_ptr<PrepareResult> prepare_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val) { validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue"); - const auto& tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr(); + const auto* tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr(); if (tensor) { return attr.prepare_set_tensor(docid, *tensor); } @@ -569,7 +569,7 @@ void complete_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val, std::unique_ptr<PrepareResult> prepare_result) { validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue"); - const auto& tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr(); + const auto* tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr(); if (tensor) { attr.complete_set_tensor(docid, *tensor, std::move(prepare_result)); } else { diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp index 0c986422be6..758d1336399 100644 --- a/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp +++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp @@ -210,7 +210,8 @@ private: } FlowStats calculate_flow_stats(uint32_t docid_limit) const override { double rel_est = abs_to_rel_est(_activeLids.size(), docid_limit); - return {rel_est, bitvector_cost(), bitvector_strict_cost(rel_est)}; + double do_not_make_me_strict = 1000.0; + return {rel_est, bitvector_cost(), do_not_make_me_strict * bitvector_strict_cost(rel_est)}; } SearchIterator::UP createLeafSearch(const TermFieldMatchDataArray &tfmda) const override diff --git a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp index 0b2660824c0..f8b6666afc4 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp @@ -9,6 +9,7 @@ #include <vespa/searchlib/queryeval/intermediate_blueprints.h> #include <vespa/searchlib/queryeval/equiv_blueprint.h> #include <vespa/searchlib/queryeval/get_weight_from_node.h> +#include <vespa/searchlib/attribute/attribute_blueprint_params.h> #include <vespa/vespalib/util/issue.h> using namespace search::queryeval; @@ -21,7 +22,7 @@ namespace { struct Mixer { std::unique_ptr<OrBlueprint> attributes; - Mixer() : attributes() {} + Mixer() noexcept: attributes() {} void addAttribute(Blueprint::UP attr) { if ( ! attributes) { @@ -61,12 +62,17 @@ private: Blueprint::UP _result; void buildChildren(IntermediateBlueprint &parent, const std::vector<Node *> &children); + bool is_search_multi_threaded() const noexcept { + return _requestContext.thread_bundle().size() > 1; + } template <typename NodeType> void buildIntermediate(IntermediateBlueprint *b, NodeType &n) __attribute__((noinline)); void buildWeakAnd(ProtonWeakAnd &n) { - auto *wand = new WeakAndBlueprint(n.getTargetNumHits()); + auto *wand = new WeakAndBlueprint(n.getTargetNumHits(), + _requestContext.get_attribute_blueprint_params().weakand_range, + is_search_multi_threaded()); Blueprint::UP result(wand); for (auto node : n.getChildren()) { uint32_t weight = getWeightFromNode(*node).percent(); diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.cpp index 01a9508220d..37ae78404a3 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.cpp @@ -1,18 +1,21 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "match_loop_communicator.h" +#include <vespa/searchlib/features/first_phase_rank_lookup.h> #include <vespa/vespalib/util/priority_queue.h> +using search::features::FirstPhaseRankLookup; + namespace proton:: matching { MatchLoopCommunicator::MatchLoopCommunicator(size_t threads, size_t topN) - : MatchLoopCommunicator(threads, topN, std::unique_ptr<IDiversifier>()) + : MatchLoopCommunicator(threads, topN, {}, nullptr) {} -MatchLoopCommunicator::MatchLoopCommunicator(size_t threads, size_t topN, std::unique_ptr<IDiversifier> diversifier) +MatchLoopCommunicator::MatchLoopCommunicator(size_t threads, size_t topN, std::unique_ptr<IDiversifier> diversifier, FirstPhaseRankLookup* first_phase_rank_lookup) : _best_scores(), _best_dropped(), _estimate_match_frequency(threads), - _get_second_phase_work(threads, topN, _best_scores, _best_dropped, std::move(diversifier)), + _get_second_phase_work(threads, topN, _best_scores, _best_dropped, std::move(diversifier), first_phase_rank_lookup), _complete_second_phase(threads, topN, _best_scores, _best_dropped) {} MatchLoopCommunicator::~MatchLoopCommunicator() = default; @@ -34,18 +37,43 @@ MatchLoopCommunicator::EstimateMatchFrequency::mingle() } } -MatchLoopCommunicator::GetSecondPhaseWork::GetSecondPhaseWork(size_t n, size_t topN_in, Range &best_scores_in, BestDropped &best_dropped_in, std::unique_ptr<IDiversifier> diversifier) +namespace { + +class NoRegisterFirstPhaseRank { +public: + static void pick(uint32_t) noexcept { }; + static void drop() noexcept { } +}; + +class RegisterFirstPhaseRank { + FirstPhaseRankLookup& _first_phase_rank_lookup; + uint32_t _rank; +public: + RegisterFirstPhaseRank(FirstPhaseRankLookup& first_phase_rank_lookup) + : _first_phase_rank_lookup(first_phase_rank_lookup), + _rank(0) + { + } + void pick(uint32_t docid) noexcept { _first_phase_rank_lookup.add(docid, ++_rank); } + void drop() noexcept { ++_rank; } +}; + +} + +MatchLoopCommunicator::GetSecondPhaseWork::GetSecondPhaseWork(size_t n, size_t topN_in, Range &best_scores_in, BestDropped &best_dropped_in, std::unique_ptr<IDiversifier> diversifier, FirstPhaseRankLookup* first_phase_rank_lookup) : vespalib::Rendezvous<SortedHitSequence, TaggedHits, true>(n), topN(topN_in), best_scores(best_scores_in), best_dropped(best_dropped_in), - _diversifier(std::move(diversifier)) + _diversifier(std::move(diversifier)), + _first_phase_rank_lookup(first_phase_rank_lookup) {} + MatchLoopCommunicator::GetSecondPhaseWork::~GetSecondPhaseWork() = default; -template<typename Q, typename F> +template<typename Q, typename F, typename R> void -MatchLoopCommunicator::GetSecondPhaseWork::mingle(Q &queue, F &&accept) +MatchLoopCommunicator::GetSecondPhaseWork::mingle(Q &queue, F &&accept, R register_first_phase_rank) { size_t picked = 0; search::feature_t last_score = 0.0; @@ -53,14 +81,18 @@ MatchLoopCommunicator::GetSecondPhaseWork::mingle(Q &queue, F &&accept) uint32_t i = queue.front(); const Hit & hit = in(i).get(); if (accept(hit.first)) { + register_first_phase_rank.pick(hit.first); out(picked % size()).emplace_back(hit, i); last_score = hit.second; if (++picked == 1) { best_scores.high = hit.second; } - } else if (!best_dropped.valid) { - best_dropped.valid = true; - best_dropped.score = hit.second; + } else { + if (!best_dropped.valid) { + best_dropped.valid = true; + best_dropped.score = hit.second; + } + register_first_phase_rank.drop(); } in(i).next(); if (in(i).valid()) { @@ -74,6 +106,17 @@ MatchLoopCommunicator::GetSecondPhaseWork::mingle(Q &queue, F &&accept) } } +template<typename Q, typename R> +void +MatchLoopCommunicator::GetSecondPhaseWork::mingle(Q &queue, R register_first_phase_rank) +{ + if (_diversifier) { + mingle(queue, [diversifier=_diversifier.get()](uint32_t docId) { return diversifier->accepted(docId);}, register_first_phase_rank); + } else { + mingle(queue, [](uint32_t) { return true;}, register_first_phase_rank); + } +} + void MatchLoopCommunicator::GetSecondPhaseWork::mingle() { @@ -87,10 +130,10 @@ MatchLoopCommunicator::GetSecondPhaseWork::mingle() queue.push(i); } } - if (_diversifier) { - mingle(queue, [diversifier=_diversifier.get()](uint32_t docId) { return diversifier->accepted(docId);}); + if (_first_phase_rank_lookup != nullptr) { + mingle(queue, RegisterFirstPhaseRank(*_first_phase_rank_lookup)); } else { - mingle(queue, [](uint32_t) { return true;}); + mingle(queue, NoRegisterFirstPhaseRank()); } } diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.h b/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.h index eb93bdb68d5..d2fdf00ba38 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.h +++ b/searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.h @@ -6,12 +6,15 @@ #include <vespa/searchlib/queryeval/idiversifier.h> #include <vespa/vespalib/util/rendezvous.h> +namespace search::features { class FirstPhaseRankLookup; } + namespace proton::matching { class MatchLoopCommunicator final : public IMatchLoopCommunicator { private: using IDiversifier = search::queryeval::IDiversifier; + using FirstPhaseRankLookup = search::features::FirstPhaseRankLookup; struct BestDropped { bool valid = false; search::feature_t score = 0.0; @@ -25,11 +28,14 @@ private: Range &best_scores; BestDropped &best_dropped; std::unique_ptr<IDiversifier> _diversifier; - GetSecondPhaseWork(size_t n, size_t topN_in, Range &best_scores_in, BestDropped &best_dropped_in, std::unique_ptr<IDiversifier>); + FirstPhaseRankLookup* _first_phase_rank_lookup; + GetSecondPhaseWork(size_t n, size_t topN_in, Range &best_scores_in, BestDropped &best_dropped_in, std::unique_ptr<IDiversifier> diversifier, FirstPhaseRankLookup* first_phase_rank_lookup); ~GetSecondPhaseWork() override; void mingle() override; - template<typename Q, typename F> - void mingle(Q &queue, F &&accept); + template<typename Q, typename R> + void mingle(Q &queue, R register_first_phase_rank); + template<typename Q, typename F, typename R> + void mingle(Q &queue, F &&accept, R register_first_phase_rank); bool cmp(uint32_t a, uint32_t b) { return (in(a).get().second > in(b).get().second); } @@ -59,7 +65,7 @@ private: public: MatchLoopCommunicator(size_t threads, size_t topN); - MatchLoopCommunicator(size_t threads, size_t topN, std::unique_ptr<IDiversifier>); + MatchLoopCommunicator(size_t threads, size_t topN, std::unique_ptr<IDiversifier>, FirstPhaseRankLookup* first_phase_rank_lookup); ~MatchLoopCommunicator(); double estimate_match_frequency(const Matches &matches) override { diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp index 89cc97767bf..6dd889da33b 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp @@ -85,7 +85,11 @@ MatchMaster::match(search::engine::Trace & trace, { vespalib::Timer query_latency_time; vespalib::DualMergeDirector mergeDirector(threadBundle.size()); - MatchLoopCommunicator communicator(threadBundle.size(), params.heapSize, mtf.createDiversifier(params.heapSize)); + /* + * We need a non-const first phase rank lookup since it will be populated + * later on when selecting documents for second phase ranking. + */ + MatchLoopCommunicator communicator(threadBundle.size(), params.heapSize, mtf.createDiversifier(params.heapSize), mtf.get_first_phase_rank_lookup()); TimedMatchLoopCommunicator timedCommunicator(communicator); DocidRangeScheduler::UP scheduler = createScheduler(threadBundle.size(), numSearchPartitions, params.numDocs); diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_params.h b/searchcore/src/vespa/searchcore/proton/matching/match_params.h index 5b58c11b7e1..f9dd55e7bb1 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_params.h +++ b/searchcore/src/vespa/searchcore/proton/matching/match_params.h @@ -27,7 +27,7 @@ struct MatchParams { uint32_t hits_in, bool hasFinalRank, bool needRanking=true); - bool save_rank_scores() const { return ((heapSize + arraySize) != 0); } + bool save_rank_scores() const noexcept { return (arraySize != 0); } bool has_rank_drop_limit() const; }; diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp index 211e67f1e2b..6b443231c0a 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp @@ -367,7 +367,7 @@ MatchThread::findMatches(MatchTools &tools) tools.give_back_search(ProfiledIterator::profile(*match_profiler, tools.borrow_search())); tools.tag_search_as_changed(); } - HitCollector hits(matchParams.numDocs, matchParams.arraySize); + HitCollector hits(matchParams.numDocs, match_with_ranking ? matchParams.arraySize : 0); trace->addEvent(4, "Start match and first phase rank"); /** * All, or none of the threads in the bundle must execute the match loop. @@ -380,7 +380,7 @@ MatchThread::findMatches(MatchTools &tools) secondPhase(tools, hits); } trace->addEvent(4, "Create result set"); - return hits.getResultSet(fallback_rank_value()); + return hits.getResultSet(); } void diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp index 532ec2f63bd..66648dda8c6 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp @@ -9,6 +9,7 @@ #include <vespa/searchlib/attribute/diversity.h> #include <vespa/searchlib/queryeval/flow.h> #include <vespa/searchlib/engine/trace.h> +#include <vespa/searchlib/features/first_phase_rank_lookup.h> #include <vespa/searchlib/fef/indexproperties.h> #include <vespa/searchlib/fef/ranksetup.h> #include <vespa/vespalib/util/issue.h> @@ -190,7 +191,8 @@ MatchToolsFactory(QueryLimiter & queryLimiter, _rankSetup(rankSetup), _featureOverrides(featureOverrides), _diversityParams(), - _valid(false) + _valid(false), + _first_phase_rank_lookup(nullptr) { if (doom.soft_doom()) return; auto trace = root_trace.make_trace(); @@ -219,6 +221,7 @@ MatchToolsFactory(QueryLimiter & queryLimiter, _query.freeze(); trace.addEvent(5, "Prepare shared state for multi-threaded rank executors"); _rankSetup.prepareSharedState(_queryEnv, _queryEnv.getObjectStore()); + _first_phase_rank_lookup = FirstPhaseRankLookup::get_mutable_shared_state(_queryEnv.getObjectStore()); _diversityParams = extractDiversityParams(_rankSetup, rankProperties); vespalib::string attribute = DegradationAttribute::lookup(rankProperties, _rankSetup.getDegradationAttribute()); DegradationParams degradationParams = extractDegradationParams(_rankSetup, attribute, rankProperties); @@ -272,11 +275,13 @@ MatchToolsFactory::createTask(vespalib::stringref attribute, vespalib::stringref ? std::make_unique<AttributeOperationTask>(_requestContext, attribute, operation) : std::unique_ptr<AttributeOperationTask>(); } + std::unique_ptr<AttributeOperationTask> MatchToolsFactory::createOnMatchTask() const { const auto & op = _rankSetup.getMutateOnMatch(); return createTask(op._attribute, op._operation); } + std::unique_ptr<AttributeOperationTask> MatchToolsFactory::createOnFirstPhaseTask() const { const auto & op = _rankSetup.getMutateOnFirstPhase(); @@ -289,6 +294,7 @@ MatchToolsFactory::createOnFirstPhaseTask() const { return createTask(op._attribute, op._operation); } } + std::unique_ptr<AttributeOperationTask> MatchToolsFactory::createOnSecondPhaseTask() const { const auto & op = _rankSetup.getMutateOnSecondPhase(); @@ -299,6 +305,7 @@ MatchToolsFactory::createOnSecondPhaseTask() const { return createTask(op._attribute, op._operation); } } + std::unique_ptr<AttributeOperationTask> MatchToolsFactory::createOnSummaryTask() const { const auto & op = _rankSetup.getMutateOnSummary(); @@ -340,6 +347,7 @@ MatchToolsFactory::extract_attribute_blueprint_params(const RankSetup& rank_setu double upper_limit = GlobalFilterUpperLimit::lookup(rank_properties, rank_setup.get_global_filter_upper_limit()); double target_hits_max_adjustment_factor = TargetHitsMaxAdjustmentFactor::lookup(rank_properties, rank_setup.get_target_hits_max_adjustment_factor()); auto fuzzy_matching_algorithm = FuzzyAlgorithm::lookup(rank_properties, rank_setup.get_fuzzy_matching_algorithm()); + double weakand_range = temporary::WeakAndRange::lookup(rank_properties, rank_setup.get_weakand_range()); // Note that we count the reserved docid 0 as active. // This ensures that when searchable-copies=1, the ratio is 1.0. @@ -348,7 +356,8 @@ MatchToolsFactory::extract_attribute_blueprint_params(const RankSetup& rank_setu return {lower_limit * active_hit_ratio, upper_limit * active_hit_ratio, target_hits_max_adjustment_factor, - fuzzy_matching_algorithm}; + fuzzy_matching_algorithm, + weakand_range}; } AttributeOperationTask::AttributeOperationTask(const RequestContext & requestContext, diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h index 759fe68eea2..da18a8b0a2f 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h +++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h @@ -21,6 +21,7 @@ namespace vespalib { class ExecutionProfiler; } namespace vespalib { struct ThreadBundle; } namespace search::engine { class Trace; } +namespace search::features { class FirstPhaseRankLookup; } namespace search::fef { class RankProgram; @@ -119,6 +120,7 @@ private: using RankSetup = search::fef::RankSetup; using IIndexEnvironment = search::fef::IIndexEnvironment; using IDiversifier = search::queryeval::IDiversifier; + using FirstPhaseRankLookup = search::features::FirstPhaseRankLookup; QueryLimiter & _queryLimiter; AttributeBlueprintParams _attribute_blueprint_params; Query _query; @@ -131,6 +133,7 @@ private: const Properties & _featureOverrides; DiversityParams _diversityParams; bool _valid; + FirstPhaseRankLookup* _first_phase_rank_lookup; std::unique_ptr<AttributeOperationTask> createTask(vespalib::stringref attribute, vespalib::stringref operation) const; @@ -186,6 +189,7 @@ public: static AttributeBlueprintParams extract_attribute_blueprint_params(const RankSetup& rank_setup, const Properties& rank_properties, uint32_t active_docids, uint32_t docid_limit); + FirstPhaseRankLookup* get_first_phase_rank_lookup() const noexcept { return _first_phase_rank_lookup; } }; } diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp index dd66c7ceb46..3c7d197d5e1 100644 --- a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp @@ -9,19 +9,23 @@ #include <vespa/searchcommon/attribute/status.h> #include <vespa/searchcore/proton/attribute/attribute_usage_filter.h> #include <vespa/searchcore/proton/attribute/i_attribute_manager.h> +#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h> #include <vespa/searchcore/proton/docsummary/isummarymanager.h> #include <vespa/searchcore/proton/matching/matching_stats.h> #include <vespa/searchcore/proton/metrics/documentdb_job_trackers.h> #include <vespa/searchcore/proton/metrics/executor_threading_service_stats.h> #include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/imported_attribute_vector.h> #include <vespa/vespalib/stllike/cache_stats.h> #include <vespa/searchlib/util/searchable_stats.h> #include <vespa/vespalib/util/memoryusage.h> +#include <vespa/vespalib/util/size_literals.h> #include <vespa/log/log.h> LOG_SETUP(".proton.server.documentdb_metrics_updater"); using search::LidUsageStats; +using search::attribute::ImportedAttributeVector; using vespalib::CacheStats; using vespalib::MemoryUsage; @@ -141,6 +145,18 @@ fillTempAttributeMetrics(TempAttributeMetrics &totalMetrics, fillTempAttributeMetrics(*subMetrics, attr->getName(), memoryUsage, bitVectors); } } + auto imported = attrMgr->getImportedAttributes(); + if (imported != nullptr) { + std::vector<std::shared_ptr<ImportedAttributeVector>> i_list; + imported->getAll(i_list); + for (const auto& attr : i_list) { + auto memory_usage = attr->get_memory_usage(); + fillTempAttributeMetrics(totalMetrics, attr->getName(), memory_usage, 0); + if (subMetrics != nullptr) { + fillTempAttributeMetrics(*subMetrics, attr->getName(), memory_usage, 0); + } + } + } } } } diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp index a2d68ad8920..4972cc790c5 100644 --- a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp @@ -12,9 +12,11 @@ #include <vespa/searchcore/proton/attribute/attribute_manager_initializer.h> #include <vespa/searchcore/proton/attribute/attribute_writer.h> #include <vespa/searchcore/proton/attribute/filter_attribute_manager.h> +#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h> #include <vespa/searchcore/proton/common/alloc_config.h> #include <vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.h> #include <vespa/searchcore/proton/reprocessing/reprocess_documents_task.h> +#include <vespa/searchlib/attribute/imported_attribute_vector.h> #include <vespa/vespalib/util/destructor_callbacks.h> #include <vespa/log/log.h> @@ -23,6 +25,7 @@ LOG_SETUP(".proton.server.fast_access_doc_subdb"); using search::AttributeGuard; using search::AttributeVector; using search::SerialNum; +using search::attribute::ImportedAttributeVector; using search::index::Schema; using proton::initializer::InitializerTask; using searchcorespi::IFlushTarget; @@ -85,16 +88,38 @@ FastAccessDocSubDB::createAttributeManagerInitializer(const DocumentDBConfig &co attrMgrResult); } +namespace { + +vespalib::hash_set<vespalib::string> +get_attribute_names(const proton::IAttributeManager& mgr) +{ + vespalib::hash_set<vespalib::string> both; + std::vector<AttributeGuard> list; + mgr.getAttributeListAll(list); + for (const auto& attr : list) { + both.insert(attr->getName()); + } + auto imported = mgr.getImportedAttributes(); + if (imported != nullptr) { + std::vector<std::shared_ptr<ImportedAttributeVector>> i_list; + imported->getAll(i_list); + for (const auto& attr : i_list) { + both.insert(attr->getName()); + } + } + return both; +} + +} + void FastAccessDocSubDB::setupAttributeManager(AttributeManager::SP attrMgrResult) { if (_addMetrics) { // register attribute metrics - std::vector<AttributeGuard> list; - attrMgrResult->getAttributeListAll(list); + auto list = get_attribute_names(*attrMgrResult); for (const auto &attr : list) { - const AttributeVector &v = *attr; - _metricsWireService.addAttribute(_subAttributeMetrics, v.getName()); + _metricsWireService.addAttribute(_subAttributeMetrics, attr); } } _initAttrMgr = attrMgrResult; @@ -141,33 +166,20 @@ void FastAccessDocSubDB::reconfigureAttributeMetrics(const proton::IAttributeManager &newMgr, const proton::IAttributeManager &oldMgr) { - std::set<vespalib::string> toAdd; - std::set<vespalib::string> toRemove; - std::vector<AttributeGuard> newList; - std::vector<AttributeGuard> oldList; - newMgr.getAttributeList(newList); - oldMgr.getAttributeList(oldList); - for (const auto &newAttr : newList) { - if (std::find_if(oldList.begin(), - oldList.end(), - AttributeGuardComp(newAttr->getName())) == - oldList.end()) { - toAdd.insert(newAttr->getName()); - } - } - for (const auto &oldAttr : oldList) { - if (std::find_if(newList.begin(), - newList.end(), - AttributeGuardComp(oldAttr->getName())) == - newList.end()) { - toRemove.insert(oldAttr->getName()); + auto old_list = get_attribute_names(oldMgr); + auto new_list = get_attribute_names(newMgr); + + for (const auto &attrName : new_list) { + if (old_list.contains(attrName)) { + continue; } - } - for (const auto &attrName : toAdd) { LOG(debug, "reconfigureAttributeMetrics(): addAttribute='%s'", attrName.c_str()); _metricsWireService.addAttribute(_subAttributeMetrics, attrName); } - for (const auto &attrName : toRemove) { + for (const auto &attrName : old_list) { + if (new_list.contains(attrName)) { + continue; + } LOG(debug, "reconfigureAttributeMetrics(): removeAttribute='%s'", attrName.c_str()); _metricsWireService.removeAttribute(_subAttributeMetrics, attrName); } diff --git a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp index b9794bf6a75..785ffcd9663 100644 --- a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp @@ -8,6 +8,7 @@ #include <vespa/fnet/frt/require_capabilities.h> #include <vespa/fnet/frt/supervisor.h> #include <vespa/fnet/transport.h> +#include <cstdlib> #include <vespa/log/log.h> LOG_SETUP(".proton.server.rtchooks"); @@ -89,11 +90,6 @@ RPCHooksBase::initRPC() rb.ReturnDesc("message", "Array of status messages"); rb.RequestAccessFilter(make_proton_admin_api_capability_filter()); //------------------------------------------------------------------------- - rb.DefineMethod("pandora.rtc.die", "", "", - FRT_METHOD(RPCHooksBase::rpc_die), this); - rb.MethodDesc("Exit the rtc application without cleanup"); - rb.RequestAccessFilter(make_proton_admin_api_capability_filter()); - //------------------------------------------------------------------------- rb.DefineMethod("proton.triggerFlush", "", "b", FRT_METHOD(RPCHooksBase::rpc_triggerFlush), this); rb.MethodDesc("Tell the node to trigger flush ASAP"); @@ -241,13 +237,6 @@ RPCHooksBase::getProtonStatus(FRT_RPCRequest *req) } void -RPCHooksBase::rpc_die(FRT_RPCRequest *) -{ - LOG(debug, "RPCHooksBase::rpc_die"); - _exit(0); -} - -void RPCHooksBase::rpc_triggerFlush(FRT_RPCRequest *req) { LOG(info, "RPCHooksBase::rpc_triggerFlush started"); diff --git a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.h b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.h index 0b9329551f5..7f863bc1fc3 100644 --- a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.h +++ b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.h @@ -55,7 +55,6 @@ public: void rpc_GetState(FRT_RPCRequest *req); void rpc_GetProtonStatus(FRT_RPCRequest *req); - void rpc_die(FRT_RPCRequest *req); void rpc_triggerFlush(FRT_RPCRequest *req); void rpc_prepareRestart(FRT_RPCRequest *req); protected: diff --git a/searchcore/src/vespa/searchcore/proton/test/port_numbers.h b/searchcore/src/vespa/searchcore/proton/test/port_numbers.h new file mode 100644 index 00000000000..30b7c9b595b --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/test/port_numbers.h @@ -0,0 +1,22 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +namespace proton::test::port_numbers { + +/* + * The following port numbers are used by unit tests in the searchcore + * module. They should all be in the range 9001..9499. + */ + +constexpr int docsummary_tls_port = 9013; +constexpr int documentdb_tls_port = 9014; +constexpr int feedhandler_tls_port = 9016; + +// Use ports 9020..9029 for persistenceconformance test +constexpr int persistenceconformance_tls_port_base = 9020; +constexpr int persistenceconformance_tls_port_max_bias = 9; + +constexpr int proton_disk_layout_tls_port = 9018; + +} |