diff options
Diffstat (limited to 'searchlib')
3 files changed, 45 insertions, 0 deletions
diff --git a/searchlib/src/tests/queryeval/same_element/same_element_test.cpp b/searchlib/src/tests/queryeval/same_element/same_element_test.cpp index 6ec379140c0..c24a11833e7 100644 --- a/searchlib/src/tests/queryeval/same_element/same_element_test.cpp +++ b/searchlib/src/tests/queryeval/same_element/same_element_test.cpp @@ -14,6 +14,13 @@ using namespace search::fef; using namespace search::queryeval; using search::attribute::ElementIterator; +void verify_elements(SameElementSearch &se, uint32_t docid, const std::initializer_list<uint32_t> list) { + std::vector<uint32_t> expect(list); + std::vector<uint32_t> actual; + se.find_matching_elements(docid, actual); + EXPECT_EQUAL(actual, expect); +} + std::unique_ptr<SameElementBlueprint> make_blueprint(const std::vector<FakeResult> &children, bool fake_attr = false) { auto result = std::make_unique<SameElementBlueprint>(false); for (size_t i = 0; i < children.size(); ++i) { @@ -61,6 +68,20 @@ TEST("require that simple match can be found") { EXPECT_EQUAL(result, expect); } +TEST("require that matching elements can be identified") { + auto a = make_result({{5, {1,3,7,12}}, {10, {1,2,3}}}); + auto b = make_result({{5, {3,5,7,10}}, {10, {4,5,6}}}); + auto bp = finalize(make_blueprint({a,b}), false); + auto md = MatchData::makeTestInstance(0, 0); + auto search = bp->createSearch(*md, false); + search->initRange(1, 1000); + SameElementSearch *se = dynamic_cast<SameElementSearch*>(search.get()); + ASSERT_TRUE(se != nullptr); + TEST_DO(verify_elements(*se, 5, {3, 7})); + TEST_DO(verify_elements(*se, 10, {})); + TEST_DO(verify_elements(*se, 20, {})); +} + TEST("require that children must match within same element") { auto a = make_result({{5, {1,3,7}}}); auto b = make_result({{5, {2,5,10}}}); diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp b/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp index 8f3fc9c350d..37f8eccadd9 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp @@ -114,4 +114,22 @@ SameElementSearch::visitMembers(vespalib::ObjectVisitor &visitor) const visit(visitor, "strict", _strict); } +void +SameElementSearch::find_matching_elements(uint32_t docid, std::vector<uint32_t> &dst) +{ + if (check_docid_match(docid)) { + unpack_children(docid); + int32_t cand = 0; + while (cand >= 0) { + int32_t next = try_match(_childMatch, _iterators, cand); + if (next == cand) { + dst.push_back(cand); + ++cand; + } else { + cand = next; + } + } + } +} + } diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_search.h b/searchlib/src/vespa/searchlib/queryeval/same_element_search.h index 1fd381eb1ae..ae7ecab781d 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_search.h +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_search.h @@ -6,6 +6,7 @@ #include <vespa/searchlib/fef/matchdata.h> #include <vespa/searchlib/fef/termfieldmatchdataarray.h> #include <vespa/searchlib/fef/termfieldmatchdata.h> +#include <vespa/searchlib/common/matching_elements.h> #include <memory> #include <vector> @@ -40,6 +41,11 @@ public: void doUnpack(uint32_t) override {} void visitMembers(vespalib::ObjectVisitor &visitor) const override; const std::vector<SearchIterator::UP> &children() const { return _children; } + + // used during docsum fetching to identify matching elements + // initRange must be called before use. + // doSeek/doUnpack must not be called. + void find_matching_elements(uint32_t docid, std::vector<uint32_t> &dst); }; } |