aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2023-11-22 16:02:38 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2023-11-22 16:17:19 +0000
commit10586103aa69d192dea6351375c75522d187bb41 (patch)
treeb621a271606ca4c4f87ff4c61d22d29e56d798ec
parent40fca839012e79e792b94f22cb7de5846acd1433 (diff)
Avoid casting by adding asXXX methods to the Blueprint interface.
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/lid_allocator.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/query.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/rangequerylocator.cpp20
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/blueprint.cpp18
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/blueprint.h32
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.h2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp28
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h10
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.h2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp2
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);