aboutsummaryrefslogtreecommitdiffstats
path: root/searchcore/src/vespa
diff options
context:
space:
mode:
Diffstat (limited to 'searchcore/src/vespa')
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt1
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_explorer.cpp21
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.cpp28
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attribute_vector_explorer.h26
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp10
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.cpp69
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_loop_communicator.h14
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_master.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_params.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp13
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_tools.h4
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp16
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp66
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp13
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/rpc_hooks.h1
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/port_numbers.h22
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;
+
+}