diff options
Diffstat (limited to 'searchlib')
20 files changed, 316 insertions, 293 deletions
diff --git a/searchlib/CMakeLists.txt b/searchlib/CMakeLists.txt index 9b9f1a704cc..1db9018bd21 100644 --- a/searchlib/CMakeLists.txt +++ b/searchlib/CMakeLists.txt @@ -187,11 +187,9 @@ vespa_define_module( src/tests/query src/tests/queryeval src/tests/queryeval/blueprint - src/tests/queryeval/booleanmatchiteratorwrapper src/tests/queryeval/dot_product src/tests/queryeval/equiv src/tests/queryeval/fake_searchable - src/tests/queryeval/filter_wrapper src/tests/queryeval/getnodeweight src/tests/queryeval/monitoring_search_iterator src/tests/queryeval/multibitvectoriterator @@ -207,6 +205,7 @@ vespa_define_module( src/tests/queryeval/weak_and_heap src/tests/queryeval/weak_and_scorers src/tests/queryeval/weighted_set_term + src/tests/queryeval/wrappers src/tests/rankingexpression/feature_name_extractor src/tests/rankingexpression/intrinsic_blueprint_adapter src/tests/ranksetup diff --git a/searchlib/abi-spec.json b/searchlib/abi-spec.json index c22d906e2b2..0768999c52f 100644 --- a/searchlib/abi-spec.json +++ b/searchlib/abi-spec.json @@ -1614,6 +1614,7 @@ "public com.yahoo.tensor.functions.TensorFunction withArguments(java.util.List)", "public com.yahoo.tensor.functions.PrimitiveTensorFunction toPrimitive()", "public com.yahoo.tensor.TensorType type(com.yahoo.tensor.evaluation.TypeContext)", + "public java.util.Optional asScalarFunction()", "public com.yahoo.tensor.Tensor evaluate(com.yahoo.tensor.evaluation.EvaluationContext)", "public java.lang.String toString()", "public java.lang.String toString(com.yahoo.tensor.functions.ToStringContext)" diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java index befe2179dc1..86541343edb 100644 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java @@ -25,6 +25,7 @@ import java.util.Deque; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -157,6 +158,11 @@ public class TensorFunctionNode extends CompositeNode { } @Override + public Optional<TensorFunction<Reference>> asTensorFunction() { + return Optional.of(new ExpressionTensorFunction(expression)); + } + + @Override public String toString() { return toString(ExpressionToStringContext.empty); } @@ -230,6 +236,11 @@ public class TensorFunctionNode extends CompositeNode { } @Override + public Optional<ScalarFunction<Reference>> asScalarFunction() { + return Optional.of(new ExpressionScalarFunction(expression)); + } + + @Override public Tensor evaluate(EvaluationContext<Reference> context) { return expression.evaluate((Context)context).asTensor(); } diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/ConstantDereferencerTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/ConstantDereferencerTestCase.java index a41fb02f784..bfaff0712ee 100644 --- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/ConstantDereferencerTestCase.java +++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/ConstantDereferencerTestCase.java @@ -29,6 +29,8 @@ public class ConstantDereferencerTestCase { assertEquals("1.0 + 2.0 + 3.5", c.transform(new RankingExpression("a + b + c"), context).toString()); assertEquals("myFunction(1.0,2.0)", c.transform(new RankingExpression("myFunction(a, b)"), context).toString()); + assertEquals("tensor(x[2],y[3])((x + y == 1.0))", c.transform(new RankingExpression("tensor(x[2],y[3])(x+y==a)"), context).toString()); + } } 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 index 660cfbaefff..8f25f6b66b8 100644 --- a/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt +++ b/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt @@ -5,6 +5,7 @@ vespa_add_executable(searchlib_document_weight_or_filter_search_test_app TEST document_weight_or_filter_search_test.cpp DEPENDS searchlib + searchlib_test 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 index c8e799a8f10..22f928ddf45 100644 --- 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 @@ -5,6 +5,8 @@ #include <vespa/searchlib/attribute/document_weight_or_filter_search.h> #include <vespa/searchlib/queryeval/searchiterator.h> #include <vespa/searchlib/common/bitvector.h> +#define ENABLE_GTEST_MIGRATION +#include <vespa/searchlib/test/searchiteratorverifier.h> using PostingList = search::attribute::PostingListTraits<int32_t>::PostingStoreBase; using Iterator = search::attribute::PostingListTraits<int32_t>::const_iterator; @@ -20,7 +22,7 @@ class DocumentWeightOrFilterSearchTest : public ::testing::Test { std::vector<EntryRef> _trees; uint32_t _range_start; uint32_t _range_end; -protected: +public: DocumentWeightOrFilterSearchTest(); ~DocumentWeightOrFilterSearchTest(); void inc_generation(); @@ -48,6 +50,13 @@ protected: _postings.apply(_trees[idx], &*adds.begin(), &*adds.end(), &*removes.begin(), &*removes.end()); } + void clear_tree(size_t idx) { + if (idx < _trees.size()) { + _postings.clear(_trees[idx]); + _trees[idx] = EntryRef(); + } + } + std::unique_ptr<SearchIterator> make_iterator() const { std::vector<Iterator> iterators; for (size_t i = 0; i < num_trees(); ++i) { @@ -200,4 +209,53 @@ TEST_F(DocumentWeightOrFilterSearchTest, taat_and_hits_into_ranged) expect_result(frombv(*bv), { 14 }); } +namespace { + +class Verifier : public search::test::SearchIteratorVerifier { + DocumentWeightOrFilterSearchTest &_test; +public: + Verifier(DocumentWeightOrFilterSearchTest &test, int num_trees) + : _test(test) + { + std::vector<std::vector<uint32_t>> trees(num_trees); + uint32_t tree_id = 0; + for (const auto doc_id : getExpectedDocIds()) { + trees[tree_id++ % trees.size()].emplace_back(doc_id); + } + tree_id = 0; + for (const auto &tree : trees) { + _test.add_tree(tree_id++, tree); + } + _test.inc_generation(); + } + ~Verifier() { + for (uint32_t tree_id = 0; tree_id < _test.num_trees(); ++tree_id) { + _test.clear_tree(tree_id); + } + _test.inc_generation(); + } + std::unique_ptr<SearchIterator> create(bool) const override { + return _test.make_iterator(); + } + +}; + +TEST_F(DocumentWeightOrFilterSearchTest, iterator_conformance) +{ + { + Verifier verifier(*this, 1); + verifier.verify(); + } + { + Verifier verifier(*this, 2); + verifier.verify(); + } + { + Verifier verifier(*this, 3); + verifier.verify(); + } +} + +} + GTEST_MAIN_RUN_ALL_TESTS() diff --git a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/.cvsignore b/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/.cvsignore deleted file mode 100644 index 9e6565f9d16..00000000000 --- a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.depend -Makefile -booleanmatchiteratorwrapper_test diff --git a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/.gitignore b/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/.gitignore deleted file mode 100644 index b568b87514a..00000000000 --- a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.depend -Makefile -booleanmatchiteratorwrapper_test -searchlib_booleanmatchiteratorwrapper_test_app diff --git a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/CMakeLists.txt b/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/CMakeLists.txt deleted file mode 100644 index d97fe5b12d7..00000000000 --- a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(searchlib_booleanmatchiteratorwrapper_test_app TEST - SOURCES - booleanmatchiteratorwrapper_test.cpp - DEPENDS - searchlib - searchlib_test -) -vespa_add_test(NAME searchlib_booleanmatchiteratorwrapper_test_app COMMAND searchlib_booleanmatchiteratorwrapper_test_app) diff --git a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/booleanmatchiteratorwrapper_test.cpp b/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/booleanmatchiteratorwrapper_test.cpp deleted file mode 100644 index 7d4551a5c7d..00000000000 --- a/searchlib/src/tests/queryeval/booleanmatchiteratorwrapper/booleanmatchiteratorwrapper_test.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/vespalib/testkit/testapp.h> -#include <vespa/searchlib/queryeval/booleanmatchiteratorwrapper.h> -#include <vespa/searchlib/fef/termfieldmatchdata.h> -#include <vespa/searchlib/common/bitvectoriterator.h> -#include <vespa/searchlib/test/searchiteratorverifier.h> - -using namespace search::fef; -using namespace search::queryeval; -using search::BitVector; -using search::BitVectorIterator; - -struct DummyItr : public SearchIterator { - static uint32_t seekCnt; - static uint32_t unpackCnt; - static uint32_t dtorCnt; - static uint32_t _unpackedDocId; - TermFieldMatchData *match; - - DummyItr(TermFieldMatchData *m) { - match = m; - } - - ~DummyItr() { - ++dtorCnt; - } - - void doSeek(uint32_t docid) override { - ++seekCnt; - if (docid <= 10) { - setDocId(10); - } else if (docid <= 20) { - setDocId(20); - } else { - setAtEnd(); - } - } - - void doUnpack(uint32_t docid) override { - ++unpackCnt; - if (match != 0) { - _unpackedDocId = docid; - } - } -}; -uint32_t DummyItr::seekCnt = 0; -uint32_t DummyItr::unpackCnt = 0; -uint32_t DummyItr::dtorCnt = 0; -uint32_t DummyItr::_unpackedDocId = 0; - - -TEST("mostly everything") { - EXPECT_EQUAL(DummyItr::seekCnt, 0u); - EXPECT_EQUAL(DummyItr::unpackCnt, 0u); - EXPECT_EQUAL(DummyItr::dtorCnt, 0u); - { // without wrapper - TermFieldMatchData match; - DummyItr::_unpackedDocId = 0; - SearchIterator::UP search(new DummyItr(&match)); - search->initFullRange(); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(1u)); - EXPECT_EQUAL(search->getDocId(), 10u); - EXPECT_TRUE(search->seek(10)); - search->unpack(10); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 10u); - EXPECT_TRUE(!search->seek(15)); - EXPECT_EQUAL(search->getDocId(), 20u); - EXPECT_TRUE(search->seek(20)); - search->unpack(20); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 20u); - EXPECT_TRUE(!search->seek(25)); - EXPECT_TRUE(search->isAtEnd()); - } - EXPECT_EQUAL(DummyItr::seekCnt, 3u); - EXPECT_EQUAL(DummyItr::unpackCnt, 2u); - EXPECT_EQUAL(DummyItr::dtorCnt, 1u); - { // with wrapper - TermFieldMatchData match; - TermFieldMatchDataArray tfmda; - tfmda.add(&match); - DummyItr::_unpackedDocId = 0; - SearchIterator::UP search(new BooleanMatchIteratorWrapper(SearchIterator::UP(new DummyItr(&match)), tfmda)); - search->initFullRange(); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(1u)); - EXPECT_EQUAL(search->getDocId(), 10u); - EXPECT_TRUE(search->seek(10)); - search->unpack(10); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(15)); - EXPECT_EQUAL(search->getDocId(), 20u); - EXPECT_TRUE(search->seek(20)); - search->unpack(20); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(25)); - EXPECT_TRUE(search->isAtEnd()); - } - EXPECT_EQUAL(DummyItr::seekCnt, 6u); - EXPECT_EQUAL(DummyItr::unpackCnt, 2u); - EXPECT_EQUAL(DummyItr::dtorCnt, 2u); - { // with wrapper, without match data - SearchIterator::UP search(new BooleanMatchIteratorWrapper(SearchIterator::UP(new DummyItr(0)), TermFieldMatchDataArray())); - search->initFullRange(); - EXPECT_TRUE(!search->seek(1u)); - EXPECT_EQUAL(search->getDocId(), 10u); - EXPECT_TRUE(search->seek(10)); - search->unpack(10); - EXPECT_TRUE(!search->seek(15)); - EXPECT_EQUAL(search->getDocId(), 20u); - EXPECT_TRUE(search->seek(20)); - search->unpack(20); - EXPECT_TRUE(!search->seek(25)); - EXPECT_TRUE(search->isAtEnd()); - } - EXPECT_EQUAL(DummyItr::seekCnt, 9u); - EXPECT_EQUAL(DummyItr::unpackCnt, 2u); - EXPECT_EQUAL(DummyItr::dtorCnt, 3u); -} - -class Verifier : public search::test::SearchIteratorVerifier { -public: - ~Verifier(); - SearchIterator::UP create(bool strict) const override { - return std::make_unique<BooleanMatchIteratorWrapper>(createIterator(getExpectedDocIds(), strict), _tfmda);; - } -private: - mutable TermFieldMatchDataArray _tfmda; -}; - -Verifier::~Verifier() {} - -TEST("Test that boolean wrapper iterators adheres to SearchIterator requirements") { - Verifier searchIteratorVerifier; - searchIteratorVerifier.verify(); -} - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/searchlib/src/tests/queryeval/filter_wrapper/CMakeLists.txt b/searchlib/src/tests/queryeval/filter_wrapper/CMakeLists.txt deleted file mode 100644 index bab956e73bb..00000000000 --- a/searchlib/src/tests/queryeval/filter_wrapper/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -vespa_add_executable(searchlib_filter_wrapper_test_app TEST - SOURCES - filter_wrapper_test.cpp - DEPENDS - searchlib - searchlib_test -) -vespa_add_test(NAME searchlib_filter_wrapper_test_app COMMAND searchlib_filter_wrapper_test_app) diff --git a/searchlib/src/tests/queryeval/filter_wrapper/filter_wrapper_test.cpp b/searchlib/src/tests/queryeval/filter_wrapper/filter_wrapper_test.cpp deleted file mode 100644 index 707f51c551a..00000000000 --- a/searchlib/src/tests/queryeval/filter_wrapper/filter_wrapper_test.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/vespalib/testkit/testapp.h> -#include <vespa/searchlib/queryeval/filter_wrapper.h> -#include <vespa/searchlib/fef/termfieldmatchdata.h> -#include <vespa/searchlib/common/bitvectoriterator.h> -#include <vespa/searchlib/test/searchiteratorverifier.h> - -using namespace search::fef; -using namespace search::queryeval; -using search::BitVector; -using search::BitVectorIterator; - -struct DummyItr : public SearchIterator { - static uint32_t seekCnt; - static uint32_t unpackCnt; - static uint32_t dtorCnt; - static uint32_t _unpackedDocId; - TermFieldMatchData *match; - - DummyItr(TermFieldMatchData *m) { - match = m; - } - - ~DummyItr() { - ++dtorCnt; - } - - void doSeek(uint32_t docid) override { - ++seekCnt; - if (docid <= 10) { - setDocId(10); - } else if (docid <= 20) { - setDocId(20); - } else { - setAtEnd(); - } - } - - void doUnpack(uint32_t docid) override { - ++unpackCnt; - if (match != 0) { - _unpackedDocId = docid; - } - } -}; -uint32_t DummyItr::seekCnt = 0; -uint32_t DummyItr::unpackCnt = 0; -uint32_t DummyItr::dtorCnt = 0; -uint32_t DummyItr::_unpackedDocId = 0; - - -TEST("filter wrapper forwards as expected") { - EXPECT_EQUAL(DummyItr::seekCnt, 0u); - EXPECT_EQUAL(DummyItr::unpackCnt, 0u); - EXPECT_EQUAL(DummyItr::dtorCnt, 0u); - { // without wrapper - TermFieldMatchData match; - DummyItr::_unpackedDocId = 0; - SearchIterator::UP search(new DummyItr(&match)); - search->initFullRange(); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(1u)); - EXPECT_EQUAL(search->getDocId(), 10u); - EXPECT_TRUE(search->seek(10)); - search->unpack(10); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 10u); - EXPECT_TRUE(!search->seek(15)); - EXPECT_EQUAL(search->getDocId(), 20u); - EXPECT_TRUE(search->seek(20)); - search->unpack(20); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 20u); - EXPECT_TRUE(!search->seek(25)); - EXPECT_TRUE(search->isAtEnd()); - } - EXPECT_EQUAL(DummyItr::seekCnt, 3u); - EXPECT_EQUAL(DummyItr::unpackCnt, 2u); - EXPECT_EQUAL(DummyItr::dtorCnt, 1u); - { // with wrapper - TermFieldMatchData match; - TermFieldMatchDataArray tfmda; - tfmda.add(&match); - DummyItr::_unpackedDocId = 0; - auto search = std::make_unique<FilterWrapper>(1); - auto to_wrap = std::make_unique<DummyItr>(search->tfmda()[0]); - search->wrap(std::move(to_wrap)); - search->initFullRange(); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(1u)); - EXPECT_EQUAL(search->getDocId(), 10u); - EXPECT_TRUE(search->seek(10)); - search->unpack(10); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(15)); - EXPECT_EQUAL(search->getDocId(), 20u); - EXPECT_TRUE(search->seek(20)); - search->unpack(20); - EXPECT_EQUAL(DummyItr::_unpackedDocId, 0u); - EXPECT_TRUE(!search->seek(25)); - EXPECT_TRUE(search->isAtEnd()); - } - EXPECT_EQUAL(DummyItr::seekCnt, 6u); - EXPECT_EQUAL(DummyItr::unpackCnt, 2u); - EXPECT_EQUAL(DummyItr::dtorCnt, 2u); -} - -class Verifier : public search::test::SearchIteratorVerifier { -public: - ~Verifier(); - SearchIterator::UP create(bool strict) const override { - auto search = std::make_unique<FilterWrapper>(1); - search->wrap(createIterator(getExpectedDocIds(), strict)); - return search; - } -}; - -Verifier::~Verifier() {} - -TEST("Test that filter wrapper iterators adheres to SearchIterator requirements") { - Verifier searchIteratorVerifier; - searchIteratorVerifier.verify(); -} - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/searchlib/src/tests/queryeval/wrappers/CMakeLists.txt b/searchlib/src/tests/queryeval/wrappers/CMakeLists.txt new file mode 100644 index 00000000000..d1d566b1cab --- /dev/null +++ b/searchlib/src/tests/queryeval/wrappers/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +vespa_add_executable(searchlib_wrappers_test_app TEST + SOURCES + wrappers_test.cpp + DEPENDS + searchlib + searchlib_test + gtest +) +vespa_add_test(NAME searchlib_wrappers_test_app COMMAND searchlib_wrappers_test_app) diff --git a/searchlib/src/tests/queryeval/wrappers/wrappers_test.cpp b/searchlib/src/tests/queryeval/wrappers/wrappers_test.cpp new file mode 100644 index 00000000000..62bff93ab0e --- /dev/null +++ b/searchlib/src/tests/queryeval/wrappers/wrappers_test.cpp @@ -0,0 +1,197 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/searchlib/queryeval/filter_wrapper.h> +#include <vespa/searchlib/queryeval/booleanmatchiteratorwrapper.h> +#include <vespa/searchlib/fef/termfieldmatchdata.h> +#include <vespa/vespalib/gtest/gtest.h> + +#define ENABLE_GTEST_MIGRATION +#include <vespa/searchlib/test/searchiteratorverifier.h> + +using namespace search::fef; +using namespace search::queryeval; + +struct ObservedData { + uint32_t seekCnt; + uint32_t unpackCnt; + uint32_t dtorCnt; + uint32_t unpackedDocId; +}; + +class WrapperTest : public ::testing::Test { +public: + class DummyItr : public SearchIterator { + private: + ObservedData &_data; + TermFieldMatchData *_match; + public: + DummyItr(ObservedData &data, TermFieldMatchData *m) : _data(data), _match(m) {} + ~DummyItr() { + ++_data.dtorCnt; + } + void doSeek(uint32_t docid) override { + ++_data.seekCnt; + if (docid <= 10) { + setDocId(10); + } else if (docid <= 20) { + setDocId(20); + } else { + setAtEnd(); + } + } + void doUnpack(uint32_t docid) override { + ++_data.unpackCnt; + if (_match != 0) { + _data.unpackedDocId = docid; + } + } + }; + WrapperTest() : _data{0,0,0,0} {} +protected: + ObservedData _data; + + void verify_unwrapped() { + EXPECT_EQ(_data.seekCnt, 0u); + EXPECT_EQ(_data.unpackCnt, 0u); + EXPECT_EQ(_data.dtorCnt, 0u); + + // without wrapper + TermFieldMatchData match; + _data.unpackedDocId = 0; + auto search = std::make_unique<DummyItr>(_data, &match); + search->initFullRange(); + EXPECT_EQ(_data.unpackedDocId, 0u); + EXPECT_TRUE(!search->seek(1u)); + EXPECT_EQ(search->getDocId(), 10u); + EXPECT_TRUE(search->seek(10)); + search->unpack(10); + EXPECT_EQ(_data.unpackedDocId, 10u); + EXPECT_TRUE(!search->seek(15)); + EXPECT_EQ(search->getDocId(), 20u); + EXPECT_TRUE(search->seek(20)); + search->unpack(20); + EXPECT_EQ(_data.unpackedDocId, 20u); + EXPECT_TRUE(!search->seek(25)); + EXPECT_TRUE(search->isAtEnd()); + + search.reset(nullptr); + EXPECT_EQ(_data.seekCnt, 3u); + EXPECT_EQ(_data.unpackCnt, 2u); + EXPECT_EQ(_data.dtorCnt, 1u); + } +}; + +TEST_F(WrapperTest, filter_wrapper) +{ + verify_unwrapped(); + + // with FilterWrapper + TermFieldMatchData match; + TermFieldMatchDataArray tfmda; + tfmda.add(&match); + _data.unpackedDocId = 0; + auto search = std::make_unique<FilterWrapper>(1); +search->wrap(std::make_unique<DummyItr>(_data, search->tfmda()[0])); + search->initFullRange(); + EXPECT_EQ(_data.unpackedDocId, 0u); + EXPECT_TRUE(!search->seek(1u)); + EXPECT_EQ(search->getDocId(), 10u); + EXPECT_TRUE(search->seek(10)); + search->unpack(10); + EXPECT_EQ(_data.unpackedDocId, 0u); + EXPECT_TRUE(!search->seek(15)); + EXPECT_EQ(search->getDocId(), 20u); + EXPECT_TRUE(search->seek(20)); + search->unpack(20); + EXPECT_EQ(_data.unpackedDocId, 0u); + EXPECT_TRUE(!search->seek(25)); + EXPECT_TRUE(search->isAtEnd()); + + search.reset(nullptr); + EXPECT_EQ(_data.seekCnt, 6u); + EXPECT_EQ(_data.unpackCnt, 2u); + EXPECT_EQ(_data.dtorCnt, 2u); +} + +TEST_F(WrapperTest, boolean_match_iterator_wrapper) +{ + verify_unwrapped(); + { // with wrapper + TermFieldMatchData match; + TermFieldMatchDataArray tfmda; + tfmda.add(&match); + _data.unpackedDocId = 0; + auto to_wrap = std::make_unique<DummyItr>(_data, &match); + auto search = std::make_unique<BooleanMatchIteratorWrapper>(std::move(to_wrap), tfmda); + search->initFullRange(); + EXPECT_EQ(_data.unpackedDocId, 0u); + EXPECT_TRUE(!search->seek(1u)); + EXPECT_EQ(search->getDocId(), 10u); + EXPECT_TRUE(search->seek(10)); + search->unpack(10); + EXPECT_EQ(_data.unpackedDocId, 0u); + EXPECT_TRUE(!search->seek(15)); + EXPECT_EQ(search->getDocId(), 20u); + EXPECT_TRUE(search->seek(20)); + search->unpack(20); + EXPECT_EQ(_data.unpackedDocId, 0u); + EXPECT_TRUE(!search->seek(25)); + EXPECT_TRUE(search->isAtEnd()); + } + EXPECT_EQ(_data.seekCnt, 6u); + EXPECT_EQ(_data.unpackCnt, 2u); + EXPECT_EQ(_data.dtorCnt, 2u); + { // with wrapper, without match data + + auto to_wrap = std::make_unique<DummyItr>(_data, nullptr); + auto search = std::make_unique<BooleanMatchIteratorWrapper>(std::move(to_wrap), TermFieldMatchDataArray()); + search->initFullRange(); + EXPECT_TRUE(!search->seek(1u)); + EXPECT_EQ(search->getDocId(), 10u); + EXPECT_TRUE(search->seek(10)); + search->unpack(10); + EXPECT_TRUE(!search->seek(15)); + EXPECT_EQ(search->getDocId(), 20u); + EXPECT_TRUE(search->seek(20)); + search->unpack(20); + EXPECT_TRUE(!search->seek(25)); + EXPECT_TRUE(search->isAtEnd()); + } + EXPECT_EQ(_data.seekCnt, 9u); + EXPECT_EQ(_data.unpackCnt, 2u); + EXPECT_EQ(_data.dtorCnt, 3u); +} + +class FilterWrapperVerifier : public search::test::SearchIteratorVerifier { +public: + ~FilterWrapperVerifier() {} + SearchIterator::UP create(bool strict) const override { + auto search = std::make_unique<FilterWrapper>(1); + search->wrap(createIterator(getExpectedDocIds(), strict)); + return search; + } +}; + +TEST(FilterWrapperTest, adheres_to_search_iterator_requirements) +{ + FilterWrapperVerifier verifier; + verifier.verify(); +} + +class BooleanMatchIteratorWrapperVerifier : public search::test::SearchIteratorVerifier { +public: + SearchIterator::UP create(bool strict) const override { + return std::make_unique<BooleanMatchIteratorWrapper>(createIterator(getExpectedDocIds(), strict), _tfmda); + } + ~BooleanMatchIteratorWrapperVerifier() {} +private: + mutable TermFieldMatchDataArray _tfmda; +}; + +TEST(BooleanMatchIteratorWrapperWrapperTest, adheres_to_search_iterator_requirements) +{ + BooleanMatchIteratorWrapperVerifier verifier; + verifier.verify(); +} + +GTEST_MAIN_RUN_ALL_TESTS() 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 index 35c5ce75f33..d9134417d27 100644 --- a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp +++ b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp @@ -53,7 +53,7 @@ DocumentWeightOrFilterSearchImpl::doSeek(uint32_t docId) _children.seek(0, docId); } uint32_t min_doc_id = _children.get_docid(0); - for (uint16_t i = 1; min_doc_id > docId && i < _children.size(); ++i) { + for (uint16_t i = 1; i < _children.size(); ++i) { if (_children.get_docid(i) < docId) { _children.seek(i, docId); } diff --git a/searchlib/src/vespa/searchlib/test/CMakeLists.txt b/searchlib/src/vespa/searchlib/test/CMakeLists.txt index 41084148c87..4d722e687ef 100644 --- a/searchlib/src/vespa/searchlib/test/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/test/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +find_package(GTest REQUIRED) vespa_add_library(searchlib_test SOURCES document_weight_attribute_helper.cpp @@ -12,7 +13,17 @@ vespa_add_library(searchlib_test statestring.cpp $<TARGET_OBJECTS:searchlib_test_fakedata> $<TARGET_OBJECTS:searchlib_searchlib_test_diskindex> + $<TARGET_OBJECTS:searchlib_test_gtest_migration> DEPENDS searchlib searchlib_searchlib_test_memoryindex + GTest::GTest ) + +vespa_add_library(searchlib_test_gtest_migration OBJECT + SOURCES + initrange.cpp + searchiteratorverifier.cpp +) + +target_compile_definitions(searchlib_test_gtest_migration PRIVATE ENABLE_GTEST_MIGRATION) diff --git a/searchlib/src/vespa/searchlib/test/initrange.cpp b/searchlib/src/vespa/searchlib/test/initrange.cpp index 2292a8e775e..1e23f7c5b8c 100644 --- a/searchlib/src/vespa/searchlib/test/initrange.cpp +++ b/searchlib/src/vespa/searchlib/test/initrange.cpp @@ -1,6 +1,12 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "initrange.h" +#ifdef ENABLE_GTEST_MIGRATION +#include <vespa/vespalib/gtest/gtest.h> +#define ASSERT_EQUAL ASSERT_EQ +#define EXPECT_EQUAL EXPECT_EQ +#else #include <vespa/vespalib/testkit/test_kit.h> +#endif #include <vespa/searchlib/queryeval/emptysearch.h> #include <vespa/searchlib/queryeval/truesearch.h> #include <algorithm> diff --git a/searchlib/src/vespa/searchlib/test/initrange.h b/searchlib/src/vespa/searchlib/test/initrange.h index a143dfdb119..4fbb851779a 100644 --- a/searchlib/src/vespa/searchlib/test/initrange.h +++ b/searchlib/src/vespa/searchlib/test/initrange.h @@ -7,6 +7,10 @@ namespace search::test { +#ifdef ENABLE_GTEST_MIGRATION +#define InitRangeVerifier InitRangeVerifierForGTest +#endif + class InitRangeVerifier { public: typedef queryeval::SearchIterator SearchIterator; diff --git a/searchlib/src/vespa/searchlib/test/searchiteratorverifier.cpp b/searchlib/src/vespa/searchlib/test/searchiteratorverifier.cpp index ec53d6d9d00..276f8fbc08d 100644 --- a/searchlib/src/vespa/searchlib/test/searchiteratorverifier.cpp +++ b/searchlib/src/vespa/searchlib/test/searchiteratorverifier.cpp @@ -2,7 +2,14 @@ #include "searchiteratorverifier.h" #include "initrange.h" +#ifdef ENABLE_GTEST_MIGRATION +#include <vespa/vespalib/gtest/gtest.h> +#define TEST_DO(x) x +#define EXPECT_EQUAL EXPECT_EQ +#define ASSERT_EQUAL ASSERT_EQ +#else #include <vespa/vespalib/testkit/test_kit.h> +#endif #include <vespa/searchlib/queryeval/emptysearch.h> #include <vespa/searchlib/queryeval/truesearch.h> #include <vespa/searchlib/queryeval/termwise_search.h> diff --git a/searchlib/src/vespa/searchlib/test/searchiteratorverifier.h b/searchlib/src/vespa/searchlib/test/searchiteratorverifier.h index 3d35731dab1..afeb46f0c16 100644 --- a/searchlib/src/vespa/searchlib/test/searchiteratorverifier.h +++ b/searchlib/src/vespa/searchlib/test/searchiteratorverifier.h @@ -7,6 +7,10 @@ namespace search::test { +#ifdef ENABLE_GTEST_MIGRATION +#define SearchIteratorVerifier SearchIteratorVerifierForGTest +#endif + class SearchIteratorVerifier { public: typedef queryeval::SearchIterator SearchIterator; |