diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-12-12 15:44:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-12 15:44:52 +0100 |
commit | efc9e84a4678ce90574cdf3d1dba99b9e04c0a87 (patch) | |
tree | a36dd7c01f09fa82bc8cbbc41ee4e1279f80cf8f | |
parent | 96e19ab8cf802a1ddf5087599201511c94ea8814 (diff) | |
parent | 81487d4843b65c66f2f14a3346f3b6b51b85e245 (diff) |
Merge pull request #29617 from vespa-engine/balder/wire-thread-bundle-to-executeinfo-and-requestcontext
Wire in thread bundle to execute info and request context.
26 files changed, 127 insertions, 96 deletions
diff --git a/searchcore/src/tests/proton/matching/match_phase_limiter/match_phase_limiter_test.cpp b/searchcore/src/tests/proton/matching/match_phase_limiter/match_phase_limiter_test.cpp index b26ed1d4765..824ee891873 100644 --- a/searchcore/src/tests/proton/matching/match_phase_limiter/match_phase_limiter_test.cpp +++ b/searchcore/src/tests/proton/matching/match_phase_limiter/match_phase_limiter_test.cpp @@ -69,7 +69,7 @@ struct MockBlueprint : SimpleLeafBlueprint { FieldSpec spec; vespalib::string term; bool postings_fetched = false; - search::queryeval::ExecuteInfo postings_strict = search::queryeval::ExecuteInfo::FALSE; + bool postings_strict = false; MockBlueprint(const FieldSpec &spec_in, const vespalib::string &term_in) : SimpleLeafBlueprint(spec_in), spec(spec_in), term(term_in) { @@ -78,7 +78,7 @@ struct MockBlueprint : SimpleLeafBlueprint { SearchIterator::UP createLeafSearch(const TermFieldMatchDataArray &tfmda, bool strict) const override { if (postings_fetched) { - EXPECT_EQUAL(postings_strict.isStrict(), strict); + EXPECT_EQUAL(postings_strict, strict); } return std::make_unique<MockSearch>(spec, term, strict, tfmda, postings_fetched); } @@ -86,7 +86,7 @@ struct MockBlueprint : SimpleLeafBlueprint { return create_default_filter(strict, constraint); } void fetchPostings(const search::queryeval::ExecuteInfo &execInfo) override { - postings_strict = execInfo; + postings_strict = execInfo.is_strict(); postings_fetched = true; } }; diff --git a/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp b/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp index 815561dc94c..8b223c3ef3a 100644 --- a/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp +++ b/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp @@ -8,6 +8,7 @@ #include <vespa/searchlib/fef/test/indexenvironment.h> #include <vespa/searchlib/fef/test/queryenvironment.h> #include <vespa/vespalib/util/testclock.h> +#include <vespa/vespalib/util/simple_thread_bundle.h> #include <vespa/vespalib/gtest/gtest.h> #include <vespa/vespalib/objects/nbostream.h> @@ -34,13 +35,14 @@ public: class RequestContextTest : public ::testing::Test { private: - vespalib::TestClock _clock; - vespalib::Doom _doom; - MyAttributeContext _attr_ctx; - IndexEnvironment _index_env; - QueryEnvironment _query_env; - RequestContext _request_ctx; - Value::UP _query_tensor; + vespalib::TestClock _clock; + vespalib::Doom _doom; + vespalib::SimpleThreadBundle _thread_bundle; + MyAttributeContext _attr_ctx; + IndexEnvironment _index_env; + QueryEnvironment _query_env; + RequestContext _request_ctx; + Value::UP _query_tensor; void insert_tensor_in_properties(const vespalib::string& tensor_name, const Value& tensor_value) { vespalib::nbostream stream; @@ -52,10 +54,11 @@ public: RequestContextTest() : _clock(), _doom(_clock.clock(), vespalib::steady_time(), vespalib::steady_time(), false), + _thread_bundle(1), _attr_ctx(), _index_env(), _query_env(&_index_env), - _request_ctx(_doom, _attr_ctx, _query_env, _query_env.getObjectStore(), AttributeBlueprintParams(), nullptr), + _request_ctx(_doom, _thread_bundle, _attr_ctx, _query_env, _query_env.getObjectStore(), AttributeBlueprintParams(), nullptr), _query_tensor(SimpleValue::from_spec(TensorSpec("tensor(x[2])") .add({{"x", 0}}, 3).add({{"x", 1}}, 5))) { diff --git a/searchcore/src/vespa/searchcore/proton/matching/attribute_limiter.cpp b/searchcore/src/vespa/searchcore/proton/matching/attribute_limiter.cpp index d66f5420990..51d96c5a843 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/attribute_limiter.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/attribute_limiter.cpp @@ -100,7 +100,8 @@ AttributeLimiter::create_match_data(size_t want_hits, size_t max_group_size, dou field.add(FieldSpec(_attribute_name, my_field_id, my_handle)); _blueprint = _searchable_attributes.createBlueprint(_requestContext, field, node); //TODO use_estimate must be switched to true quite soon - auto execInfo = ExecuteInfo::create(strictSearch, strictSearch ? 1.0 : hit_rate, &_requestContext.getDoom(), true, false); + auto execInfo = ExecuteInfo::create(strictSearch, strictSearch ? 1.0 : hit_rate, &_requestContext.getDoom(), + _requestContext.thread_bundle(), true, false); _blueprint->fetchPostings(execInfo); _estimatedHits.store(_blueprint->getState().estimate().estHits, std::memory_order_relaxed); _blueprint->freeze(); diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp index ace0f8642b9..527f7702a7c 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp @@ -182,7 +182,8 @@ MatchToolsFactory(QueryLimiter & queryLimiter, _query(), _match_limiter(), _queryEnv(indexEnv, attributeContext, rankProperties, searchContext.getIndexes()), - _requestContext(doom, attributeContext, _queryEnv, _queryEnv.getObjectStore(), _attribute_blueprint_params, metaStoreReadGuard), + _requestContext(doom, thread_bundle, attributeContext, _queryEnv, _queryEnv.getObjectStore(), + _attribute_blueprint_params, metaStoreReadGuard), _mdl(), _rankSetup(rankSetup), _featureOverrides(featureOverrides), @@ -207,14 +208,13 @@ MatchToolsFactory(QueryLimiter & queryLimiter, double hitRate = std::min(1.0, double(maxNumHits)/double(searchContext.getDocIdLimit())); bool create_postinglist_when_non_strict = CreatePostingListWhenNonStrict::check(_queryEnv.getProperties(), rankSetup.create_postinglist_when_non_strict()); bool use_estimate_for_fetch_postings = UseEstimateForFetchPostings::check(_queryEnv.getProperties(), rankSetup.use_estimate_for_fetch_postings()); - _query.fetchPostings(ExecuteInfo::create(is_search, hitRate, &_requestContext.getDoom(), + _query.fetchPostings(ExecuteInfo::create(is_search, hitRate, &_requestContext.getDoom(), thread_bundle, create_postinglist_when_non_strict, use_estimate_for_fetch_postings)); if (is_search) { - _query.handle_global_filter(_requestContext.getDoom(), searchContext.getDocIdLimit(), + _query.handle_global_filter(_requestContext, searchContext.getDocIdLimit(), _attribute_blueprint_params.global_filter_lower_limit, _attribute_blueprint_params.global_filter_upper_limit, - thread_bundle, trace, create_postinglist_when_non_strict, - use_estimate_for_fetch_postings); + trace, create_postinglist_when_non_strict, use_estimate_for_fetch_postings); } _query.freeze(); trace.addEvent(5, "Prepare shared state for multi-threaded rank executors"); diff --git a/searchcore/src/vespa/searchcore/proton/matching/query.cpp b/searchcore/src/vespa/searchcore/proton/matching/query.cpp index 42db9ab65ab..027625a2a57 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/query.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/query.cpp @@ -211,12 +211,14 @@ Query::fetchPostings(const ExecuteInfo & executeInfo) } void -Query::handle_global_filter(const vespalib::Doom & doom, uint32_t docid_limit, +Query::handle_global_filter(const IRequestContext & requestContext, uint32_t docid_limit, double global_filter_lower_limit, double global_filter_upper_limit, - vespalib::ThreadBundle &thread_bundle, search::engine::Trace& trace, + search::engine::Trace& trace, bool create_postinglist_when_non_strict, bool use_estimate_for_fetch_postings) { - if (!handle_global_filter(*_blueprint, docid_limit, global_filter_lower_limit, global_filter_upper_limit, thread_bundle, &trace)) { + if (!handle_global_filter(*_blueprint, docid_limit, global_filter_lower_limit, global_filter_upper_limit, + requestContext.thread_bundle(), &trace)) + { return; } // optimized order may change after accounting for global filter: @@ -224,7 +226,8 @@ Query::handle_global_filter(const vespalib::Doom & doom, uint32_t docid_limit, _blueprint = Blueprint::optimize(std::move(_blueprint)); LOG(debug, "blueprint after handle_global_filter:\n%s\n", _blueprint->asString().c_str()); // strictness may change if optimized order changed: - fetchPostings(ExecuteInfo::create(true, 1.0, &doom, create_postinglist_when_non_strict, use_estimate_for_fetch_postings)); + fetchPostings(ExecuteInfo::create(true, 1.0, &requestContext.getDoom(), requestContext.thread_bundle(), + create_postinglist_when_non_strict, use_estimate_for_fetch_postings)); } bool diff --git a/searchcore/src/vespa/searchcore/proton/matching/query.h b/searchcore/src/vespa/searchcore/proton/matching/query.h index c3ea2c5e664..97402d766ea 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/query.h +++ b/searchcore/src/vespa/searchcore/proton/matching/query.h @@ -24,14 +24,16 @@ private: using Blueprint = search::queryeval::Blueprint; using GlobalFilter = search::queryeval::GlobalFilter; using ExecuteInfo = search::queryeval::ExecuteInfo; - search::query::Node::UP _query_tree; - Blueprint::UP _blueprint; - Blueprint::UP _whiteListBlueprint; - std::vector<search::common::GeoLocationSpec> _locations; + using IRequestContext = search::queryeval::IRequestContext; + using GeoLocationSpec = search::common::GeoLocationSpec; + search::query::Node::UP _query_tree; + Blueprint::UP _blueprint; + Blueprint::UP _whiteListBlueprint; + std::vector<GeoLocationSpec> _locations; public: /** Convenience typedef. */ - using GeoLocationSpecPtrs = std::vector<const search::common::GeoLocationSpec *>; + using GeoLocationSpecPtrs = std::vector<const GeoLocationSpec *>; Query(); ~Query(); @@ -89,7 +91,7 @@ public: * @param context search context * @param mdl match data layout **/ - void reserveHandles(const search::queryeval::IRequestContext & requestContext, + void reserveHandles(const IRequestContext & requestContext, ISearchContext &context, search::fef::MatchDataLayout &mdl); @@ -104,9 +106,9 @@ public: void optimize(); void fetchPostings(const ExecuteInfo & executeInfo) ; - void handle_global_filter(const vespalib::Doom & doom, uint32_t docid_limit, + void handle_global_filter(const IRequestContext & requestContext, uint32_t docid_limit, double global_filter_lower_limit, double global_filter_upper_limit, - vespalib::ThreadBundle &thread_bundle, search::engine::Trace& trace, + search::engine::Trace& trace, bool create_postinglist_when_non_strict, bool use_estimate_for_fetch_postings); /** diff --git a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp index 41da21b1583..9663a3ebd8b 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp @@ -18,12 +18,15 @@ namespace proton { using search::attribute::IAttributeVector; -RequestContext::RequestContext(const Doom & doom, IAttributeContext & attributeContext, +RequestContext::RequestContext(const Doom & doom, + vespalib::ThreadBundle & thread_bundle_in, + IAttributeContext & attributeContext, const search::fef::IQueryEnvironment& query_env, search::fef::IObjectStore& shared_store, const search::attribute::AttributeBlueprintParams& attribute_blueprint_params, const MetaStoreReadGuardSP * metaStoreReadGuard) : _doom(doom), + _thread_bundle(thread_bundle_in), _attributeContext(attributeContext), _query_env(query_env), _shared_store(shared_store), diff --git a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h index 5596826f7da..c2721fd18ed 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h +++ b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h @@ -23,6 +23,7 @@ public: using IAttributeFunctor = search::attribute::IAttributeFunctor; using Doom = vespalib::Doom; RequestContext(const Doom& softDoom, + vespalib::ThreadBundle & threadBundle, IAttributeContext& attributeContext, const search::fef::IQueryEnvironment& query_env, search::fef::IObjectStore& shared_store, @@ -30,6 +31,7 @@ public: const MetaStoreReadGuardSP * metaStoreReadGuard); const Doom & getDoom() const override { return _doom; } + vespalib::ThreadBundle & thread_bundle() const override { return _thread_bundle; } const search::attribute::IAttributeVector *getAttribute(const vespalib::string &name) const override; void asyncForAttribute(const vespalib::string &name, std::unique_ptr<IAttributeFunctor> func) const override; @@ -47,6 +49,7 @@ public: private: const Doom _doom; + vespalib::ThreadBundle & _thread_bundle; IAttributeContext & _attributeContext; const search::fef::IQueryEnvironment & _query_env; search::fef::IObjectStore & _shared_store; diff --git a/searchcore/src/vespa/searchcorespi/index/warmupindexcollection.cpp b/searchcore/src/vespa/searchcorespi/index/warmupindexcollection.cpp index 46dfcda119d..5d5348de52a 100644 --- a/searchcore/src/vespa/searchcorespi/index/warmupindexcollection.cpp +++ b/searchcore/src/vespa/searchcorespi/index/warmupindexcollection.cpp @@ -35,9 +35,10 @@ class WarmupRequestContext : public IRequestContext { using IAttributeVector = search::attribute::IAttributeVector; using AttributeBlueprintParams = search::attribute::AttributeBlueprintParams; public: - WarmupRequestContext(const vespalib::Clock & clock); + explicit WarmupRequestContext(const vespalib::Clock & clock); ~WarmupRequestContext() override; const vespalib::Doom & getDoom() const override { return _doom; } + vespalib::ThreadBundle & thread_bundle() const override { return vespalib::ThreadBundle::trivial(); } const IAttributeVector *getAttribute(const vespalib::string &) const override { return nullptr; } const IAttributeVector *getAttributeStableEnum(const vespalib::string &) const override { return nullptr; } const vespalib::eval::Value* get_query_tensor(const vespalib::string&) const override; @@ -182,7 +183,7 @@ WarmupIndexCollection::fireWarmup(Task::UP task) bool WarmupIndexCollection::handledBefore(uint32_t fieldId, const Node &term) { - const StringBase * sb(dynamic_cast<const StringBase *>(&term)); + const auto * sb(dynamic_cast<const StringBase *>(&term)); if (sb != nullptr) { const vespalib::string & s = sb->getTerm(); std::lock_guard<std::mutex> guard(_lock); diff --git a/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp b/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp index eea6c898aa2..7d994ee4cd6 100644 --- a/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp @@ -39,13 +39,16 @@ struct WeightOrder { }; struct RememberExecuteInfo : public MyLeaf { - ExecuteInfo executeInfo; + bool is_strict; + double hit_rate; - using MyLeaf::MyLeaf; + RememberExecuteInfo() : MyLeaf(), is_strict(false), hit_rate(0.0) {} + RememberExecuteInfo(FieldSpecBaseList fields) : MyLeaf(std::move(fields)), is_strict(false), hit_rate(0.0) {} void fetchPostings(const ExecuteInfo &execInfo) override { LeafBlueprint::fetchPostings(execInfo); - executeInfo = execInfo; + is_strict = execInfo.is_strict(); + hit_rate = execInfo.hit_rate(); } }; @@ -134,11 +137,11 @@ TEST("test And propagates updated histestimate") { EXPECT_EQUAL(3u, bp->childCnt()); for (uint32_t i = 0; i < bp->childCnt(); i++) { const auto & child = dynamic_cast<const RememberExecuteInfo &>(bp->getChild(i)); - EXPECT_EQUAL((i == 0), child.executeInfo.isStrict()); + EXPECT_EQUAL((i == 0), child.is_strict); } - EXPECT_EQUAL(1.0, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(0)).executeInfo.hitRate()); - EXPECT_EQUAL(1.0/250, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(1)).executeInfo.hitRate()); - EXPECT_EQUAL(1.0/(250*25), dynamic_cast<const RememberExecuteInfo &>(bp->getChild(2)).executeInfo.hitRate()); + EXPECT_EQUAL(1.0, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(0)).hit_rate); + EXPECT_EQUAL(1.0/250, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(1)).hit_rate); + EXPECT_EQUAL(1.0/(250*25), dynamic_cast<const RememberExecuteInfo &>(bp->getChild(2)).hit_rate); } TEST("test Or propagates updated histestimate") { @@ -154,12 +157,12 @@ TEST("test Or propagates updated histestimate") { EXPECT_EQUAL(4u, bp->childCnt()); for (uint32_t i = 0; i < bp->childCnt(); i++) { const auto & child = dynamic_cast<const RememberExecuteInfo &>(bp->getChild(i)); - EXPECT_TRUE(child.executeInfo.isStrict()); + EXPECT_TRUE(child.is_strict); } - EXPECT_EQUAL(1.0, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(0)).executeInfo.hitRate()); - EXPECT_APPROX(0.5, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(1)).executeInfo.hitRate(), 1e-6); - EXPECT_APPROX(0.5*3.0/5.0, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(2)).executeInfo.hitRate(), 1e-6); - EXPECT_APPROX(0.5*3.0*42.0/(5.0*50.0), dynamic_cast<const RememberExecuteInfo &>(bp->getChild(3)).executeInfo.hitRate(), 1e-6); + EXPECT_EQUAL(1.0, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(0)).hit_rate); + EXPECT_APPROX(0.5, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(1)).hit_rate, 1e-6); + EXPECT_APPROX(0.5*3.0/5.0, dynamic_cast<const RememberExecuteInfo &>(bp->getChild(2)).hit_rate, 1e-6); + EXPECT_APPROX(0.5*3.0*42.0/(5.0*50.0), dynamic_cast<const RememberExecuteInfo &>(bp->getChild(3)).hit_rate, 1e-6); } TEST("test And Blueprint") { diff --git a/searchlib/src/tests/queryeval/blueprint/mysearch.h b/searchlib/src/tests/queryeval/blueprint/mysearch.h index 6cfc7a04368..db7dd2adae6 100644 --- a/searchlib/src/tests/queryeval/blueprint/mysearch.h +++ b/searchlib/src/tests/queryeval/blueprint/mysearch.h @@ -58,10 +58,10 @@ public: if (!_isLeaf) { ok &= (_md == &md); } - for (size_t i = 0; i < _children.size(); ++i) { - MySearch *child = dynamic_cast<MySearch *>(_children[i].get()); - ok &= (child != 0); - if (child != 0) { + for (const auto & my_search : _children) { + auto *child = dynamic_cast<MySearch *>(my_search.get()); + ok &= (child != nullptr); + if (child != nullptr) { ok &= child->verifyAndInferImpl(md); } } @@ -80,8 +80,8 @@ public: } static bool verifyAndInfer(SearchIterator *search, MatchData &md) { - MySearch *self = dynamic_cast<MySearch *>(search); - if (self == 0) { + auto *self = dynamic_cast<MySearch *>(search); + if (self == nullptr) { return false; } else { return self->verifyAndInferImpl(md); diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp index 42b2cca06f7..99d3ba3f7aa 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp @@ -163,7 +163,7 @@ AttributeWeightedSetBlueprint::createFilterSearch(bool strict, FilterConstraint) void AttributeWeightedSetBlueprint::fetchPostings(const queryeval::ExecuteInfo &execInfo) { - if (execInfo.isStrict()) { + if (execInfo.is_strict()) { for (auto * context : _contexts) { context->fetchPostings(execInfo); } diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp index b49ec1bfc9e..b27a67e893b 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp @@ -308,7 +308,7 @@ void ImportedSearchContext::fetchPostings(const queryeval::ExecuteInfo &execInfo) { if (!_searchCacheLookup) { _target_search_context->fetchPostings(execInfo); - if (!_merger.merge_done() && (execInfo.isStrict() || (_target_attribute.getIsFastSearch() && execInfo.hitRate() > 0.01))) { + if (!_merger.merge_done() && (execInfo.is_strict() || (_target_attribute.getIsFastSearch() && execInfo.hit_rate() > 0.01))) { makeMergedPostings(_target_attribute.getIsFilter()); considerAddSearchCacheEntry(); } diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h index eefb2ea77d5..a291318e837 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h +++ b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h @@ -318,7 +318,7 @@ bool StringPostingSearchContext<BaseSC, AttrT, DataT>::use_posting_lists_when_non_strict(const queryeval::ExecuteInfo& info) const { if (this->isFuzzy()) { - uint32_t exp_doc_hits = this->_docIdLimit * info.hitRate(); + uint32_t exp_doc_hits = this->_docIdLimit * info.hit_rate(); constexpr uint32_t fuzzy_use_posting_lists_doc_limit = 10000; /** * The above constant was derived after a query latency experiment with fuzzy matching @@ -441,7 +441,7 @@ NumericPostingSearchContext<BaseSC, AttrT, DataT>::use_posting_lists_when_non_st constexpr float lookup_match_constant = 5.0; constexpr float posting_list_merge_constant = 1.0; - uint32_t exp_doc_hits = this->_docIdLimit * info.hitRate(); + uint32_t exp_doc_hits = this->_docIdLimit * info.hit_rate(); float avg_values_per_document = static_cast<float>(this->_numValues) / static_cast<float>(this->_docIdLimit); float lookup_match_cost = exp_doc_hits * avg_values_per_document * lookup_match_constant; float posting_list_cost = this->estimated_hits_in_range() * posting_list_merge_constant; diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp index 3ff5c749899..ecdfad433ee 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp +++ b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp @@ -62,8 +62,7 @@ void PostingListSearchContextT<DataT>::fillArray() { for (auto it(_lowerDictItr); it != _upperDictItr; ++it) { - _merger.addToArray(PostingListTraverser<PostingStore>(_posting_store, - it.getData().load_acquire())); + _merger.addToArray(PostingListTraverser<PostingStore>(_posting_store, it.getData().load_acquire())); } _merger.merge(); } @@ -110,7 +109,7 @@ PostingListSearchContextT<DataT>::fetchPostings(const queryeval::ExecuteInfo & e // The threshold for when to use array merging is therefore 0.0025 (0.08 / 32). constexpr float threshold_for_using_array = 0.0025; if (!_merger.merge_done() && _uniqueValues >= 2u && this->_dictionary.get_has_btree_dictionary()) { - if (execInfo.isStrict() || use_posting_lists_when_non_strict(execInfo)) { + if (execInfo.is_strict() || use_posting_lists_when_non_strict(execInfo)) { size_t sum = estimated_hits_in_range(); if (sum < (_docIdLimit * threshold_for_using_array)) { _merger.reserveArray(_uniqueValues, sum); diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index 16a2ba64fa7..043b006d3bd 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -628,10 +628,10 @@ IntermediateBlueprint::visitMembers(vespalib::ObjectVisitor &visitor) const void IntermediateBlueprint::fetchPostings(const ExecuteInfo &execInfo) { - double nextHitRate = execInfo.hitRate(); + double nextHitRate = execInfo.hit_rate(); for (size_t i = 0; i < _children.size(); ++i) { Blueprint & child = *_children[i]; - child.fetchPostings(ExecuteInfo::create(execInfo.isStrict() && inheritStrict(i), nextHitRate, execInfo)); + child.fetchPostings(ExecuteInfo::create(execInfo.is_strict() && inheritStrict(i), nextHitRate, execInfo)); nextHitRate = computeNextHitRate(child, nextHitRate, execInfo.use_estimate_for_fetch_postings()); } } diff --git a/searchlib/src/vespa/searchlib/queryeval/executeinfo.cpp b/searchlib/src/vespa/searchlib/queryeval/executeinfo.cpp index ac3dfcc3b20..858cb92331a 100644 --- a/searchlib/src/vespa/searchlib/queryeval/executeinfo.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/executeinfo.cpp @@ -4,7 +4,7 @@ namespace search::queryeval { -const ExecuteInfo ExecuteInfo::TRUE(true, 1.0, nullptr, true, true); -const ExecuteInfo ExecuteInfo::FALSE(false, 1.0, nullptr, true, true); +const ExecuteInfo ExecuteInfo::TRUE(true, 1.0, nullptr, vespalib::ThreadBundle::trivial(), true, true); +const ExecuteInfo ExecuteInfo::FALSE(false, 1.0, nullptr, vespalib::ThreadBundle::trivial(), true, true); } diff --git a/searchlib/src/vespa/searchlib/queryeval/executeinfo.h b/searchlib/src/vespa/searchlib/queryeval/executeinfo.h index 01b3ddfd182..3300a2aea4d 100644 --- a/searchlib/src/vespa/searchlib/queryeval/executeinfo.h +++ b/searchlib/src/vespa/searchlib/queryeval/executeinfo.h @@ -3,6 +3,7 @@ #pragma once #include <vespa/vespalib/util/doom.h> +#include <vespa/vespalib/util/thread_bundle.h> namespace search::queryeval { @@ -12,26 +13,27 @@ namespace search::queryeval { */ class ExecuteInfo { public: - ExecuteInfo() noexcept : ExecuteInfo(false, 1.0, nullptr, true, true) { } - bool isStrict() const noexcept { return _strict; } + ExecuteInfo() noexcept : ExecuteInfo(false, 1.0, nullptr, vespalib::ThreadBundle::trivial(), true, true) { } + bool is_strict() const noexcept { return _strict; } bool create_postinglist_when_non_strict() const noexcept { return _create_postinglist_when_non_strict; } bool use_estimate_for_fetch_postings() const noexcept { return _use_estimate_for_fetch_postings; } - double hitRate() const noexcept { return _hitRate; } + double hit_rate() const noexcept { return _hitRate; } bool soft_doom() const noexcept { return _doom && _doom->soft_doom(); } - const vespalib::Doom * getDoom() const { return _doom; } + vespalib::ThreadBundle & thread_bundle() const noexcept { return _thread_bundle; } + static const ExecuteInfo TRUE; static const ExecuteInfo FALSE; static ExecuteInfo create(bool strict, const ExecuteInfo & org) noexcept { return create(strict, org._hitRate, org); } static ExecuteInfo create(bool strict, double hitRate, const ExecuteInfo & org) noexcept { - return {strict, hitRate, org.getDoom(), org.create_postinglist_when_non_strict(), org.use_estimate_for_fetch_postings()}; + return {strict, hitRate, org._doom, org.thread_bundle(), org.create_postinglist_when_non_strict(), org.use_estimate_for_fetch_postings()}; } - static ExecuteInfo create(bool strict, double hitRate, const vespalib::Doom * doom, bool postinglist_when_non_strict, - bool use_estimate_for_fetch_postings) noexcept + static ExecuteInfo create(bool strict, double hitRate, const vespalib::Doom * doom, vespalib::ThreadBundle & thread_bundle_in, + bool postinglist_when_non_strict, bool use_estimate_for_fetch_postings) noexcept { - return {strict, hitRate, doom, postinglist_when_non_strict, use_estimate_for_fetch_postings}; + return {strict, hitRate, doom, thread_bundle_in, postinglist_when_non_strict, use_estimate_for_fetch_postings}; } static ExecuteInfo createForTest(bool strict) noexcept { return createForTest(strict, 1.0); @@ -40,22 +42,24 @@ public: return createForTest(strict, hitRate, nullptr); } static ExecuteInfo createForTest(bool strict, double hitRate, const vespalib::Doom * doom) noexcept { - return create(strict, hitRate, doom, true, true); + return create(strict, hitRate, doom, vespalib::ThreadBundle::trivial(), true, true); } private: - ExecuteInfo(bool strict, double hitRate_in, const vespalib::Doom * doom, bool postinglist_when_non_strict, - bool use_estimate_for_fetch_postings) noexcept + ExecuteInfo(bool strict, double hitRate_in, const vespalib::Doom * doom, vespalib::ThreadBundle & thread_bundle_in, + bool postinglist_when_non_strict, bool use_estimate_for_fetch_postings) noexcept : _doom(doom), + _thread_bundle(thread_bundle_in), _hitRate(hitRate_in), _strict(strict), _create_postinglist_when_non_strict(postinglist_when_non_strict), _use_estimate_for_fetch_postings(use_estimate_for_fetch_postings) { } - const vespalib::Doom * _doom; - double _hitRate; - bool _strict; - bool _create_postinglist_when_non_strict; - bool _use_estimate_for_fetch_postings; + const vespalib::Doom * _doom; + vespalib::ThreadBundle & _thread_bundle; + double _hitRate; + bool _strict; + bool _create_postinglist_when_non_strict; + bool _use_estimate_for_fetch_postings; }; } diff --git a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h index e536727169a..0122352656e 100644 --- a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h +++ b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h @@ -11,6 +11,7 @@ #include <vespa/searchlib/attribute/attributevector.h> #include <vespa/searchlib/attribute/attribute_blueprint_params.h> #include <vespa/vespalib/util/doom.h> +#include <vespa/vespalib/util/thread_bundle.h> #include <limits> namespace vespalib { class TestClock; } @@ -25,6 +26,7 @@ public: vespalib::steady_time hard=vespalib::steady_time::max()); ~FakeRequestContext() override; const vespalib::Doom & getDoom() const override { return _doom; } + vespalib::ThreadBundle & thread_bundle() const override { return vespalib::ThreadBundle::trivial(); } const attribute::IAttributeVector *getAttribute(const vespalib::string &name) const override { return _attributeContext ? _attributeContext->getAttribute(name) diff --git a/searchlib/src/vespa/searchlib/queryeval/irequestcontext.h b/searchlib/src/vespa/searchlib/queryeval/irequestcontext.h index f4c3ae547f0..ad25385be4b 100644 --- a/searchlib/src/vespa/searchlib/queryeval/irequestcontext.h +++ b/searchlib/src/vespa/searchlib/queryeval/irequestcontext.h @@ -8,7 +8,10 @@ namespace search::attribute { struct AttributeBlueprintParams; } namespace search::attribute { class IAttributeVector; } namespace vespalib::eval { struct Value; } -namespace vespalib { class Doom; } +namespace vespalib { + class Doom; + struct ThreadBundle; +} namespace search::queryeval { @@ -26,6 +29,10 @@ public: * @return time of soft doom. */ virtual const vespalib::Doom & getDoom() const = 0; + /** + * Provide an optional thread bundle that can be used for multithreading parts of the query. + */ + virtual vespalib::ThreadBundle & thread_bundle() const = 0; /** * Provide access to attributevectors diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp index eb1d217ad6a..f0c75173671 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp @@ -61,7 +61,7 @@ SameElementBlueprint::fetchPostings(const ExecuteInfo &execInfo) if (_terms.empty()) return; _terms[0]->fetchPostings(execInfo); double estimate = execInfo.use_estimate_for_fetch_postings() ? _terms[0]->hit_ratio() : _terms[0]->estimate(); - double hit_rate = execInfo.hitRate() * estimate; + double hit_rate = execInfo.hit_rate() * estimate; for (size_t i = 1; i < _terms.size(); ++i) { Blueprint & term = *_terms[i]; term.fetchPostings(ExecuteInfo::create(false, hit_rate, execInfo)); diff --git a/vespalib/src/vespa/vespalib/util/doom.cpp b/vespalib/src/vespa/vespalib/util/doom.cpp index 01ad3aa4e97..227d43ee4c4 100644 --- a/vespalib/src/vespa/vespalib/util/doom.cpp +++ b/vespalib/src/vespa/vespalib/util/doom.cpp @@ -5,7 +5,7 @@ namespace vespalib { Doom::Doom(const Clock &clock, steady_time softDoom, - steady_time hardDoom, bool explicitSoftDoom) + steady_time hardDoom, bool explicitSoftDoom) noexcept : _clock(clock), _softDoom(softDoom), _hardDoom(hardDoom), diff --git a/vespalib/src/vespa/vespalib/util/doom.h b/vespalib/src/vespa/vespalib/util/doom.h index cbac7e2cfbd..a175bbd20df 100644 --- a/vespalib/src/vespa/vespalib/util/doom.h +++ b/vespalib/src/vespa/vespalib/util/doom.h @@ -8,17 +8,17 @@ namespace vespalib { class Doom { public: - Doom(const Clock &clock, steady_time doom) + Doom(const Clock &clock, steady_time doom) noexcept : Doom(clock, doom, doom, false) {} Doom(const Clock &clock, steady_time softDoom, - steady_time hardDoom, bool explicitSoftDoom); + steady_time hardDoom, bool explicitSoftDoom) noexcept; - bool soft_doom() const { return (_clock.getTimeNS() > _softDoom); } - bool hard_doom() const { return (_clock.getTimeNS() > _hardDoom); } - duration soft_left() const { return _softDoom - _clock.getTimeNS(); } - duration hard_left() const { return _hardDoom - _clock.getTimeNS(); } - bool isExplicitSoftDoom() const { return _isExplicitSoftDoom; } + bool soft_doom() const noexcept { return (_clock.getTimeNS() > _softDoom); } + bool hard_doom() const noexcept { return (_clock.getTimeNS() > _hardDoom); } + duration soft_left() const noexcept { return _softDoom - _clock.getTimeNS(); } + duration hard_left() const noexcept { return _hardDoom - _clock.getTimeNS(); } + bool isExplicitSoftDoom() const noexcept { return _isExplicitSoftDoom; } private: const Clock &_clock; steady_time _softDoom; diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp index 3b56a2bd297..5909c2df8c3 100644 --- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp +++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp @@ -14,33 +14,33 @@ namespace { struct SignalHook : Runnable { Signal &signal; - SignalHook(Signal &s) : signal(s) {} + explicit SignalHook(Signal &s) noexcept : signal(s) {} void run() override { signal.send(); } }; struct BroadcastHook : Runnable { Signal &signal; - BroadcastHook(Signal &s) : signal(s) {} + explicit BroadcastHook(Signal &s) noexcept : signal(s) {} void run() override { signal.broadcast(); } }; struct PartHook : Runnable { Part part; - PartHook(const Part &p) : part(p) {} + explicit PartHook(const Part &p) noexcept : part(p) {} void run() override { part.perform(); } }; struct HookPair : Runnable { Runnable::UP first; Runnable::UP second; - HookPair(Runnable::UP f, Runnable::UP s) : first(std::move(f)), second(std::move(s)) {} + HookPair(Runnable::UP f, Runnable::UP s) noexcept : first(std::move(f)), second(std::move(s)) {} void run() override { first->run(); second->run(); } }; -Runnable::UP wrap(Runnable *runnable) { +Runnable::UP wrap(Runnable *runnable) noexcept { return Runnable::UP(runnable); } diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h index 9a5ae9dcf6f..9fccbef1f9a 100644 --- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h +++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h @@ -21,7 +21,7 @@ struct Work { Runnable* const* targets; size_t cnt; CountDownLatch *latch; - Work() : targets(nullptr), cnt(0), latch(nullptr) {} + Work() noexcept : targets(nullptr), cnt(0), latch(nullptr) {} }; /** @@ -30,9 +30,9 @@ struct Work { struct Part { const Work &work; size_t offset; - Part(const Work &w, size_t o) : work(w), offset(o) {} + Part(const Work &w, size_t o) noexcept : work(w), offset(o) {} bool valid() const noexcept { return (offset < work.cnt); } - void perform() { + void perform() const { if (valid()) { work.targets[offset]->run(); } diff --git a/vespalib/src/vespa/vespalib/util/thread_bundle.h b/vespalib/src/vespa/vespalib/util/thread_bundle.h index 72f9a0ce368..6a9bbeea0d1 100644 --- a/vespalib/src/vespa/vespalib/util/thread_bundle.h +++ b/vespalib/src/vespa/vespalib/util/thread_bundle.h @@ -64,7 +64,7 @@ struct ThreadBundle { /** * Empty virtual destructor to enable subclassing. **/ - virtual ~ThreadBundle() {} + virtual ~ThreadBundle() = default; // a thread bundle that can only run things in the current thread. static ThreadBundle &trivial(); |