summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2023-12-11 11:22:38 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2023-12-11 11:22:38 +0000
commit4cff8bc199f18e5f2db39ba08e844d906dde2dad (patch)
tree0dc5c459c3d69cddb5314bf9a0b6a84c81471e16 /searchcore
parent8bd3d0f7c319117d7045d8035993687929daff83 (diff)
Move whitelist into BlueprintBuilder::build
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp106
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.h11
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/query.cpp38
3 files changed, 84 insertions, 71 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
index 092fbd85d56..c03d93b6480 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
@@ -12,6 +12,7 @@
#include <vespa/vespalib/util/issue.h>
using namespace search::queryeval;
+using search::query::Node;
namespace proton::matching {
@@ -59,29 +60,17 @@ private:
ISearchContext &_context;
Blueprint::UP _result;
- void buildChildren(IntermediateBlueprint &parent,
- const std::vector<search::query::Node *> &children)
- {
- parent.reserve(children.size());
- for (size_t i = 0; i < children.size(); ++i) {
- parent.addChild(BlueprintBuilder::build(_requestContext, *children[i], _context));
- }
- }
+ void buildChildren(IntermediateBlueprint &parent, const std::vector<Node *> &children);
template <typename NodeType>
- void buildIntermediate(IntermediateBlueprint *b, NodeType &n) {
- std::unique_ptr<IntermediateBlueprint> blueprint(b);
- buildChildren(*blueprint, n.getChildren());
- _result.reset(blueprint.release());
- }
+ void buildIntermediate(IntermediateBlueprint *b, NodeType &n) __attribute__((noinline));
void buildWeakAnd(ProtonWeakAnd &n) {
- WeakAndBlueprint *wand = new WeakAndBlueprint(n.getTargetNumHits());
+ auto *wand = new WeakAndBlueprint(n.getTargetNumHits());
Blueprint::UP result(wand);
- for (size_t i = 0; i < n.getChildren().size(); ++i) {
- search::query::Node &node = *n.getChildren()[i];
- uint32_t weight = getWeightFromNode(node).percent();
- wand->addTerm(BlueprintBuilder::build(_requestContext, node, _context), weight);
+ for (auto node : n.getChildren()) {
+ uint32_t weight = getWeightFromNode(*node).percent();
+ wand->addTerm(build(_requestContext, *node, _context), weight);
}
_result = std::move(result);
}
@@ -93,12 +82,11 @@ private:
for (size_t i = 0; i < n.numFields(); ++i) {
specs.add(n.field(i).fieldSpec());
}
- EquivBlueprint *eq = new EquivBlueprint(std::move(specs), n.children_mdl);
+ auto *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];
- double w = getWeightFromNode(node).percent();
- eq->addTerm(BlueprintBuilder::build(_requestContext, node, _context), w / eqw);
+ for (auto node : n.getChildren()) {
+ double w = getWeightFromNode(*node).percent();
+ eq->addTerm(build(_requestContext, *node, _context), w / eqw);
}
n.setDocumentFrequency(_result->getState().estimate().estHits, _context.getDocIdLimit());
}
@@ -106,7 +94,7 @@ private:
void buildSameElement(ProtonSameElement &n) {
if (n.numFields() == 1) {
SameElementBuilder builder(_requestContext, _context, n.field(0).fieldSpec(), n.is_expensive());
- for (search::query::Node *node: n.getChildren()) {
+ for (Node *node: n.getChildren()) {
builder.add_child(*node);
}
_result = builder.build();
@@ -183,20 +171,74 @@ public:
assert(_result);
return std::move(_result);
}
+ static Blueprint::UP build(const IRequestContext & requestContext, Node &node, ISearchContext &context) {
+ BlueprintBuilderVisitor visitor(requestContext, context);
+ node.accept(visitor);
+ Blueprint::UP result = visitor.build();
+ return result;
+
+ }
};
+void
+BlueprintBuilderVisitor::buildChildren(IntermediateBlueprint &parent, const std::vector<Node *> &children)
+{
+ parent.reserve(children.size());
+ for (auto child : children) {
+ parent.addChild(build(_requestContext, *child, _context));
+ }
+}
+
+template <typename NodeType>
+void
+BlueprintBuilderVisitor::buildIntermediate(IntermediateBlueprint *b, NodeType &n) {
+ std::unique_ptr<IntermediateBlueprint> blueprint(b);
+ buildChildren(*blueprint, n.getChildren());
+ _result = std::move(blueprint);
+}
+
+IntermediateBlueprint *
+asRankOrAndNot(Blueprint * blueprint) {
+ return ((blueprint->isAndNot() || blueprint->isRank()))
+ ? blueprint->asIntermediate()
+ : nullptr;
+}
+
+IntermediateBlueprint *
+lastConsequtiveRankOrAndNot(Blueprint * blueprint) {
+ IntermediateBlueprint * prev = nullptr;
+ IntermediateBlueprint * curr = asRankOrAndNot(blueprint);
+ while (curr != nullptr) {
+ prev = curr;
+ curr = asRankOrAndNot(&curr->getChild(0));
+ }
+ return prev;
+}
+
} // namespace proton::matching::<unnamed>
-search::queryeval::Blueprint::UP
+Blueprint::UP
BlueprintBuilder::build(const IRequestContext & requestContext,
- search::query::Node &node,
- ISearchContext &context)
+ Node &node, Blueprint::UP whiteList, ISearchContext &context)
{
- BlueprintBuilderVisitor visitor(requestContext, context);
- node.accept(visitor);
- Blueprint::UP result = visitor.build();
- result->setDocIdLimit(context.getDocIdLimit());
- return result;
+ auto blueprint = BlueprintBuilderVisitor::build(requestContext, node, context);
+ if (whiteList) {
+ auto andBlueprint = std::make_unique<AndBlueprint>();
+ IntermediateBlueprint * rankOrAndNot = lastConsequtiveRankOrAndNot(blueprint.get());
+ if (rankOrAndNot != nullptr) {
+ (*andBlueprint)
+ .addChild(rankOrAndNot->removeChild(0))
+ .addChild(std::move(whiteList));
+ rankOrAndNot->insertChild(0, std::move(andBlueprint));
+ } else {
+ (*andBlueprint)
+ .addChild(std::move(blueprint))
+ .addChild(std::move(whiteList));
+ blueprint = std::move(andBlueprint);
+ }
+ }
+ blueprint->setDocIdLimit(context.getDocIdLimit());
+ return blueprint;
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.h b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.h
index aa7b7a2094e..d07fc19ceaf 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.h
@@ -11,12 +11,19 @@ namespace search::queryeval { class IRequestContext; }
namespace proton::matching {
struct BlueprintBuilder {
+ using IRequestContext = search::queryeval::IRequestContext;
+ using Blueprint = search::queryeval::Blueprint;
+ using Node = search::query::Node;
/**
* Build a tree of blueprints from the query tree and inject
* blueprint meta-data back into corresponding query tree nodes.
*/
- static search::queryeval::Blueprint::UP
- build(const search::queryeval::IRequestContext & requestContext, search::query::Node &node, ISearchContext &context);
+ static Blueprint::UP
+ build(const IRequestContext & requestContext, Node &node, ISearchContext &context) {
+ return build(requestContext, node, {}, context);
+ }
+ static Blueprint::UP
+ build(const IRequestContext & requestContext, Node &node, Blueprint::UP whiteList, ISearchContext &context);
};
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/query.cpp b/searchcore/src/vespa/searchcore/proton/matching/query.cpp
index 250a53591d4..e41af3771a0 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/query.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/query.cpp
@@ -140,24 +140,6 @@ void exchange_location_nodes(const string &location_str,
}
}
-IntermediateBlueprint *
-asRankOrAndNot(Blueprint * blueprint) {
- return ((blueprint->isAndNot() || blueprint->isRank()))
- ? blueprint->asIntermediate()
- : nullptr;
-}
-
-IntermediateBlueprint *
-lastConsequtiveRankOrAndNot(Blueprint * blueprint) {
- IntermediateBlueprint * prev = nullptr;
- IntermediateBlueprint * curr = asRankOrAndNot(blueprint);
- while (curr != nullptr) {
- prev = curr;
- curr = asRankOrAndNot(&curr->getChild(0));
- }
- return prev;
-}
-
} // namespace
Query::Query() = default;
@@ -211,26 +193,8 @@ Query::reserveHandles(const IRequestContext & requestContext, ISearchContext &co
MatchDataReserveVisitor reserve_visitor(mdl);
_query_tree->accept(reserve_visitor);
- _blueprint = BlueprintBuilder::build(requestContext, *_query_tree, context);
+ _blueprint = BlueprintBuilder::build(requestContext, *_query_tree, std::move(_whiteListBlueprint), context);
LOG(debug, "original blueprint:\n%s\n", _blueprint->asString().c_str());
- if (_whiteListBlueprint) {
- auto andBlueprint = std::make_unique<AndBlueprint>();
- IntermediateBlueprint * rankOrAndNot = lastConsequtiveRankOrAndNot(_blueprint.get());
- if (rankOrAndNot != nullptr) {
- (*andBlueprint)
- .addChild(rankOrAndNot->removeChild(0))
- .addChild(std::move(_whiteListBlueprint))
- .setDocIdLimit(context.getDocIdLimit());
- rankOrAndNot->insertChild(0, std::move(andBlueprint));
- } else {
- (*andBlueprint)
- .addChild(std::move(_blueprint))
- .addChild(std::move(_whiteListBlueprint))
- .setDocIdLimit(context.getDocIdLimit());
- _blueprint = std::move(andBlueprint);
- }
- LOG(debug, "blueprint after white listing:\n%s\n", _blueprint->asString().c_str());
- }
}
void