summaryrefslogtreecommitdiffstats
path: root/searchlib/src/tests
diff options
context:
space:
mode:
authorTor Egge <tegge@vespa.ai>2024-01-23 12:13:54 +0100
committerGitHub <noreply@github.com>2024-01-23 12:13:54 +0100
commit056a486a55fd66c39b9b30065865d29655f338f7 (patch)
treeeeef486a9fe8327a2fdbe55fa6700869d54de338 /searchlib/src/tests
parent3f6a2f98c452bc34ab7947d9b93594e7f74e46e1 (diff)
parent6b1bc00a239215eba984a1c0c7e1fbe5f8560bac (diff)
Merge pull request #30018 from vespa-engine/toregge/add-hit-iterator-pack
Add hit iterator pack and use it for phrase search in streaming mode.
Diffstat (limited to 'searchlib/src/tests')
-rw-r--r--searchlib/src/tests/query/streaming/CMakeLists.txt19
-rw-r--r--searchlib/src/tests/query/streaming/hit_iterator_pack_test.cpp44
-rw-r--r--searchlib/src/tests/query/streaming/hit_iterator_test.cpp122
3 files changed, 185 insertions, 0 deletions
diff --git a/searchlib/src/tests/query/streaming/CMakeLists.txt b/searchlib/src/tests/query/streaming/CMakeLists.txt
new file mode 100644
index 00000000000..d40250fbc3f
--- /dev/null
+++ b/searchlib/src/tests/query/streaming/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+vespa_add_executable(searchlib_query_streaming_hit_iterator_test_app TEST
+ SOURCES
+ hit_iterator_test.cpp
+ DEPENDS
+ searchlib
+ GTest::gtest
+)
+vespa_add_test(NAME searchlib_query_streaming_hit_iterator_test_app COMMAND searchlib_query_streaming_hit_iterator_test_app)
+
+vespa_add_executable(searchlib_query_streaming_hit_iterator_pack_test_app TEST
+ SOURCES
+ hit_iterator_pack_test.cpp
+ DEPENDS
+ searchlib
+ GTest::gtest
+)
+vespa_add_test(NAME searchlib_query_streaming_hit_iterator_pack_test_app COMMAND searchlib_query_streaming_hit_iterator_pack_test_app)
diff --git a/searchlib/src/tests/query/streaming/hit_iterator_pack_test.cpp b/searchlib/src/tests/query/streaming/hit_iterator_pack_test.cpp
new file mode 100644
index 00000000000..7d7d8307920
--- /dev/null
+++ b/searchlib/src/tests/query/streaming/hit_iterator_pack_test.cpp
@@ -0,0 +1,44 @@
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/searchlib/query/streaming/hit_iterator_pack.h>
+#include <vespa/vespalib/gtest/gtest.h>
+
+using search::streaming::HitIterator;
+using search::streaming::HitIteratorPack;
+using search::streaming::QueryNodeList;
+using search::streaming::QueryTerm;
+using search::streaming::QueryNodeResultBase;
+
+using FieldElement = HitIterator::FieldElement;
+
+TEST(HitIteratorPackTest, seek_to_matching_field_element)
+{
+ QueryNodeList qnl;
+ auto qt = std::make_unique<QueryTerm>(std::unique_ptr<QueryNodeResultBase>(), "7", "", QueryTerm::Type::WORD);
+ qt->add(11, 0, 10, 0);
+ qt->add(11, 0, 10, 5);
+ qt->add(11, 1, 12, 0);
+ qt->add(11, 1, 12, 0);
+ qt->add(12, 1, 13, 0);
+ qt->add(12, 1, 13, 0);
+ qnl.emplace_back(std::move(qt));
+ qt = std::make_unique<QueryTerm>(std::unique_ptr<QueryNodeResultBase>(), "8", "", QueryTerm::Type::WORD);
+ qt->add(2, 0, 4, 0);
+ qt->add(11, 0, 10, 0);
+ qt->add(12, 1, 13, 0);
+ qt->add(12, 2, 14, 0);
+ qnl.emplace_back(std::move(qt));
+ HitIteratorPack itr_pack(qnl);
+ EXPECT_TRUE(itr_pack.all_valid());
+ EXPECT_TRUE(itr_pack.seek_to_matching_field_element());
+ EXPECT_EQ(FieldElement(11, 0), itr_pack.get_field_element_ref());
+ EXPECT_TRUE(itr_pack.seek_to_matching_field_element());
+ EXPECT_EQ(FieldElement(11, 0), itr_pack.get_field_element_ref());
+ ++itr_pack.get_field_element_ref().second;
+ EXPECT_TRUE(itr_pack.seek_to_matching_field_element());
+ EXPECT_EQ(FieldElement(12, 1), itr_pack.get_field_element_ref());
+ ++itr_pack.get_field_element_ref().second;
+ EXPECT_FALSE(itr_pack.seek_to_matching_field_element());
+}
+
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/searchlib/src/tests/query/streaming/hit_iterator_test.cpp b/searchlib/src/tests/query/streaming/hit_iterator_test.cpp
new file mode 100644
index 00000000000..a9588ea3d6c
--- /dev/null
+++ b/searchlib/src/tests/query/streaming/hit_iterator_test.cpp
@@ -0,0 +1,122 @@
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/searchlib/query/streaming/hit_iterator.h>
+#include <vespa/vespalib/gtest/gtest.h>
+
+using search::streaming::Hit;
+using search::streaming::HitList;
+using search::streaming::HitIterator;
+
+using FieldElement = HitIterator::FieldElement;
+
+namespace {
+
+HitList
+make_hit_list()
+{
+ HitList hl;
+ hl.emplace_back(11, 0, 10, 0);
+ hl.emplace_back(11, 0, 10, 5);
+ hl.emplace_back(11, 1, 12, 0);
+ hl.emplace_back(11, 1, 12, 7);
+ hl.emplace_back(12, 1, 13, 0);
+ hl.emplace_back(12, 1, 13, 9);
+ return hl;
+}
+
+void
+check_seek_to_field_elem(HitIterator& it, const FieldElement& field_element, const Hit* exp_ptr, const vespalib::string& label)
+{
+ SCOPED_TRACE(label);
+ EXPECT_TRUE(it.seek_to_field_element(field_element));
+ EXPECT_TRUE(it.valid());
+ EXPECT_EQ(exp_ptr, &*it);
+}
+
+void
+check_seek_to_field_elem_failure(HitIterator& it, const FieldElement& field_element, const vespalib::string& label)
+{
+ SCOPED_TRACE(label);
+ EXPECT_FALSE(it.seek_to_field_element(field_element));
+ EXPECT_FALSE(it.valid());
+}
+
+void
+check_step_in_field_element(HitIterator& it, FieldElement& field_element, bool exp_success, const Hit* exp_ptr, const vespalib::string& label)
+{
+ SCOPED_TRACE(label);
+ EXPECT_EQ(exp_success, it.step_in_field_element(field_element));
+ if (exp_ptr) {
+ EXPECT_TRUE(it.valid());
+ EXPECT_EQ(it.get_field_element(), field_element);
+ EXPECT_EQ(exp_ptr, &*it);
+ } else {
+ EXPECT_FALSE(it.valid());
+ }
+}
+
+void
+check_seek_in_field_element(HitIterator& it, uint32_t position, FieldElement& field_element, bool exp_success, const Hit* exp_ptr, const vespalib::string& label)
+{
+ SCOPED_TRACE(label);
+ EXPECT_EQ(exp_success, it.seek_in_field_element(position, field_element));
+ if (exp_ptr) {
+ EXPECT_TRUE(it.valid());
+ EXPECT_EQ(it.get_field_element(), field_element);
+ EXPECT_EQ(exp_ptr, &*it);
+ } else {
+ EXPECT_FALSE(it.valid());
+ }
+}
+
+}
+
+TEST(HitITeratorTest, seek_to_field_element)
+{
+ auto hl = make_hit_list();
+ HitIterator it(hl);
+ EXPECT_TRUE(it.valid());
+ EXPECT_EQ(&hl[0], &*it);
+ check_seek_to_field_elem(it, FieldElement(0, 0), &hl[0], "(0, 0)");
+ check_seek_to_field_elem(it, FieldElement(11, 0), &hl[0], "(11, 0)");
+ check_seek_to_field_elem(it, FieldElement(11, 1), &hl[2], "(11, 1)");
+ check_seek_to_field_elem(it, FieldElement(11, 2), &hl[4], "(11, 2)");
+ check_seek_to_field_elem(it, FieldElement(12, 0), &hl[4], "(12, 0)");
+ check_seek_to_field_elem(it, FieldElement(12, 1), &hl[4], "(12, 1)");
+ check_seek_to_field_elem_failure(it, FieldElement(12, 2), "(12, 2)");
+ check_seek_to_field_elem_failure(it, FieldElement(13, 0), "(13, 0)");
+}
+
+TEST(HitIteratorTest, step_in_field_element)
+{
+ auto hl = make_hit_list();
+ HitIterator it(hl);
+ auto field_element = it.get_field_element();
+ check_step_in_field_element(it, field_element, true, &hl[1], "1");
+ check_step_in_field_element(it, field_element, false, &hl[2], "2");
+ check_step_in_field_element(it, field_element, true, &hl[3], "3");
+ check_step_in_field_element(it, field_element, false, &hl[4], "4");
+ check_step_in_field_element(it, field_element, true, &hl[5], "5");
+ check_step_in_field_element(it, field_element, false, nullptr, "end");
+}
+
+TEST(hitIteratorTest, seek_in_field_elem)
+{
+ auto hl = make_hit_list();
+ HitIterator it(hl);
+ auto field_element = it.get_field_element();
+ check_seek_in_field_element(it, 0, field_element, true, &hl[0], "0a");
+ check_seek_in_field_element(it, 2, field_element, true, &hl[1], "2");
+ check_seek_in_field_element(it, 5, field_element, true, &hl[1], "5");
+ check_seek_in_field_element(it, 6, field_element, false, &hl[2], "6");
+ check_seek_in_field_element(it, 0, field_element, true, &hl[2], "0b");
+ check_seek_in_field_element(it, 1, field_element, true, &hl[3], "1");
+ check_seek_in_field_element(it, 7, field_element, true, &hl[3], "7");
+ check_seek_in_field_element(it, 8, field_element, false, &hl[4], "8");
+ check_seek_in_field_element(it, 0, field_element, true, &hl[4], "0c");
+ check_seek_in_field_element(it, 3, field_element, true, &hl[5], "3");
+ check_seek_in_field_element(it, 9, field_element, true, &hl[5], "9");
+ check_seek_in_field_element(it, 10, field_element, false, nullptr, "end");
+}
+
+GTEST_MAIN_RUN_ALL_TESTS()