diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-11-22 16:02:38 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2023-11-22 16:17:19 +0000 |
commit | 10586103aa69d192dea6351375c75522d187bb41 (patch) | |
tree | b621a271606ca4c4f87ff4c61d22d29e56d798ec | |
parent | 40fca839012e79e792b94f22cb7de5846acd1433 (diff) |
Avoid casting by adding asXXX methods to the Blueprint interface.
12 files changed, 65 insertions, 59 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp index 0393bdc2ee8..95e4eac437c 100644 --- a/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp +++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp @@ -222,7 +222,7 @@ public: setEstimate(HitEstimate(_activeLids.size(), false)); } - bool isWhiteList() const override { return true; } + bool isWhiteList() const noexcept final { return true; } SearchIterator::UP createFilterSearch(bool strict, FilterConstraint) const override { if (_all_lids_active) { @@ -231,7 +231,7 @@ public: return create_search_helper(strict); } - ~WhiteListBlueprint() { + ~WhiteListBlueprint() override { for (auto matchData : _matchDataVector) { delete matchData; } diff --git a/searchcore/src/vespa/searchcore/proton/matching/query.cpp b/searchcore/src/vespa/searchcore/proton/matching/query.cpp index 071e914b405..f55ba77cec8 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/query.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/query.cpp @@ -143,7 +143,7 @@ void exchange_location_nodes(const string &location_str, IntermediateBlueprint * asRankOrAndNot(Blueprint * blueprint) { return ((blueprint->isAndNot() || blueprint->isRank())) - ? static_cast<IntermediateBlueprint *>(blueprint) + ? blueprint->asIntermediate() : nullptr; } diff --git a/searchcore/src/vespa/searchcore/proton/matching/rangequerylocator.cpp b/searchcore/src/vespa/searchcore/proton/matching/rangequerylocator.cpp index fcae5794e9e..af26a47fba3 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/rangequerylocator.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/rangequerylocator.cpp @@ -25,15 +25,13 @@ namespace { RangeLimitMetaInfo locateFirst(uint32_t field_id, const Blueprint & blueprint) { - if (blueprint.isIntermediate()) { - const auto & intermediate = static_cast<const IntermediateBlueprint &>(blueprint); - if (intermediate.isAndNot()) { - return locateFirst(field_id, intermediate.getChild(0)); - } else if (intermediate.isRank()) { - return locateFirst(field_id, intermediate.getChild(0)); - } else if (intermediate.isAnd()) { - for (size_t i(0); i < intermediate.childCnt(); i++) { - RangeLimitMetaInfo childMeta = locateFirst(field_id, intermediate.getChild(i)); + const auto * intermediate = blueprint.asIntermediate(); + if (intermediate) { + if (intermediate->isAndNot() || intermediate->isRank()) { + return locateFirst(field_id, intermediate->getChild(0)); + } else if (intermediate->isAnd()) { + for (size_t i(0); i < intermediate->childCnt(); i++) { + RangeLimitMetaInfo childMeta = locateFirst(field_id, intermediate->getChild(i)); if (childMeta.valid()) { return childMeta; } @@ -42,9 +40,9 @@ locateFirst(uint32_t field_id, const Blueprint & blueprint) { } else { const Blueprint::State & state = blueprint.getState(); if (state.isTermLike() && (state.numFields() == 1) && (state.field(0).getFieldId() == field_id)) { - const LeafBlueprint &leaf = static_cast<const LeafBlueprint &>(blueprint); + const LeafBlueprint * leaf = blueprint.asLeaf(); vespalib::string from, too; - if (leaf.getRange(from, too)) { + if (leaf->getRange(from, too)) { return {from, too, state.estimate().estHits}; } } diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index a289cc7a2f6..50c79ce4108 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -162,7 +162,7 @@ public: void visitMembers(vespalib::ObjectVisitor &visitor) const override; - const attribute::ISearchContext *get_attribute_search_context() const override { + const attribute::ISearchContext *get_attribute_search_context() const noexcept final { return _search_context.get(); } bool getRange(vespalib::string &from, vespalib::string &to) const override; diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index 5eaa2dc40ab..30aee5e0e83 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -644,21 +644,23 @@ IntermediateBlueprint::freeze() namespace { bool -areAnyParentsEquiv(const Blueprint * node) -{ +areAnyParentsEquiv(const Blueprint * node) { return (node != nullptr) && (node->isEquiv() || areAnyParentsEquiv(node->getParent())); } bool -canBlueprintSkipUnpack(const Blueprint & bp, const fef::MatchData & md) -{ +emptyUnpackInfo(const IntermediateBlueprint * intermediate, const fef::MatchData & md) { + return intermediate != nullptr && intermediate->calculateUnpackInfo(md).empty(); +} + +bool +canBlueprintSkipUnpack(const Blueprint & bp, const fef::MatchData & md) { if (bp.always_needs_unpack()) { return false; } - return (bp.isWhiteList() || - (bp.getState().numFields() != 0) || - (bp.isIntermediate() && - static_cast<const IntermediateBlueprint &>(bp).calculateUnpackInfo(md).empty())); + return bp.isWhiteList() || + (bp.getState().numFields() != 0) || + emptyUnpackInfo(bp.asIntermediate(), md); } } diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.h b/searchlib/src/vespa/searchlib/queryeval/blueprint.h index cd0e8f2af40..81d225661d0 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.h @@ -27,6 +27,11 @@ class SearchIterator; class ExecuteInfo; class MatchingElementsSearch; class LeafBlueprint; +class IntermediateBlueprint; +class SourceBlenderBlueprint; +class AndBlueprint; +class AndNotBlueprint; +class OrBlueprint; /** * A Blueprint is an intermediate representation of a search. More @@ -251,16 +256,19 @@ public: vespalib::slime::Cursor & asSlime(const vespalib::slime::Inserter & cursor) const; virtual vespalib::string getClassName() const; virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; - virtual bool isEquiv() const { return false; } - virtual bool isWhiteList() const { return false; } - virtual bool isIntermediate() const { return false; } - virtual LeafBlueprint * asLeaf() noexcept { return nullptr; } - virtual bool isAnd() const { return false; } - virtual bool isAndNot() const { return false; } - virtual bool isOr() const { return false; } - virtual bool isSourceBlender() const { return false; } - virtual bool isRank() const { return false; } - virtual const attribute::ISearchContext *get_attribute_search_context() const { return nullptr; } + virtual bool isEquiv() const noexcept { return false; } + virtual bool isWhiteList() const noexcept { return false; } + virtual IntermediateBlueprint * asIntermediate() noexcept { return nullptr; } + const IntermediateBlueprint * asIntermediate() const noexcept { return const_cast<Blueprint *>(this)->asIntermediate(); } + virtual const LeafBlueprint * asLeaf() const noexcept { return nullptr; } + virtual AndBlueprint * asAnd() noexcept { return nullptr; } + bool isAnd() const noexcept { return const_cast<Blueprint *>(this)->asAnd() != nullptr; } + virtual AndNotBlueprint * asAndNot() noexcept { return nullptr; } + bool isAndNot() const noexcept { return const_cast<Blueprint *>(this)->asAndNot() != nullptr; } + virtual OrBlueprint * asOr() noexcept { return nullptr; } + virtual SourceBlenderBlueprint * asSourceBlender() noexcept { return nullptr; } + virtual bool isRank() const noexcept { return false; } + virtual const attribute::ISearchContext *get_attribute_search_context() const noexcept { return nullptr; } // For document summaries with matched-elements-only set. virtual std::unique_ptr<MatchingElementsSearch> create_matching_elements_search(const MatchingElementsFields &fields) const; @@ -354,7 +362,7 @@ public: void freeze() final; UnpackInfo calculateUnpackInfo(const fef::MatchData & md) const; - bool isIntermediate() const override { return true; } + IntermediateBlueprint * asIntermediate() noexcept final { return this; } }; @@ -400,7 +408,7 @@ public: void fetchPostings(const ExecuteInfo &execInfo) override; void freeze() final; SearchIteratorUP createSearch(fef::MatchData &md, bool strict) const override; - LeafBlueprint * asLeaf() noexcept final { return this; } + const LeafBlueprint * asLeaf() const noexcept final { return this; } virtual bool getRange(vespalib::string & from, vespalib::string & to) const; virtual SearchIteratorUP createLeafSearch(const fef::TermFieldMatchDataArray &tfmda, bool strict) const = 0; diff --git a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h index bc4c68a9e24..df1ea13105a 100644 --- a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h @@ -27,7 +27,7 @@ public: void visitMembers(vespalib::ObjectVisitor &visitor) const override; void fetchPostings(const ExecuteInfo &execInfo) override; - bool isEquiv() const override { return true; } + bool isEquiv() const noexcept final { return true; } }; } diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp index c0439df1c1b..b315965b5f4 100644 --- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp @@ -34,13 +34,13 @@ size_t lookup_create_source(std::vector<std::unique_ptr<CombineType> > &sources, template <typename CombineType> void optimize_source_blenders(IntermediateBlueprint &self, size_t begin_idx) { std::vector<size_t> source_blenders; - SourceBlenderBlueprint *reference = nullptr; + const SourceBlenderBlueprint * reference = nullptr; for (size_t i = begin_idx; i < self.childCnt(); ++i) { - if (self.getChild(i).isSourceBlender()) { - auto *child = static_cast<SourceBlenderBlueprint *>(&self.getChild(i)); - if (reference == nullptr || reference->isCompatibleWith(*child)) { + const SourceBlenderBlueprint * sbChild = self.getChild(i).asSourceBlender(); + if (sbChild) { + if (reference == nullptr || reference->isCompatibleWith(*sbChild)) { source_blenders.push_back(i); - reference = child; + reference = sbChild; } } } @@ -50,16 +50,14 @@ void optimize_source_blenders(IntermediateBlueprint &self, size_t begin_idx) { while (!source_blenders.empty()) { blender_up = self.removeChild(source_blenders.back()); source_blenders.pop_back(); - assert(blender_up->isSourceBlender()); - auto *blender = static_cast<SourceBlenderBlueprint *>(blender_up.get()); + SourceBlenderBlueprint * blender = blender_up->asSourceBlender(); while (blender->childCnt() > 0) { Blueprint::UP child_up = blender->removeChild(blender->childCnt() - 1); size_t source_idx = lookup_create_source(sources, child_up->getSourceId(), self.get_docid_limit()); sources[source_idx]->addChild(std::move(child_up)); } } - assert(blender_up->isSourceBlender()); - auto *top = static_cast<SourceBlenderBlueprint *>(blender_up.get()); + SourceBlenderBlueprint * top = blender_up->asSourceBlender(); while (!sources.empty()) { top->addChild(std::move(sources.back())); sources.pop_back(); @@ -109,8 +107,8 @@ AndNotBlueprint::optimize_self(OptimizePass pass) return; } if (pass == OptimizePass::FIRST) { - if (getChild(0).isAndNot()) { - auto *child = static_cast<AndNotBlueprint *>(&getChild(0)); + AndNotBlueprint * child = getChild(0).asAndNot(); + if (child != nullptr) { while (child->childCnt() > 1) { addChild(child->removeChild(1)); } @@ -197,8 +195,8 @@ AndBlueprint::optimize_self(OptimizePass pass) { if (pass == OptimizePass::FIRST) { for (size_t i = 0; i < childCnt(); ++i) { - if (getChild(i).isAnd()) { - auto *child = static_cast<AndBlueprint *>(&getChild(i)); + AndBlueprint * child = getChild(i).asAnd(); + if (child != nullptr) { while (child->childCnt() > 0) { addChild(child->removeChild(0)); } @@ -299,8 +297,8 @@ OrBlueprint::optimize_self(OptimizePass pass) { if (pass == OptimizePass::FIRST) { for (size_t i = 0; (childCnt() > 1) && (i < childCnt()); ++i) { - if (getChild(i).isOr()) { - auto *child = static_cast<OrBlueprint *>(&getChild(i)); + OrBlueprint * child = getChild(i).asOr(); + if (child != nullptr) { while (child->childCnt() > 0) { addChild(child->removeChild(0)); } diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h index 75dc47272af..6d8082b60f6 100644 --- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h +++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h @@ -18,7 +18,7 @@ public: HitEstimate combine(const std::vector<HitEstimate> &data) const override; FieldSpecBaseList exposeFields() const override; void optimize_self(OptimizePass pass) override; - bool isAndNot() const override { return true; } + AndNotBlueprint * asAndNot() noexcept final { return this; } Blueprint::UP get_replacement() override; void sort(Children &children) const override; bool inheritStrict(size_t i) const override; @@ -44,7 +44,7 @@ public: HitEstimate combine(const std::vector<HitEstimate> &data) const override; FieldSpecBaseList exposeFields() const override; void optimize_self(OptimizePass pass) override; - bool isAnd() const override { return true; } + AndBlueprint * asAnd() noexcept final { return this; } Blueprint::UP get_replacement() override; void sort(Children &children) const override; bool inheritStrict(size_t i) const override; @@ -68,7 +68,7 @@ public: HitEstimate combine(const std::vector<HitEstimate> &data) const override; FieldSpecBaseList exposeFields() const override; void optimize_self(OptimizePass pass) override; - bool isOr() const override { return true; } + OrBlueprint * asOr() noexcept final { return this; } Blueprint::UP get_replacement() override; void sort(Children &children) const override; bool inheritStrict(size_t i) const override; @@ -166,7 +166,7 @@ public: Blueprint::UP get_replacement() override; void sort(Children &children) const override; bool inheritStrict(size_t i) const override; - bool isRank() const override { return true; } + bool isRank() const noexcept final { return true; } SearchIterator::UP createIntermediateSearch(MultiSearch::Children subSearches, bool strict, fef::MatchData &md) const override; @@ -199,7 +199,7 @@ public: /** check if this blueprint has the same source selector as the other */ bool isCompatibleWith(const SourceBlenderBlueprint &other) const; - bool isSourceBlender() const override { return true; } + SourceBlenderBlueprint * asSourceBlender() noexcept final { return this; } uint8_t calculate_cost_tier() const override; }; diff --git a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h index 5710d2c2106..a95ca0efc72 100644 --- a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h +++ b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h @@ -83,7 +83,7 @@ public: return *this; } - const attribute::ISearchContext *get_attribute_search_context() const override { + const attribute::ISearchContext *get_attribute_search_context() const noexcept final { return _ctx.get(); } diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h index cc6331375cf..6a988e67149 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h @@ -26,7 +26,7 @@ public: ~SameElementBlueprint() override; // no match data - bool isWhiteList() const override { return true; } + bool isWhiteList() const noexcept final { return true; } // used by create visitor FieldSpec getNextChildField(const vespalib::string &field_name, uint32_t field_id); diff --git a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp index 2b1ae90e452..e2e9516badf 100644 --- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp @@ -97,7 +97,7 @@ WeightedSetTermBlueprint::createLeafSearch(const fef::TermFieldMatchDataArray &t { assert(tfmda.size() == 1); if ((_terms.size() == 1) && tfmda[0]->isNotNeeded()) { - if (LeafBlueprint * leaf = _terms[0]->asLeaf(); leaf != nullptr) { + if (const LeafBlueprint * leaf = _terms[0]->asLeaf(); leaf != nullptr) { // Always returnin a strict iterator independently of what was required, // as that is what we do with all the children when there are more. return leaf->createLeafSearch(tfmda, true); |