diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-05-12 18:09:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-12 18:09:29 +0200 |
commit | aff2a48b41d3014883f450ddbcafe5df58f8cbe4 (patch) | |
tree | 54ea044088444740d215300b1dced89cc63edea5 | |
parent | adb58e0d4ffca0fdd590f99f10b10e424d8d42c9 (diff) | |
parent | 8444b221bf0513c45234b84924785abf436f4bec (diff) |
Merge pull request #27080 from vespa-engine/balder/avoid-copying-fieldspecbase-vector
Move the fieldspec base vector.
20 files changed, 207 insertions, 229 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 45ac0a8f924..2cb82fabc4c 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 @@ -71,7 +71,7 @@ struct MockBlueprint : SimpleLeafBlueprint { bool postings_fetched = false; search::queryeval::ExecuteInfo postings_strict = search::queryeval::ExecuteInfo::FALSE; MockBlueprint(const FieldSpec &spec_in, const vespalib::string &term_in) - : SimpleLeafBlueprint(FieldSpecBaseList().add(spec_in)), spec(spec_in), term(term_in) + : SimpleLeafBlueprint(spec_in), spec(spec_in), term(term_in) { setEstimate(HitEstimate(756, false)); } diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp index 7b7d590d913..162db5d8760 100644 --- a/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp +++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp @@ -213,7 +213,7 @@ private: } public: WhiteListBlueprint(const search::BitVector &activeLids, bool all_lids_active) - : SimpleLeafBlueprint(FieldSpecBaseList()), + : SimpleLeafBlueprint(), _activeLids(activeLids), _all_lids_active(all_lids_active), _lock(), diff --git a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp index 2d3323949d1..eee2b7a7203 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp @@ -2,7 +2,6 @@ #include "blueprintbuilder.h" #include "querynodes.h" -#include "termdatafromnode.h" #include "same_element_builder.h" #include <vespa/searchcorespi/index/indexsearchable.h> #include <vespa/searchlib/query/tree/customtypevisitor.h> @@ -25,7 +24,7 @@ struct Mixer { void addAttribute(Blueprint::UP attr) { if (attributes.get() == 0) { - attributes.reset(new OrBlueprint()); + attributes = std::make_unique<OrBlueprint>(); } attributes->addChild(std::move(attr)); } @@ -92,7 +91,7 @@ private: for (size_t i = 0; i < n.numFields(); ++i) { specs.add(n.field(i).fieldSpec()); } - EquivBlueprint *eq = new EquivBlueprint(specs, n.children_mdl); + EquivBlueprint *eq = new EquivBlueprint(std::move(specs), n.children_mdl); _result.reset(eq); for (size_t i = 0; i < n.getChildren().size(); ++i) { search::query::Node &node = *n.getChildren()[i]; 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 6f4ffc31741..b0d3edc984a 100644 --- a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp @@ -22,19 +22,19 @@ class MyOr : public IntermediateBlueprint { private: public: - virtual HitEstimate combine(const std::vector<HitEstimate> &data) const override { + HitEstimate combine(const std::vector<HitEstimate> &data) const override { return max(data); } - virtual FieldSpecBaseList exposeFields() const override { + FieldSpecBaseList exposeFields() const override { return mixChildrenFields(); } - virtual void sort(Children &children) const override { + void sort(Children &children) const override { std::sort(children.begin(), children.end(), TieredGreaterEstimate()); } - virtual bool inheritStrict(size_t i) const override { + bool inheritStrict(size_t i) const override { (void) i; return true; } @@ -136,10 +136,10 @@ public: //----------------------------------------------------------------------------- struct MyTerm : SimpleLeafBlueprint { - MyTerm(const FieldSpecBaseList &fields, uint32_t hitEstimate) : SimpleLeafBlueprint(fields) { + MyTerm(FieldSpecBase field, uint32_t hitEstimate) : SimpleLeafBlueprint(field) { setEstimate(HitEstimate(hitEstimate, false)); } - virtual SearchIterator::UP createLeafSearch(const search::fef::TermFieldMatchDataArray &, bool) const override { + SearchIterator::UP createLeafSearch(const search::fef::TermFieldMatchDataArray &, bool) const override { return SearchIterator::UP(); } SearchIteratorUP createFilterSearch(bool strict, FilterConstraint constraint) const override { @@ -149,49 +149,29 @@ struct MyTerm : SimpleLeafBlueprint { //----------------------------------------------------------------------------- +Blueprint::UP ap(Blueprint *b) { return Blueprint::UP(b); } +Blueprint::UP ap(Blueprint &b) { return Blueprint::UP(&b); } + } // namespace <unnamed> -class Test : public vespalib::TestApp +class Fixture { private: MatchData::UP _md; - - static Blueprint::UP ap(Blueprint *b) { return Blueprint::UP(b); } - static Blueprint::UP ap(Blueprint &b) { return Blueprint::UP(&b); } - +public: + Fixture() + : _md(MatchData::makeTestInstance(100, 10)) + {} + ~Fixture() = default; SearchIterator::UP create(const Blueprint &blueprint); - bool check_equal(const SearchIterator &a, const SearchIterator &b); bool check_equal(const Blueprint &a, const Blueprint &b); - bool check_not_equal(const SearchIterator &a, const SearchIterator &b); bool check_not_equal(const Blueprint &a, const Blueprint &b); - -public: - Test() - : vespalib::TestApp(), - _md(MatchData::makeTestInstance(100, 10)) - {} - ~Test() {} - Blueprint::UP buildBlueprint1(); - Blueprint::UP buildBlueprint2(); - void testBlueprintBuilding(); - void testHitEstimateCalculation(); - void testHitEstimatePropagation(); - void testMatchDataPropagation(); - void testChildSorting(); - void testChildAndNotCollapsing(); - void testChildAndCollapsing(); - void testChildOrCollapsing(); - void testSearchCreation(); - void testBlueprintMakeNew(); - void requireThatAsStringWorks(); - void requireThatAsSlimeWorks(); - void requireThatVisitMembersWorks(); - void requireThatDocIdLimitInjectionWorks(); - int Main() override; + static bool check_equal(const SearchIterator &a, const SearchIterator &b); + static bool check_not_equal(const SearchIterator &a, const SearchIterator &b); }; SearchIterator::UP -Test::create(const Blueprint &blueprint) +Fixture::create(const Blueprint &blueprint) { const_cast<Blueprint &>(blueprint).fetchPostings(ExecuteInfo::TRUE); SearchIterator::UP search = blueprint.createSearch(*_md, true); @@ -200,39 +180,37 @@ Test::create(const Blueprint &blueprint) } bool -Test::check_equal(const SearchIterator &a, const SearchIterator &b) +Fixture::check_equal(const SearchIterator &a, const SearchIterator &b) { return EXPECT_EQUAL(a.asString(), b.asString()); } bool -Test::check_equal(const Blueprint &a, const Blueprint &b) +Fixture::check_not_equal(const SearchIterator &a, const SearchIterator &b) { - SearchIterator::UP searchA = create(a); - SearchIterator::UP searchB = create(b); - TEST_STATE("check_equal"); - bool ok = check_equal(*searchA, *searchB); - return ok; + return EXPECT_NOT_EQUAL(a.asString(), b.asString()); } bool -Test::check_not_equal(const SearchIterator &a, const SearchIterator &b) +Fixture::check_equal(const Blueprint &a, const Blueprint &b) { - return EXPECT_NOT_EQUAL(a.asString(), b.asString()); + SearchIterator::UP searchA = create(a); + SearchIterator::UP searchB = create(b); + bool ok = check_equal(*searchA, *searchB); + return ok; } bool -Test::check_not_equal(const Blueprint &a, const Blueprint &b) +Fixture::check_not_equal(const Blueprint &a, const Blueprint &b) { SearchIterator::UP searchA = create(a); SearchIterator::UP searchB = create(b); - TEST_STATE("check_not_equal"); bool ok = check_not_equal(*searchA, *searchB); return ok; } Blueprint::UP -Test::buildBlueprint1() +buildBlueprint1() { return ap(MyAnd::create() .add(MyOr::create() @@ -248,7 +226,7 @@ Test::buildBlueprint1() } Blueprint::UP -Test::buildBlueprint2() +buildBlueprint2() { return ap(MyAnd::create() .add(MyOr::create() @@ -263,19 +241,17 @@ Test::buildBlueprint2() ); } -void -Test::testBlueprintBuilding() +TEST_F("testBlueprintBuilding", Fixture) { Blueprint::UP root1 = buildBlueprint1(); Blueprint::UP root2 = buildBlueprint2(); - SearchIterator::UP search1 = create(*root1); - SearchIterator::UP search2 = create(*root2); + SearchIterator::UP search1 = f.create(*root1); + SearchIterator::UP search2 = f.create(*root2); // fprintf(stderr, "%s\n", search1->asString().c_str()); // fprintf(stderr, "%s\n", search2->asString().c_str()); } -void -Test::testHitEstimateCalculation() +TEST("testHitEstimateCalculation") { { Blueprint::UP leaf = ap(MyLeafSpec(37).create()); @@ -333,16 +309,15 @@ Test::testHitEstimateCalculation() } } -void -Test::testHitEstimatePropagation() +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(); @@ -375,8 +350,7 @@ Test::testHitEstimatePropagation() EXPECT_EQUAL(25u, root->getState().estimate().estHits); } -void -Test::testMatchDataPropagation() +TEST("testMatchDataPropagation") { { Blueprint::UP leaf = ap(MyLeafSpec(0, true).create()); @@ -430,8 +404,7 @@ Test::testMatchDataPropagation() } } -void -Test::testChildAndNotCollapsing() +TEST_F("testChildAndNotCollapsing", Fixture) { Blueprint::UP unsorted = ap(OtherAndNot::create() .add(OtherAndNot::create() @@ -464,13 +437,12 @@ Test::testChildAndNotCollapsing() .add(MyLeafSpec(3).addField(2, 62).create()) ) ); - TEST_DO(check_not_equal(*sorted, *unsorted)); + TEST_DO(f.check_not_equal(*sorted, *unsorted)); unsorted = Blueprint::optimize(std::move(unsorted)); - TEST_DO(check_equal(*sorted, *unsorted)); + TEST_DO(f.check_equal(*sorted, *unsorted)); } -void -Test::testChildAndCollapsing() +TEST_F("testChildAndCollapsing", Fixture) { Blueprint::UP unsorted = ap(OtherAnd::create() .add(OtherAnd::create() @@ -504,13 +476,12 @@ Test::testChildAndCollapsing() .add(MyLeafSpec(300).addField(1, 31).create()) ); - TEST_DO(check_not_equal(*sorted, *unsorted)); + TEST_DO(f.check_not_equal(*sorted, *unsorted)); unsorted = Blueprint::optimize(std::move(unsorted)); - TEST_DO(check_equal(*sorted, *unsorted)); + TEST_DO(f.check_equal(*sorted, *unsorted)); } -void -Test::testChildOrCollapsing() +TEST_F("testChildOrCollapsing", Fixture) { Blueprint::UP unsorted = ap(OtherOr::create() .add(OtherOr::create() @@ -543,13 +514,12 @@ Test::testChildOrCollapsing() .add(MyLeafSpec(2).addField(2, 52).create()) .add(MyLeafSpec(1).addField(2, 42).create()) ); - TEST_DO(check_not_equal(*sorted, *unsorted)); + TEST_DO(f.check_not_equal(*sorted, *unsorted)); unsorted = Blueprint::optimize(std::move(unsorted)); - TEST_DO(check_equal(*sorted, *unsorted)); + TEST_DO(f.check_equal(*sorted, *unsorted)); } -void -Test::testChildSorting() +TEST_F("testChildSorting", Fixture) { Blueprint::UP unsorted = ap(MyAnd::create() .add(MyOr::create() @@ -587,33 +557,32 @@ Test::testChildSorting() ) ); - TEST_DO(check_not_equal(*sorted, *unsorted)); + TEST_DO(f.check_not_equal(*sorted, *unsorted)); unsorted = Blueprint::optimize(std::move(unsorted)); - TEST_DO(check_equal(*sorted, *unsorted)); + TEST_DO(f.check_equal(*sorted, *unsorted)); } -void -Test::testSearchCreation() +TEST_F("testSearchCreation", Fixture) { { Blueprint::UP l = ap(MyLeafSpec(3) .addField(1, 1) .addField(2, 2) .addField(3, 3).create()); - SearchIterator::UP leafsearch = create(*l); + SearchIterator::UP leafsearch = f.create(*l); MySearch *lw = new MySearch("leaf", true, true); lw->addHandle(1).addHandle(2).addHandle(3); SearchIterator::UP wantleaf(lw); - TEST_DO(check_equal(*wantleaf, *leafsearch)); + TEST_DO(f.check_equal(*wantleaf, *leafsearch)); } { Blueprint::UP a = ap(MyAnd::create() .add(MyLeafSpec(1).addField(1, 1).create()) .add(MyLeafSpec(2).addField(2, 2).create())); - SearchIterator::UP andsearch = create(*a); + SearchIterator::UP andsearch = f.create(*a); MySearch *l1 = new MySearch("leaf", true, true); MySearch *l2 = new MySearch("leaf", true, false); @@ -623,13 +592,13 @@ Test::testSearchCreation() aw->add(l1); aw->add(l2); SearchIterator::UP wanted(aw); - TEST_DO(check_equal(*wanted, *andsearch)); + TEST_DO(f.check_equal(*wanted, *andsearch)); } { Blueprint::UP o = ap(MyOr::create() .add(MyLeafSpec(1).addField(1, 11).create()) .add(MyLeafSpec(2).addField(2, 22).create())); - SearchIterator::UP orsearch = create(*o); + SearchIterator::UP orsearch = f.create(*o); MySearch *l1 = new MySearch("leaf", true, true); MySearch *l2 = new MySearch("leaf", true, true); @@ -639,18 +608,11 @@ Test::testSearchCreation() ow->add(l1); ow->add(l2); SearchIterator::UP wanted(ow); - TEST_DO(check_equal(*wanted, *orsearch)); + TEST_DO(f.check_equal(*wanted, *orsearch)); } } -template<typename T> -Blueprint::UP makeNew(T *orig) -{ - return std::make_unique<T>(*orig); -} - -void -Test::testBlueprintMakeNew() +TEST("testBlueprintMakeNew") { Blueprint::UP orig = ap(MyOr::create() .add(MyLeafSpec(1).addField(1, 11).create()) @@ -765,19 +727,17 @@ struct BlueprintFixture { MyOr _blueprint; BlueprintFixture() : _blueprint() { - _blueprint.add(new MyTerm(FieldSpecBaseList().add(FieldSpecBase(5, 7)), 9)); + _blueprint.add(new MyTerm(FieldSpecBase(5, 7), 9)); } }; -void -Test::requireThatAsStringWorks() +TEST("requireThatAsStringWorks") { BlueprintFixture f; EXPECT_EQUAL(getExpectedBlueprint(), f._blueprint.asString()); } -void -Test::requireThatAsSlimeWorks() +TEST("requireThatAsSlimeWorks") { BlueprintFixture f; vespalib::Slime slime; @@ -788,8 +748,7 @@ Test::requireThatAsSlimeWorks() EXPECT_EQUAL(expectedSlime, slime); } -void -Test::requireThatVisitMembersWorks() +TEST("requireThatVisitMembersWorks") { BlueprintFixture f; vespalib::ObjectDumper dumper; @@ -797,8 +756,7 @@ Test::requireThatVisitMembersWorks() EXPECT_EQUAL(getExpectedBlueprint(), dumper.toString()); } -void -Test::requireThatDocIdLimitInjectionWorks() +TEST("requireThatDocIdLimitInjectionWorks") { BlueprintFixture f; ASSERT_GREATER(f._blueprint.childCnt(), 0u); @@ -808,26 +766,13 @@ Test::requireThatDocIdLimitInjectionWorks() EXPECT_EQUAL(1000u, term.get_docid_limit()); } -int -Test::Main() -{ - TEST_DEBUG("lhs.out", "rhs.out"); - TEST_INIT("blueprint_test"); - testBlueprintBuilding(); - testHitEstimateCalculation(); - testHitEstimatePropagation(); - testMatchDataPropagation(); - testChildSorting(); - testChildAndNotCollapsing(); - testChildAndCollapsing(); - testChildOrCollapsing(); - testSearchCreation(); - testBlueprintMakeNew(); - requireThatAsStringWorks(); - requireThatAsSlimeWorks(); - requireThatVisitMembersWorks(); - requireThatDocIdLimitInjectionWorks(); - TEST_DONE(); +TEST("Control object sizes") { + EXPECT_EQUAL(32u, sizeof(Blueprint::State)); + EXPECT_EQUAL(32u, sizeof(Blueprint)); + EXPECT_EQUAL(64u, sizeof(LeafBlueprint)); } -TEST_APPHOOK(Test); +TEST_MAIN() { + TEST_DEBUG("lhs.out", "rhs.out"); + TEST_RUN_ALL(); +} diff --git a/searchlib/src/tests/queryeval/blueprint/mysearch.h b/searchlib/src/tests/queryeval/blueprint/mysearch.h index 6c91a23e80b..4fa53443123 100644 --- a/searchlib/src/tests/queryeval/blueprint/mysearch.h +++ b/searchlib/src/tests/queryeval/blueprint/mysearch.h @@ -110,11 +110,14 @@ 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(const FieldSpecBaseList &fields) - : SimpleLeafBlueprint(fields), _got_global_filter(false) + MyLeaf() + : SimpleLeafBlueprint(), _got_global_filter(false) + {} + MyLeaf(FieldSpecBaseList fields) + : SimpleLeafBlueprint(std::move(fields)), _got_global_filter(false) {} MyLeaf &estimate(uint32_t hits, bool empty = 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/equiv/equiv_test.cpp b/searchlib/src/tests/queryeval/equiv/equiv_test.cpp index 887128b8d5e..bc927e233db 100644 --- a/searchlib/src/tests/queryeval/equiv/equiv_test.cpp +++ b/searchlib/src/tests/queryeval/equiv/equiv_test.cpp @@ -45,7 +45,7 @@ EquivTest::test_equiv(bool strict, bool unpack_normal_features, bool unpack_inte FieldSpecBaseList fields; fields.add(FieldSpecBase(1, 1)); fields.add(FieldSpecBase(2, 2)); - auto bp = std::make_unique<EquivBlueprint>(fields, subLayout); + auto bp = std::make_unique<EquivBlueprint>(std::move(fields), subLayout); bp->addTerm(std::make_unique<FakeBlueprint>(FieldSpec("foo", 1, fbh11), a), 1.0); bp->addTerm(std::make_unique<FakeBlueprint>(FieldSpec("bar", 2, fbh21), b), 1.0); diff --git a/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp b/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp index fdac3c582b1..ea4753ab847 100644 --- a/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp +++ b/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp @@ -66,7 +66,7 @@ struct LeafProxy : SimpleLeafBlueprint { child->setParent(this); } LeafProxy(std::unique_ptr<Blueprint> child_in) - : SimpleLeafBlueprint({}), child(std::move(child_in)) { init(); } + : SimpleLeafBlueprint(), child(std::move(child_in)) { init(); } LeafProxy(const FieldSpec &field, std::unique_ptr<Blueprint> child_in) : SimpleLeafBlueprint(field), child(std::move(child_in)) { init(); } SearchIteratorUP createLeafSearch(const TermFieldMatchDataArray &, bool) const override { abort(); } 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/termwise_eval/termwise_eval_test.cpp b/searchlib/src/tests/queryeval/termwise_eval/termwise_eval_test.cpp index bad7146479c..763701b00a3 100644 --- a/searchlib/src/tests/queryeval/termwise_eval/termwise_eval_test.cpp +++ b/searchlib/src/tests/queryeval/termwise_eval/termwise_eval_test.cpp @@ -66,12 +66,12 @@ struct MyTerm : public SearchIterator { struct MyBlueprint : SimpleLeafBlueprint { std::vector<uint32_t> hits; MyBlueprint(const std::vector<uint32_t> &hits_in) - : SimpleLeafBlueprint(FieldSpecBaseList()), hits(hits_in) + : SimpleLeafBlueprint(), hits(hits_in) { setEstimate(HitEstimate(hits.size(), hits.empty())); } MyBlueprint(const std::vector<uint32_t> &hits_in, bool allow_termwise_eval) - : SimpleLeafBlueprint(FieldSpecBaseList()), hits(hits_in) + : SimpleLeafBlueprint(), hits(hits_in) { setEstimate(HitEstimate(hits.size(), hits.empty())); set_allow_termwise_eval(allow_termwise_eval); 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 87f7ab99002..488c58e3119 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -2,7 +2,6 @@ #include "blueprint.h" #include "leaf_blueprints.h" -#include "intermediate_blueprints.h" #include "emptysearch.h" #include "full_search.h" #include "field_spec.hpp" @@ -17,7 +16,6 @@ #include <vespa/vespalib/util/classname.h> #include <vespa/vespalib/util/require.h> #include <vespa/vespalib/data/slime/inserter.h> -#include <type_traits> #include <map> #include <vespa/log/log.h> @@ -89,13 +87,30 @@ Blueprint::sat_sum(const std::vector<HitEstimate> &data, uint32_t docid_limit) return { uint32_t(std::min(sum, uint64_t(limit))), empty }; } -Blueprint::State::State(const FieldSpecBaseList &fields_in) - : _fields(fields_in), - _estimate(), - _cost_tier(COST_TIER_NORMAL), +Blueprint::State::State() + : _fields(), + _estimateHits(0), _tree_size(1), + _estimateEmpty(true), _allow_termwise_eval(true), - _want_global_filter(false) + _want_global_filter(false), + _cost_tier(COST_TIER_NORMAL) +{} + +Blueprint::State::State(FieldSpecBase field) + : State() +{ + _fields.add(field); +} + +Blueprint::State::State(FieldSpecBaseList fields_in) + : _fields(std::move(fields_in)), + _estimateHits(0), + _tree_size(1), + _estimateEmpty(true), + _allow_termwise_eval(true), + _want_global_filter(false), + _cost_tier(COST_TIER_NORMAL) { } @@ -387,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()); } @@ -483,6 +498,7 @@ IntermediateBlueprint::mixChildrenFields() const } } } + fieldList.reserve(fieldMap.size()); for (const auto & entry : fieldMap) { fieldList.add(*entry.second); } @@ -684,18 +700,9 @@ IntermediateBlueprint::calculateUnpackInfo(const fef::MatchData & md) const //----------------------------------------------------------------------------- -LeafBlueprint::LeafBlueprint(const FieldSpecBaseList &fields, bool allow_termwise_eval) - : _state(fields) -{ - _state.allow_termwise_eval(allow_termwise_eval); -} - -LeafBlueprint::~LeafBlueprint() = default; - void -LeafBlueprint::fetchPostings(const ExecuteInfo &execInfo) +LeafBlueprint::fetchPostings(const ExecuteInfo &) { - (void) execInfo; } void @@ -739,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 c76f0a22e98..1ea02e41a62 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.h @@ -65,22 +65,25 @@ public: { private: FieldSpecBaseList _fields; - HitEstimate _estimate; - uint32_t _cost_tier; - uint32_t _tree_size; - bool _allow_termwise_eval; - bool _want_global_filter; + uint32_t _estimateHits; + uint32_t _tree_size : 20; + bool _estimateEmpty : 1; + bool _allow_termwise_eval : 1; + bool _want_global_filter : 1; + uint8_t _cost_tier; public: - static constexpr uint32_t COST_TIER_NORMAL = 1; - static constexpr uint32_t COST_TIER_EXPENSIVE = 2; - static constexpr uint32_t COST_TIER_MAX = 999; + static constexpr uint8_t COST_TIER_NORMAL = 1; + static constexpr uint8_t COST_TIER_EXPENSIVE = 2; + static constexpr uint8_t COST_TIER_MAX = 255; - State(const FieldSpecBaseList &fields_in); + State(); + State(FieldSpecBase field); + State(FieldSpecBaseList fields_in); State(const State &rhs) = delete; - State(State &&rhs) = default; + State(State &&rhs) noexcept = default; State &operator=(const State &rhs) = delete; - State &operator=(State &&rhs) = default; + State &operator=(State &&rhs) noexcept = default; ~State(); bool isTermLike() const { return !_fields.empty(); } @@ -97,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 < 0x100000); + _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 @@ -269,7 +278,7 @@ protected: virtual State calculateState() const = 0; public: - StateCache() : _stale(true), _state(FieldSpecBaseList()) {} + StateCache() : _stale(true), _state() {} const State &getState() const final { if (_stale) { updateState(); @@ -287,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; @@ -348,7 +357,6 @@ class LeafBlueprint : public Blueprint { private: State _state; - protected: void optimize(Blueprint* &self) final; void setEstimate(HitEstimate est); @@ -357,9 +365,25 @@ protected: void set_want_global_filter(bool value); void set_tree_size(uint32_t value); - LeafBlueprint(const FieldSpecBaseList &fields, bool allow_termwise_eval); + LeafBlueprint(bool allow_termwise_eval) + : _state() + { + _state.allow_termwise_eval(allow_termwise_eval); + } + + LeafBlueprint(FieldSpecBase field, bool allow_termwise_eval) + : _state(field) + { + _state.allow_termwise_eval(allow_termwise_eval); + } + LeafBlueprint(FieldSpecBaseList fields, bool allow_termwise_eval) + : _state(std::move(fields)) + { + _state.allow_termwise_eval(allow_termwise_eval); + } + public: - ~LeafBlueprint() override; + ~LeafBlueprint() override = default; const State &getState() const final { return _state; } void setDocIdLimit(uint32_t limit) final { Blueprint::setDocIdLimit(limit); } void fetchPostings(const ExecuteInfo &execInfo) override; @@ -372,14 +396,15 @@ public: // for leaf nodes representing a single term struct SimpleLeafBlueprint : LeafBlueprint { - explicit SimpleLeafBlueprint(const FieldSpecBase &field) : LeafBlueprint(FieldSpecBaseList().add(field), true) {} - explicit SimpleLeafBlueprint(const FieldSpecBaseList &fields) : LeafBlueprint(fields, true) {} + explicit SimpleLeafBlueprint() : LeafBlueprint(true) {} + explicit SimpleLeafBlueprint(FieldSpecBase field) : LeafBlueprint(field, true) {} + explicit SimpleLeafBlueprint(FieldSpecBaseList fields) : LeafBlueprint(std::move(fields), true) {} }; // for leaf nodes representing more complex structures like wand/phrase struct ComplexLeafBlueprint : LeafBlueprint { - explicit ComplexLeafBlueprint(const FieldSpecBase &field) : LeafBlueprint(FieldSpecBaseList().add(field), false) {} - explicit ComplexLeafBlueprint(const FieldSpecBaseList &fields) : LeafBlueprint(fields, false) {} + explicit ComplexLeafBlueprint(FieldSpecBase field) : LeafBlueprint(field, false) {} + explicit ComplexLeafBlueprint(FieldSpecBaseList fields) : LeafBlueprint(std::move(fields), false) {} }; //----------------------------------------------------------------------------- diff --git a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp index c2f4c53224d..af6b59dd6ca 100644 --- a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp @@ -40,10 +40,9 @@ public: }; -EquivBlueprint::EquivBlueprint(const FieldSpecBaseList &fields, +EquivBlueprint::EquivBlueprint(FieldSpecBaseList fields, fef::MatchDataLayout subtree_mdl) - : ComplexLeafBlueprint(fields), - _fields(fields), + : ComplexLeafBlueprint(std::move(fields)), _estimate(), _layout(subtree_mdl), _terms(), diff --git a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h index 86bd4f09cd4..140da63afcc 100644 --- a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h @@ -10,14 +10,13 @@ namespace search::queryeval { class EquivBlueprint : public ComplexLeafBlueprint { private: - FieldSpecBaseList _fields; HitEstimate _estimate; fef::MatchDataLayout _layout; std::vector<Blueprint::UP> _terms; std::vector<double> _exactness; public: - EquivBlueprint(const FieldSpecBaseList &fields, fef::MatchDataLayout subtree_mdl); + EquivBlueprint(FieldSpecBaseList fields, fef::MatchDataLayout subtree_mdl); ~EquivBlueprint() override; // used by create visitor diff --git a/searchlib/src/vespa/searchlib/queryeval/field_spec.h b/searchlib/src/vespa/searchlib/queryeval/field_spec.h index f37403471ac..a1050209b41 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,12 +57,18 @@ private: class FieldSpecBaseList { private: - using List = std::vector<FieldSpecBase>; + using List = vespalib::SmallVector<FieldSpecBase, 1>; List _list; public: + FieldSpecBaseList() = default; + FieldSpecBaseList(FieldSpecBaseList &&) noexcept = default; + FieldSpecBaseList & operator=(FieldSpecBaseList &&) noexcept = default; + FieldSpecBaseList(const FieldSpecBaseList &) = default; + FieldSpecBaseList & operator=(FieldSpecBaseList &) = delete; ~FieldSpecBaseList(); - using const_iterator = List::const_iterator; + void reserve(size_t sz) { _list.reserve(sz); } + using const_iterator = const FieldSpecBase *; FieldSpecBaseList &add(const FieldSpecBase &spec) { _list.push_back(spec); return *this; @@ -71,8 +78,6 @@ public: const_iterator begin() const { return _list.begin(); } const_iterator end() const { return _list.end(); } const FieldSpecBase &operator[](size_t i) const { return _list[i]; } - void clear() { _list.clear(); } - void swap(FieldSpecBaseList & rhs) { _list.swap(rhs._list); } }; /** @@ -84,6 +89,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); @@ -93,7 +103,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); } }; } diff --git a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp index 86f520c8711..1af5f7fa3d4 100644 --- a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp @@ -11,8 +11,7 @@ namespace search::queryeval { //----------------------------------------------------------------------------- SearchIterator::UP -EmptyBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArray &, - bool) const +EmptyBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArray &, bool) const { return std::make_unique<EmptySearch>(); } @@ -23,22 +22,11 @@ EmptyBlueprint::createFilterSearch(bool /*strict*/, FilterConstraint /* constrai return std::make_unique<EmptySearch>(); } -EmptyBlueprint::EmptyBlueprint(const FieldSpecBase &field) - : SimpleLeafBlueprint(field) +EmptyBlueprint::EmptyBlueprint(FieldSpecBaseList fields) + : SimpleLeafBlueprint(std::move(fields)) { } -EmptyBlueprint::EmptyBlueprint(const FieldSpecBaseList &fields) - : SimpleLeafBlueprint(fields) -{ -} - -EmptyBlueprint::EmptyBlueprint() - : SimpleLeafBlueprint(FieldSpecBaseList()) -{ -} - - SearchIterator::UP AlwaysTrueBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArray &, bool) const { @@ -51,7 +39,7 @@ AlwaysTrueBlueprint::createFilterSearch(bool /*strict*/, FilterConstraint /* con return std::make_unique<FullSearch>(); } -AlwaysTrueBlueprint::AlwaysTrueBlueprint() : SimpleLeafBlueprint(FieldSpecBaseList()) +AlwaysTrueBlueprint::AlwaysTrueBlueprint() : SimpleLeafBlueprint() { setEstimate(HitEstimate(search::endDocId, false)); } @@ -61,25 +49,23 @@ AlwaysTrueBlueprint::AlwaysTrueBlueprint() : SimpleLeafBlueprint(FieldSpecBaseLi SearchIterator::UP SimpleBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArray &, bool strict) const { - SimpleSearch *ss = new SimpleSearch(_result, strict); - SearchIterator::UP search(ss); - ss->tag(_tag); + auto search = std::make_unique<SimpleSearch>(_result, strict); + search->tag(_tag); return search; } SearchIterator::UP SimpleBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const { - SimpleSearch *ss = new SimpleSearch(_result, strict); - SearchIterator::UP search(ss); - ss->tag(_tag + - (strict ? "<strict," : "<nostrict,") + - (constraint == FilterConstraint::UPPER_BOUND ? "upper>" : "lower>")); + auto search = std::make_unique<SimpleSearch>(_result, strict); + search->tag(_tag + + (strict ? "<strict," : "<nostrict,") + + (constraint == FilterConstraint::UPPER_BOUND ? "upper>" : "lower>")); return search; } SimpleBlueprint::SimpleBlueprint(const SimpleResult &result) - : SimpleLeafBlueprint(FieldSpecBaseList()), + : SimpleLeafBlueprint(), _tag(), _result(result) { diff --git a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h index b4d7682cf89..57c3e5f3533 100644 --- a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h +++ b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h @@ -16,9 +16,9 @@ class EmptyBlueprint : public SimpleLeafBlueprint protected: SearchIterator::UP createLeafSearch(const search::fef::TermFieldMatchDataArray &tfmda, bool strict) const override; public: - EmptyBlueprint(const FieldSpecBaseList &fields); - EmptyBlueprint(const FieldSpecBase &field); - EmptyBlueprint(); + EmptyBlueprint(FieldSpecBaseList fields); + EmptyBlueprint(FieldSpecBase field) : SimpleLeafBlueprint(field) {} + EmptyBlueprint() = default; SearchIterator::UP createFilterSearch(bool strict, FilterConstraint constraint) const override; }; |