diff options
Diffstat (limited to 'searchlib/src/vespa')
5 files changed, 56 insertions, 21 deletions
diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index 2f69c45d418..f3539c6989a 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -481,6 +481,12 @@ IntermediateBlueprint::count_termwise_nodes(const UnpackInfo &unpack) const return termwise_nodes; } +FlowCalc +IntermediateBlueprint::make_flow_calc(bool strict, double flow) const +{ + return full_flow_calc(strict, flow); +} + IntermediateBlueprint::IndexList IntermediateBlueprint::find(const IPredicate & pred) const { @@ -538,13 +544,6 @@ IntermediateBlueprint::calculateState() const return state; } -double -IntermediateBlueprint::computeNextHitRate(const Blueprint & child, double hit_rate) const -{ - (void) child; - return hit_rate; -} - bool IntermediateBlueprint::should_do_termwise_eval(const UnpackInfo &unpack, double match_limit) const { @@ -648,11 +647,11 @@ IntermediateBlueprint::visitMembers(vespalib::ObjectVisitor &visitor) const void IntermediateBlueprint::fetchPostings(const ExecuteInfo &execInfo) { - double nextHitRate = execInfo.hit_rate(); + FlowCalc flow_calc = make_flow_calc(execInfo.is_strict(), execInfo.hit_rate()); for (size_t i = 0; i < _children.size(); ++i) { Blueprint & child = *_children[i]; + double nextHitRate = flow_calc(child.estimate()); child.fetchPostings(ExecuteInfo::create(execInfo.is_strict() && inheritStrict(i), nextHitRate, execInfo)); - nextHitRate = computeNextHitRate(child, nextHitRate); } } diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.h b/searchlib/src/vespa/searchlib/queryeval/blueprint.h index 439eff680ec..395512d84cc 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.h @@ -362,7 +362,7 @@ private: bool infer_want_global_filter() const; size_t count_termwise_nodes(const UnpackInfo &unpack) const; - virtual double computeNextHitRate(const Blueprint & child, double hit_rate) const; + virtual FlowCalc make_flow_calc(bool strict, double flow) const; protected: // returns an empty collection if children have empty or diff --git a/searchlib/src/vespa/searchlib/queryeval/flow.h b/searchlib/src/vespa/searchlib/queryeval/flow.h index cfbb28b190f..f31122166d9 100644 --- a/searchlib/src/vespa/searchlib/queryeval/flow.h +++ b/searchlib/src/vespa/searchlib/queryeval/flow.h @@ -4,7 +4,7 @@ #include <vespa/vespalib/util/small_vector.h> #include <cstddef> #include <algorithm> -#include <cmath> +#include <functional> // Model how boolean result decisions flow through intermediate nodes // of different types based on relative estimates for sub-expressions @@ -280,4 +280,38 @@ public: } }; +using FlowCalc = std::function<double(double)>; + +template <typename FLOW> +FlowCalc flow_calc(bool strict, double non_strict_rate) { + FLOW flow = strict ? FLOW(true) : FLOW(non_strict_rate); + return [flow](double est) mutable noexcept { + double next_flow = flow.flow(); + flow.add(est); + return next_flow; + }; +} + +inline FlowCalc first_flow_calc(bool strict, double flow) { + if (strict) { + flow = 1.0; + } + bool first = true; + return [flow,first](double est) mutable noexcept { + double next_flow = flow; + if (first) { + flow *= est; + first = false; + } + return next_flow; + }; +} + +inline FlowCalc full_flow_calc(bool strict, double flow) { + if (strict) { + flow = 1.0; + } + return [flow](double) noexcept { return flow; }; +} + } diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp index 993639becf2..6faa4ddf147 100644 --- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp @@ -300,14 +300,10 @@ AndBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const return create_and_filter(get_children(), strict, constraint); } -double -AndBlueprint::computeNextHitRate(const Blueprint & child, double hit_rate) const { - return hit_rate * child.estimate(); -} - -double -OrBlueprint::computeNextHitRate(const Blueprint & child, double hit_rate) const { - return hit_rate * (1.0 - child.estimate()); +FlowCalc +AndBlueprint::make_flow_calc(bool strict, double flow) const +{ + return flow_calc<AndFlow>(strict, flow); } //----------------------------------------------------------------------------- @@ -404,6 +400,12 @@ OrBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const return create_or_filter(get_children(), strict, constraint); } +FlowCalc +OrBlueprint::make_flow_calc(bool strict, double flow) const +{ + return flow_calc<OrFlow>(strict, flow); +} + uint8_t OrBlueprint::calculate_cost_tier() const { diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h index 1da70b4fa70..25586022535 100644 --- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h +++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h @@ -56,7 +56,7 @@ public: SearchIterator::UP createFilterSearch(bool strict, FilterConstraint constraint) const override; private: - double computeNextHitRate(const Blueprint & child, double hit_rate) const override; + virtual FlowCalc make_flow_calc(bool strict, double flow) const override; }; //----------------------------------------------------------------------------- @@ -81,7 +81,7 @@ public: SearchIterator::UP createFilterSearch(bool strict, FilterConstraint constraint) const override; private: - double computeNextHitRate(const Blueprint & child, double hit_rate) const override; + FlowCalc make_flow_calc(bool strict, double flow) const override; uint8_t calculate_cost_tier() const override; }; |