summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2019-09-23 12:35:50 +0000
committerHåvard Pettersen <havardpe@oath.com>2019-09-23 12:35:50 +0000
commit21786e4d5ec36cb05b62bb01514998b0a2875974 (patch)
tree3de77ed095e032a00edaec68ce7957c610c4cb9a /searchlib
parent5c038ce0dd067ccd5eca723d577fe123c031f7a0 (diff)
added low-level code used to identify matching elements
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/queryeval/same_element/same_element_test.cpp21
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp18
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_search.h6
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);
};
}