summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2020-06-24 19:40:32 +0200
committerTor Egge <Tor.Egge@broadpark.no>2020-06-25 15:11:33 +0200
commit07344e04b5628b52da54aaeaed6a28fe979e83f1 (patch)
treed876a4c85ff43e66e6412c4bd965877193e24493 /searchlib
parent8109d90cf0249356c21a1f65d009381646e2540b (diff)
Add filter iterators for weighted set blueprints.
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/CMakeLists.txt1
-rw-r--r--searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt10
-rw-r--r--searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp203
-rw-r--r--searchlib/src/vespa/searchlib/attribute/CMakeLists.txt1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp15
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp17
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp80
-rw-r--r--searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h23
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/blueprint.cpp34
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/blueprint.h5
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp19
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp7
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h1
14 files changed, 404 insertions, 13 deletions
diff --git a/searchlib/CMakeLists.txt b/searchlib/CMakeLists.txt
index f6e8d35459e..9b9f1a704cc 100644
--- a/searchlib/CMakeLists.txt
+++ b/searchlib/CMakeLists.txt
@@ -78,6 +78,7 @@ vespa_define_module(
src/tests/attribute/changevector
src/tests/attribute/compaction
src/tests/attribute/document_weight_iterator
+ src/tests/attribute/document_weight_or_filter_search
src/tests/attribute/enum_attribute_compaction
src/tests/attribute/enum_comparator
src/tests/attribute/enumeratedsave
diff --git a/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt b/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt
new file mode 100644
index 00000000000..660cfbaefff
--- /dev/null
+++ b/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+find_package(GTest REQUIRED)
+vespa_add_executable(searchlib_document_weight_or_filter_search_test_app TEST
+ SOURCES
+ document_weight_or_filter_search_test.cpp
+ DEPENDS
+ searchlib
+ GTest::GTest
+)
+vespa_add_test(NAME searchlib_document_weight_or_filter_search_test_app COMMAND searchlib_document_weight_or_filter_search_test_app)
diff --git a/searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp b/searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp
new file mode 100644
index 00000000000..c8e799a8f10
--- /dev/null
+++ b/searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp
@@ -0,0 +1,203 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/vespalib/gtest/gtest.h>
+#include <vespa/searchlib/attribute/i_document_weight_attribute.h>
+#include <vespa/searchlib/attribute/document_weight_or_filter_search.h>
+#include <vespa/searchlib/queryeval/searchiterator.h>
+#include <vespa/searchlib/common/bitvector.h>
+
+using PostingList = search::attribute::PostingListTraits<int32_t>::PostingStoreBase;
+using Iterator = search::attribute::PostingListTraits<int32_t>::const_iterator;
+using KeyData = PostingList::KeyDataType;
+using search::BitVector;
+using search::attribute::DocumentWeightOrFilterSearch;
+using search::queryeval::SearchIterator;
+using vespalib::datastore::EntryRef;
+
+class DocumentWeightOrFilterSearchTest : public ::testing::Test {
+ PostingList _postings;
+ vespalib::GenerationHandler _gens;
+ std::vector<EntryRef> _trees;
+ uint32_t _range_start;
+ uint32_t _range_end;
+protected:
+ DocumentWeightOrFilterSearchTest();
+ ~DocumentWeightOrFilterSearchTest();
+ void inc_generation();
+ size_t num_trees() const { return _trees.size(); }
+ Iterator get_tree(size_t idx) const {
+ if (idx < _trees.size()) {
+ return _postings.beginFrozen(_trees[idx]);
+ } else {
+ return Iterator();
+ }
+ }
+ void ensure_tree(size_t idx) {
+ if (idx <= _trees.size()) {
+ _trees.resize(idx + 1);
+ }
+ }
+ void add_tree(size_t idx, std::vector<uint32_t> keys) {
+ ensure_tree(idx);
+ std::vector<KeyData> adds;
+ std::vector<uint32_t> removes;
+ adds.reserve(keys.size());
+ for (auto& key : keys) {
+ adds.emplace_back(KeyData(key, 1));
+ }
+ _postings.apply(_trees[idx], &*adds.begin(), &*adds.end(), &*removes.begin(), &*removes.end());
+ }
+
+ std::unique_ptr<SearchIterator> make_iterator() const {
+ std::vector<Iterator> iterators;
+ for (size_t i = 0; i < num_trees(); ++i) {
+ iterators.emplace_back(get_tree(i));
+ }
+ auto result = DocumentWeightOrFilterSearch::create(std::move(iterators));
+ result->initRange(_range_start, _range_end);
+ return result;
+ };
+
+ std::vector<uint32_t> eval_daat(SearchIterator &iterator) {
+ std::vector<uint32_t> result;
+ uint32_t doc_id = _range_start;
+ while (doc_id < _range_end) {
+ if (iterator.seek(doc_id)) {
+ result.emplace_back(doc_id);
+ ++doc_id;
+ } else {
+ doc_id = std::max(doc_id + 1, iterator.getDocId());
+ }
+ }
+ return result;
+ }
+
+ std::vector<uint32_t> frombv(const BitVector &bv) {
+ std::vector<uint32_t> result;
+ uint32_t doc_id = _range_start;
+ doc_id = bv.getNextTrueBit(doc_id);
+ while (doc_id < _range_end) {
+ result.emplace_back(doc_id);
+ ++doc_id;
+ doc_id = bv.getNextTrueBit(doc_id);
+ }
+ return result;
+ }
+
+ std::unique_ptr<BitVector> tobv(std::vector<uint32_t> values) {
+ auto bv = BitVector::create(_range_start, _range_end);
+ for (auto value : values) {
+ bv->setBit(value);
+ }
+ bv->invalidateCachedCount();
+ return bv;
+ }
+
+ void expect_result(std::vector<uint32_t> exp, std::vector<uint32_t> act)
+ {
+ EXPECT_EQ(exp, act);
+ }
+
+ void make_sample_data() {
+ add_tree(0, { 10, 11 });
+ add_tree(1, { 14, 17, 20 });
+ add_tree(2, { 3 });
+ add_tree(3, { 17 });
+ }
+
+ uint32_t get_range_start() const { return _range_start; }
+ void set_range(uint32_t start, uint32_t end) {
+ _range_start = start;
+ _range_end = end;
+ }
+};
+
+DocumentWeightOrFilterSearchTest::DocumentWeightOrFilterSearchTest()
+ : _postings(true),
+ _gens(),
+ _range_start(1),
+ _range_end(10000)
+{
+}
+
+DocumentWeightOrFilterSearchTest::~DocumentWeightOrFilterSearchTest()
+{
+ for (auto& tree : _trees) {
+ _postings.clear(tree);
+ }
+ _postings.clearBuilder();
+ _postings.clearHoldLists();
+ inc_generation();
+}
+
+void
+DocumentWeightOrFilterSearchTest::inc_generation()
+{
+ _postings.freeze();
+ _postings.transferHoldLists(_gens.getCurrentGeneration());
+ _gens.incGeneration();
+ _gens.updateFirstUsedGeneration();
+ _postings.trimHoldLists(_gens.getFirstUsedGeneration());
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, daat_or)
+{
+ make_sample_data();
+ expect_result(eval_daat(*make_iterator()), { 3, 10, 11, 14, 17, 20 });
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, taat_get_hits)
+{
+ make_sample_data();
+ expect_result(frombv(*make_iterator()->get_hits(get_range_start())), { 3, 10, 11, 14, 17, 20 });
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, taat_or_hits_into)
+{
+ make_sample_data();
+ auto bv = tobv({13, 14});
+ make_iterator()->or_hits_into(*bv, get_range_start());
+ expect_result(frombv(*bv), { 3, 10, 11, 13, 14, 17, 20 });
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, taat_and_hits_into)
+{
+ make_sample_data();
+ auto bv = tobv({13, 14});
+ make_iterator()->and_hits_into(*bv, get_range_start());
+ expect_result(frombv(*bv), { 14 });
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, daat_or_ranged)
+{
+ make_sample_data();
+ set_range(4, 15);
+ expect_result(eval_daat(*make_iterator()), {10, 11, 14 });
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, taat_get_hits_ranged)
+{
+ make_sample_data();
+ set_range(4, 15);
+ expect_result(frombv(*make_iterator()->get_hits(get_range_start())), { 10, 11, 14 });
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, taat_or_hits_into_ranged)
+{
+ make_sample_data();
+ set_range(4, 15);
+ auto bv = tobv({13, 14});
+ make_iterator()->or_hits_into(*bv, get_range_start());
+ expect_result(frombv(*bv), { 10, 11, 13, 14 });
+}
+
+TEST_F(DocumentWeightOrFilterSearchTest, taat_and_hits_into_ranged)
+{
+ make_sample_data();
+ set_range(4, 15);
+ auto bv = tobv({13, 14});
+ make_iterator()->and_hits_into(*bv, get_range_start());
+ expect_result(frombv(*bv), { 14 });
+}
+
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
index 6ab70e11fc0..bf56b476cc9 100644
--- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
+++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
@@ -34,6 +34,7 @@ vespa_add_library(searchlib_attribute OBJECT
defines.cpp
diversity.cpp
dociditerator.cpp
+ document_weight_or_filter_search.cpp
searchcontextelementiterator.cpp
enumattribute.cpp
enumattributesaver.cpp
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
index 84bed6bb5e9..c4467df5a1c 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
@@ -6,6 +6,7 @@
#include "iterator_pack.h"
#include "predicate_attribute.h"
#include "attribute_blueprint_params.h"
+#include "document_weight_or_filter_search.h"
#include <vespa/eval/eval/value.h>
#include <vespa/eval/tensor/dense/dense_tensor_view.h>
#include <vespa/searchlib/common/location.h>
@@ -342,8 +343,22 @@ public:
}
return SearchType::create(*tfmda[0], _weights, std::move(iterators));
}
+
+ std::unique_ptr<SearchIterator> createFilterSearch(bool strict, FilterConstraint constraint) const override;
};
+template <typename SearchType>
+std::unique_ptr<SearchIterator>
+DirectWeightedSetBlueprint<SearchType>::createFilterSearch(bool, FilterConstraint) const
+{
+ std::vector<DocumentWeightIterator> iterators;
+ iterators.reserve(_terms.size());
+ for (const IDocumentWeightAttribute::LookupResult &r : _terms) {
+ _attr.create(r.posting_idx, iterators);
+ }
+ return attribute::DocumentWeightOrFilterSearch::create(std::move(iterators));
+}
+
//-----------------------------------------------------------------------------
class DirectWandBlueprint : public queryeval::ComplexLeafBlueprint
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp
index 121cb736471..0959476158f 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp
@@ -9,6 +9,8 @@
#include <vespa/vespalib/objects/visit.h>
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/vespalib/stllike/hash_map.hpp>
+#include <vespa/searchlib/queryeval/filter_wrapper.h>
+#include <vespa/searchlib/queryeval/orsearch.h>
namespace search {
@@ -182,6 +184,21 @@ AttributeWeightedSetBlueprint::createLeafSearch(const fef::TermFieldMatchDataArr
}
}
+queryeval::SearchIterator::UP
+AttributeWeightedSetBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const
+{
+ (void) constraint;
+ std::vector<std::unique_ptr<queryeval::SearchIterator>> children;
+ children.reserve(_contexts.size());
+ for (auto& context : _contexts) {
+ auto wrapper = std::make_unique<search::queryeval::FilterWrapper>(1);
+ wrapper->wrap(context->createIterator(wrapper->tfmda()[0], strict));
+ children.emplace_back(std::move(wrapper));
+ }
+ search::queryeval::UnpackInfo unpack_info;
+ return search::queryeval::OrSearch::create(std::move(children), strict, unpack_info);
+}
+
void
AttributeWeightedSetBlueprint::fetchPostings(const queryeval::ExecuteInfo &execInfo)
{
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h
index 6af3405c91d..7ab11aace81 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h
@@ -29,6 +29,7 @@ public:
~AttributeWeightedSetBlueprint();
void addToken(std::unique_ptr<ISearchContext> context, int32_t weight);
queryeval::SearchIterator::UP createLeafSearch(const fef::TermFieldMatchDataArray &tfmda, bool strict) const override;
+ queryeval::SearchIterator::UP createFilterSearch(bool strict, FilterConstraint constraint) const override;
void fetchPostings(const queryeval::ExecuteInfo &execInfo) override;
void visitMembers(vespalib::ObjectVisitor &visitor) const override;
};
diff --git a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp
new file mode 100644
index 00000000000..9a181c37250
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp
@@ -0,0 +1,80 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "document_weight_or_filter_search.h"
+#include "iterator_pack.h"
+#include <vespa/searchlib/common/bitvector.h>
+#include <vespa/searchlib/queryeval/emptysearch.h>
+
+namespace search::attribute {
+
+class DocumentWeightOrFilterSearchImpl : public DocumentWeightOrFilterSearch
+{
+ AttributeIteratorPack _children;
+public:
+ DocumentWeightOrFilterSearchImpl(AttributeIteratorPack&& children);
+ ~DocumentWeightOrFilterSearchImpl();
+
+ void doSeek(uint32_t docId) override;
+
+ void doUnpack(uint32_t) override;
+
+ void initRange(uint32_t begin, uint32_t end) override {
+ SearchIterator::initRange(begin, end);
+ _children.initRange(begin, end);
+ }
+
+ void or_hits_into(BitVector &result, uint32_t begin_id) override {
+ return _children.or_hits_into(result, begin_id);
+ }
+
+ void and_hits_into(BitVector &result, uint32_t begin_id) override {
+ return result.andWith(*get_hits(begin_id));
+ }
+
+ std::unique_ptr<BitVector> get_hits(uint32_t begin_id) override {
+ return _children.get_hits(begin_id, getEndId());
+ }
+
+ Trinary is_strict() const override { return Trinary::True; }
+};
+
+DocumentWeightOrFilterSearchImpl::DocumentWeightOrFilterSearchImpl(AttributeIteratorPack&& children)
+ : DocumentWeightOrFilterSearch(),
+ _children(std::move(children))
+{
+}
+
+DocumentWeightOrFilterSearchImpl::~DocumentWeightOrFilterSearchImpl() = default;
+
+void
+DocumentWeightOrFilterSearchImpl::doSeek(uint32_t docId)
+{
+ if (_children.get_docid(0) < docId) {
+ _children.seek(0, docId);
+ }
+ uint32_t min_doc_id = _children.get_docid(0);
+ for (unsigned int i = 1; min_doc_id > docId && i < _children.size(); ++i) {
+ if (_children.get_docid(i) < docId) {
+ _children.seek(i, docId);
+ }
+ min_doc_id = std::min(min_doc_id, _children.get_docid(i));
+ }
+ setDocId(min_doc_id);
+}
+
+void
+DocumentWeightOrFilterSearchImpl::doUnpack(uint32_t)
+{
+}
+
+std::unique_ptr<search::queryeval::SearchIterator>
+DocumentWeightOrFilterSearch::create(std::vector<DocumentWeightIterator>&& children)
+{
+ if (children.empty()) {
+ return std::make_unique<queryeval::EmptySearch>();
+ } else {
+ return std::make_unique<DocumentWeightOrFilterSearchImpl>(AttributeIteratorPack(std::move(children)));
+ }
+}
+
+}
diff --git a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h
new file mode 100644
index 00000000000..d9721871b81
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h
@@ -0,0 +1,23 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "i_document_weight_attribute.h"
+#include <vespa/searchlib/queryeval/searchiterator.h>
+
+namespace search::attribute {
+
+/**
+ * Filter iterator on top of document weight iterators with OR semantics used during
+ * calculation of global filter for weighted set terms, wand terms and dot product terms.
+ */
+class DocumentWeightOrFilterSearch : public search::queryeval::SearchIterator
+{
+protected:
+ DocumentWeightOrFilterSearch()
+ : search::queryeval::SearchIterator()
+ {
+ }
+public:
+ static std::unique_ptr<search::queryeval::SearchIterator> create(std::vector<DocumentWeightIterator>&& children);
+};
+
+}
diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp
index 1a7a0c5eba2..0b4b5b29a8c 100644
--- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp
@@ -6,6 +6,8 @@
#include "emptysearch.h"
#include "full_search.h"
#include "field_spec.hpp"
+#include "andsearch.h"
+#include "orsearch.h"
#include <vespa/searchlib/fef/termfieldmatchdataarray.h>
#include <vespa/vespalib/objects/visit.hpp>
#include <vespa/vespalib/objects/objectdumper.h>
@@ -132,6 +134,38 @@ Blueprint::createFilterSearch(bool /*strict*/, FilterConstraint constraint) cons
}
}
+namespace {
+
+template <typename Op>
+std::unique_ptr<SearchIterator>
+create_op_filter(const std::vector<Blueprint *>& children, bool strict, Blueprint::FilterConstraint constraint)
+{
+ MultiSearch::Children sub_searches;
+ sub_searches.reserve(children.size());
+ for (size_t i = 0; i < children.size(); ++i) {
+ bool child_strict = strict && (std::is_same_v<Op,AndSearch> ? (i == 0) : true);
+ auto search = children[i]->createFilterSearch(child_strict, constraint);
+ sub_searches.push_back(std::move(search));
+ }
+ UnpackInfo unpack_info;
+ auto search = Op::create(std::move(sub_searches), strict, unpack_info);
+ return search;
+}
+
+}
+
+std::unique_ptr<SearchIterator>
+Blueprint::create_and_filter(const std::vector<Blueprint *>& children, bool strict, Blueprint::FilterConstraint constraint)
+{
+ return create_op_filter<AndSearch>(children, strict, constraint);
+}
+
+std::unique_ptr<SearchIterator>
+Blueprint::create_or_filter(const std::vector<Blueprint *>& children, bool strict, Blueprint::FilterConstraint constraint)
+{
+ return create_op_filter<OrSearch>(children, strict, constraint);
+}
+
vespalib::string
Blueprint::asString() const
{
diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.h b/searchlib/src/vespa/searchlib/queryeval/blueprint.h
index ef15736073e..1ee58f8b97d 100644
--- a/searchlib/src/vespa/searchlib/queryeval/blueprint.h
+++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.h
@@ -208,6 +208,9 @@ public:
virtual SearchIteratorUP createSearch(fef::MatchData &md, bool strict) const = 0;
virtual SearchIteratorUP createFilterSearch(bool strict, FilterConstraint constraint) const;
+ static std::unique_ptr<SearchIterator> create_and_filter(const std::vector<Blueprint *>& children, bool strict, FilterConstraint constraint);
+ static std::unique_ptr<SearchIterator> create_or_filter(const std::vector<Blueprint *>& children, bool strict, FilterConstraint constraint);
+
// for debug dumping
vespalib::string asString() const;
vespalib::slime::Cursor & asSlime(const vespalib::slime::Inserter & cursor) const;
@@ -274,6 +277,8 @@ protected:
bool should_do_termwise_eval(const UnpackInfo &unpack, double match_limit) const;
+ const Children& get_children() const { return _children; }
+
public:
typedef std::vector<size_t> IndexList;
IntermediateBlueprint();
diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp
index 3d3a703cd7b..aa65342c114 100644
--- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp
@@ -84,18 +84,11 @@ need_normal_features_for_children(const IntermediateBlueprint &blueprint, fef::M
/** utility for operators that degrade to AND when creating filter */
SearchIterator::UP createAndFilter(const IntermediateBlueprint &self,
+ const std::vector<Blueprint *>& children,
bool strict, Blueprint::FilterConstraint constraint)
{
- MultiSearch::Children sub_searches;
- sub_searches.reserve(self.childCnt());
- for (size_t i = 0; i < self.childCnt(); ++i) {
- bool child_strict = strict && (i == 0);
- auto search = self.getChild(i).createFilterSearch(child_strict, constraint);
- sub_searches.push_back(std::move(search));
- }
- UnpackInfo unpack_info;
- auto search = AndSearch::create(std::move(sub_searches), strict, unpack_info);
- search->estimate(self.getState().estimate().estHits);
+ auto search = Blueprint::create_and_filter(children, strict, constraint);
+ static_cast<AndSearch &>(*search).estimate(self.getState().estimate().estHits);
return search;
}
@@ -292,7 +285,7 @@ AndBlueprint::createIntermediateSearch(MultiSearch::Children sub_searches,
SearchIterator::UP
AndBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const
{
- return createAndFilter(*this, strict, constraint);
+ return createAndFilter(*this, get_children(), strict, constraint);
}
double
@@ -492,7 +485,7 @@ SearchIterator::UP
NearBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const
{
if (constraint == Blueprint::FilterConstraint::UPPER_BOUND) {
- return createAndFilter(*this, strict, constraint);
+ return createAndFilter(*this, get_children(), strict, constraint);
} else {
return std::make_unique<EmptySearch>();
}
@@ -552,7 +545,7 @@ SearchIterator::UP
ONearBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const
{
if (constraint == Blueprint::FilterConstraint::UPPER_BOUND) {
- return createAndFilter(*this, strict, constraint);
+ return createAndFilter(*this, get_children(), strict, constraint);
} else {
return std::make_unique<EmptySearch>();
}
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 cea35d976f0..3cfa928da87 100644
--- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp
@@ -2,6 +2,7 @@
#include "weighted_set_term_blueprint.h"
#include "weighted_set_term_search.h"
+#include "orsearch.h"
#include <vespa/vespalib/objects/visit.hpp>
namespace search::queryeval {
@@ -56,6 +57,12 @@ WeightedSetTermBlueprint::createLeafSearch(const fef::TermFieldMatchDataArray &t
return SearchIterator::UP(WeightedSetTermSearch::create(children, *tfmda[0], _weights, std::move(md)));
}
+SearchIterator::UP
+WeightedSetTermBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const
+{
+ return create_or_filter(_terms, strict, constraint);
+}
+
void
WeightedSetTermBlueprint::fetchPostings(const ExecuteInfo &execInfo)
{
diff --git a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h
index 8ae42607a9d..864e3e7fc7f 100644
--- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h
+++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h
@@ -34,6 +34,7 @@ public:
void addTerm(Blueprint::UP term, int32_t weight);
SearchIteratorUP createLeafSearch(const fef::TermFieldMatchDataArray &tfmda, bool strict) const override;
+ SearchIteratorUP createFilterSearch(bool strict, FilterConstraint constraint) const override;
void visitMembers(vespalib::ObjectVisitor &visitor) const override;
private: