diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-05-12 13:28:36 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2023-05-12 13:28:36 +0000 |
commit | 2b9d5158ffd67d49bc23ea25044f62c0c36b2070 (patch) | |
tree | b0ea03fbad1468bc242789ddba1fa786c61da9a0 /searchlib | |
parent | 579ce1c7cee8880426b76fc24ad14e02282d880b (diff) |
Use SmallVector to avoid allocation in the common case.
Diffstat (limited to 'searchlib')
10 files changed, 57 insertions, 34 deletions
diff --git a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp index 26fbed81146..d7a854e0afc 100644 --- a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp @@ -101,7 +101,8 @@ struct WS { FakeRequestContext requestContext(&ac); MatchData::UP md = layout.createMatchData(); Node::UP node = createNode(); - FieldSpecList fields = FieldSpecList().add(FieldSpec(field, fieldId, handle)); + FieldSpecList fields; + fields.add(FieldSpec(field, fieldId, handle)); queryeval::Blueprint::UP bp = searchable.createBlueprint(requestContext, fields, *node); bp->fetchPostings(queryeval::ExecuteInfo::create(strict)); SearchIterator::UP sb = bp->createSearch(*md, strict); @@ -113,7 +114,8 @@ struct WS { FakeRequestContext requestContext(&ac); MatchData::UP md = layout.createMatchData(); Node::UP node = createNode(); - FieldSpecList fields = FieldSpecList().add(FieldSpec(field, fieldId, handle)); + FieldSpecList fields; + fields.add(FieldSpec(field, fieldId, handle)); queryeval::Blueprint::UP bp = searchable.createBlueprint(requestContext, fields, *node); bp->fetchPostings(queryeval::ExecuteInfo::create(strict)); SearchIterator::UP sb = bp->createSearch(*md, strict); diff --git a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp index cd61c4c9669..675b137f1a2 100644 --- a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp @@ -136,7 +136,7 @@ public: //----------------------------------------------------------------------------- struct MyTerm : SimpleLeafBlueprint { - MyTerm(FieldSpecBaseList fields, uint32_t hitEstimate) : SimpleLeafBlueprint(std::move(fields)) { + MyTerm(FieldSpecBase field, uint32_t hitEstimate) : SimpleLeafBlueprint(field) { setEstimate(HitEstimate(hitEstimate, false)); } SearchIterator::UP createLeafSearch(const search::fef::TermFieldMatchDataArray &, bool) const override { @@ -311,13 +311,13 @@ TEST("testHitEstimateCalculation") TEST("testHitEstimatePropagation") { - MyLeaf *leaf1 = new MyLeaf(FieldSpecBaseList()); + MyLeaf *leaf1 = new MyLeaf(); leaf1->estimate(10); - MyLeaf *leaf2 = new MyLeaf(FieldSpecBaseList()); + MyLeaf *leaf2 = new MyLeaf(); leaf2->estimate(20); - MyLeaf *leaf3 = new MyLeaf(FieldSpecBaseList()); + MyLeaf *leaf3 = new MyLeaf(); leaf3->estimate(30); MyOr *parent = new MyOr(); @@ -727,7 +727,7 @@ struct BlueprintFixture { MyOr _blueprint; BlueprintFixture() : _blueprint() { - _blueprint.add(new MyTerm(FieldSpecBaseList(FieldSpecBase(5, 7)), 9)); + _blueprint.add(new MyTerm(FieldSpecBase(5, 7), 9)); } }; @@ -767,9 +767,9 @@ TEST("requireThatDocIdLimitInjectionWorks") } TEST("Control object sizes") { - EXPECT_EQUAL(40u, sizeof(Blueprint::State)); + EXPECT_EQUAL(32u, sizeof(Blueprint::State)); EXPECT_EQUAL(32u, sizeof(Blueprint)); - EXPECT_EQUAL(72u, sizeof(LeafBlueprint)); + EXPECT_EQUAL(64u, sizeof(LeafBlueprint)); } TEST_MAIN() { diff --git a/searchlib/src/tests/queryeval/blueprint/mysearch.h b/searchlib/src/tests/queryeval/blueprint/mysearch.h index 6e8b6fa9adc..4fa53443123 100644 --- a/searchlib/src/tests/queryeval/blueprint/mysearch.h +++ b/searchlib/src/tests/queryeval/blueprint/mysearch.h @@ -110,9 +110,12 @@ public: SearchIterator::UP createLeafSearch(const TFMDA &tfmda, bool strict) const override { - return SearchIterator::UP(new MySearch("leaf", tfmda, strict)); + return std::make_unique<MySearch>("leaf", tfmda, strict); } + MyLeaf() + : SimpleLeafBlueprint(), _got_global_filter(false) + {} MyLeaf(FieldSpecBaseList fields) : SimpleLeafBlueprint(std::move(fields)), _got_global_filter(false) {} diff --git a/searchlib/src/tests/queryeval/dot_product/dot_product_test.cpp b/searchlib/src/tests/queryeval/dot_product/dot_product_test.cpp index 0fef721a6fa..b90f009e4b7 100644 --- a/searchlib/src/tests/queryeval/dot_product/dot_product_test.cpp +++ b/searchlib/src/tests/queryeval/dot_product/dot_product_test.cpp @@ -70,7 +70,8 @@ struct DP { } FakeRequestContext requestContext; Node::UP node = createNode(); - FieldSpecList fields = FieldSpecList().add(FieldSpec(field, fieldId, handle, field_is_filter)); + FieldSpecList fields; + fields.add(FieldSpec(field, fieldId, handle, field_is_filter)); queryeval::Blueprint::UP bp = searchable.createBlueprint(requestContext, fields, *node); bp->fetchPostings(ExecuteInfo::create(strict)); SearchIterator::UP sb = bp->createSearch(*md, strict); diff --git a/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp b/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp index 83ffae0524c..3c08b263a7b 100644 --- a/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp +++ b/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp @@ -12,7 +12,6 @@ #include <vespa/searchlib/test/weightedchildrenverifiers.h> #include <vespa/searchlib/test/document_weight_attribute_helper.h> #include <vespa/searchlib/queryeval/document_weight_search_iterator.h> -#include <vespa/searchlib/fef/fef.h> using namespace search::query; using namespace search::queryeval; @@ -167,7 +166,8 @@ struct WandBlueprintSpec } Blueprint::UP blueprint(Searchable &searchable, const std::string &field, const search::query::Node &term) const { - FieldSpecList fields = FieldSpecList().add(FieldSpec(field, fieldId, handle)); + FieldSpecList fields; + fields.add(FieldSpec(field, fieldId, handle)); Blueprint::UP bp = searchable.createBlueprint(requestContext, fields, term); EXPECT_TRUE(dynamic_cast<ParallelWeakAndBlueprint*>(bp.get()) != 0); return bp; diff --git a/searchlib/src/tests/queryeval/queryeval.cpp b/searchlib/src/tests/queryeval/queryeval.cpp index 517e633f328..698bf7c08d5 100644 --- a/searchlib/src/tests/queryeval/queryeval.cpp +++ b/searchlib/src/tests/queryeval/queryeval.cpp @@ -339,7 +339,7 @@ class DummySingleValueBitNumericAttributeBlueprint : public SimpleLeafBlueprint { public: explicit DummySingleValueBitNumericAttributeBlueprint(const SimpleResult & result) : - SimpleLeafBlueprint(FieldSpecBaseList()), + SimpleLeafBlueprint(), _a("a", search::GrowStrategy(), false), _sc(), _tfmd() diff --git a/searchlib/src/tests/queryeval/weighted_set_term/weighted_set_term_test.cpp b/searchlib/src/tests/queryeval/weighted_set_term/weighted_set_term_test.cpp index 51594c478e5..90e16d4feff 100644 --- a/searchlib/src/tests/queryeval/weighted_set_term/weighted_set_term_test.cpp +++ b/searchlib/src/tests/queryeval/weighted_set_term/weighted_set_term_test.cpp @@ -66,7 +66,8 @@ struct WS { FakeRequestContext requestContext; MatchData::UP md = layout.createMatchData(); Node::UP node = createNode(); - FieldSpecList fields = FieldSpecList().add(FieldSpec(field, fieldId, handle)); + FieldSpecList fields; + fields.add(FieldSpec(field, fieldId, handle)); queryeval::Blueprint::UP bp = searchable.createBlueprint(requestContext, fields, *node); bp->fetchPostings(ExecuteInfo::create(strict)); SearchIterator::UP sb = bp->createSearch(*md, strict); @@ -80,7 +81,8 @@ struct WS { md->resolveTermField(handle)->tagAsNotNeeded(); } Node::UP node = createNode(); - FieldSpecList fields = FieldSpecList().add(FieldSpec(field, fieldId, handle, field_is_filter)); + FieldSpecList fields; + fields.add(FieldSpec(field, fieldId, handle, field_is_filter)); queryeval::Blueprint::UP bp = searchable.createBlueprint(requestContext, fields, *node); bp->fetchPostings(ExecuteInfo::create(strict)); SearchIterator::UP sb = bp->createSearch(*md, strict); diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index 60e24431351..8c3857ca539 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -89,9 +89,10 @@ Blueprint::sat_sum(const std::vector<HitEstimate> &data, uint32_t docid_limit) Blueprint::State::State() : _fields(), - _estimate(), + _estimateHits(0), _tree_size(1), _cost_tier(COST_TIER_NORMAL), + _estimateEmpty(true), _allow_termwise_eval(true), _want_global_filter(false) {} @@ -104,9 +105,10 @@ Blueprint::State::State(FieldSpecBase field) Blueprint::State::State(FieldSpecBaseList fields_in) : _fields(std::move(fields_in)), - _estimate(), + _estimateHits(0), _tree_size(1), _cost_tier(COST_TIER_NORMAL), + _estimateEmpty(true), _allow_termwise_eval(true), _want_global_filter(false) { @@ -400,10 +402,10 @@ IntermediateBlueprint::calculateEstimate() const return combine(estimates); } -uint32_t +uint8_t IntermediateBlueprint::calculate_cost_tier() const { - uint32_t cost_tier = State::COST_TIER_MAX; + uint8_t cost_tier = State::COST_TIER_MAX; for (const Blueprint::UP &child : _children) { cost_tier = std::min(cost_tier, child->getState().cost_tier()); } @@ -744,6 +746,7 @@ LeafBlueprint::setEstimate(HitEstimate est) void LeafBlueprint::set_cost_tier(uint32_t value) { + assert(value < 0x100); _state.cost_tier(value); notifyChange(); } diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.h b/searchlib/src/vespa/searchlib/queryeval/blueprint.h index b607a5d421f..870309dab7d 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.h @@ -65,11 +65,12 @@ public: { private: FieldSpecBaseList _fields; - HitEstimate _estimate; - uint32_t _tree_size; + uint32_t _estimateHits; + uint16_t _tree_size; uint8_t _cost_tier; - bool _allow_termwise_eval; - bool _want_global_filter; + bool _estimateEmpty : 1; + bool _allow_termwise_eval : 1; + bool _want_global_filter : 1; public: static constexpr uint8_t COST_TIER_NORMAL = 1; @@ -99,21 +100,27 @@ public: return nullptr; } - void estimate(HitEstimate est) { _estimate = est; } - HitEstimate estimate() const { return _estimate; } + void estimate(HitEstimate est) { + _estimateHits = est.estHits; + _estimateEmpty = est.empty; + } + HitEstimate estimate() const { return HitEstimate(_estimateHits, _estimateEmpty); } double hit_ratio(uint32_t docid_limit) const { - uint32_t total_hits = _estimate.estHits; + uint32_t total_hits = _estimateHits; uint32_t total_docs = std::max(total_hits, docid_limit); return (total_docs == 0) ? 0.0 : double(total_hits) / double(total_docs); } - void tree_size(uint32_t value) { _tree_size = value; } + void tree_size(uint32_t value) { + assert(value < 0x10000); + _tree_size = value; + } uint32_t tree_size() const { return _tree_size; } void allow_termwise_eval(bool value) { _allow_termwise_eval = value; } bool allow_termwise_eval() const { return _allow_termwise_eval; } void want_global_filter(bool value) { _want_global_filter = value; } bool want_global_filter() const { return _want_global_filter; } - void cost_tier(uint32_t value) { _cost_tier = value; } - uint32_t cost_tier() const { return _cost_tier; } + void cost_tier(uint8_t value) { _cost_tier = value; } + uint8_t cost_tier() const { return _cost_tier; } }; // utility that just takes maximum estimate @@ -289,7 +296,7 @@ class IntermediateBlueprint : public blueprint::StateCache private: Children _children; HitEstimate calculateEstimate() const; - uint32_t calculate_cost_tier() const; + uint8_t calculate_cost_tier() const; uint32_t calculate_tree_size() const; bool infer_allow_termwise_eval() const; bool infer_want_global_filter() const; diff --git a/searchlib/src/vespa/searchlib/queryeval/field_spec.h b/searchlib/src/vespa/searchlib/queryeval/field_spec.h index b9aeb148681..b6700613381 100644 --- a/searchlib/src/vespa/searchlib/queryeval/field_spec.h +++ b/searchlib/src/vespa/searchlib/queryeval/field_spec.h @@ -4,6 +4,7 @@ #include <vespa/searchlib/fef/handle.h> #include <vespa/vespalib/stllike/string.h> +#include <vespa/vespalib/util/small_vector.h> #include <vector> namespace search::fef { @@ -56,7 +57,7 @@ private: class FieldSpecBaseList { private: - using List = std::vector<FieldSpecBase>; + using List = vespalib::SmallVector<FieldSpecBase, 1>; List _list; public: @@ -68,7 +69,7 @@ public: FieldSpecBaseList & operator=(FieldSpecBaseList &) = delete; ~FieldSpecBaseList(); void reserve(size_t sz) { _list.reserve(sz); } - using const_iterator = List::const_iterator; + using const_iterator = const FieldSpecBase *; FieldSpecBaseList &add(const FieldSpecBase &spec) { _list.push_back(spec); return *this; @@ -89,6 +90,11 @@ private: std::vector<FieldSpec> _list; public: + FieldSpecList() = default; + FieldSpecList(FieldSpecList &&) noexcept = delete; + FieldSpecList & operator=(FieldSpecList &&) noexcept = delete; + FieldSpecList(const FieldSpecList &) noexcept = delete; + FieldSpecList & operator=(const FieldSpecList &) noexcept = delete; ~FieldSpecList(); FieldSpecList &add(const FieldSpec &spec) { _list.push_back(spec); @@ -98,7 +104,6 @@ public: size_t size() const { return _list.size(); } const FieldSpec &operator[](size_t i) const { return _list[i]; } void clear() { _list.clear(); } - void swap(FieldSpecList & rhs) { _list.swap(rhs._list); } }; } |