diff options
author | Tor Egge <tegge@vespa.ai> | 2024-01-23 12:13:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-23 12:13:54 +0100 |
commit | 056a486a55fd66c39b9b30065865d29655f338f7 (patch) | |
tree | eeef486a9fe8327a2fdbe55fa6700869d54de338 /searchlib/src/tests | |
parent | 3f6a2f98c452bc34ab7947d9b93594e7f74e46e1 (diff) | |
parent | 6b1bc00a239215eba984a1c0c7e1fbe5f8560bac (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')
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() |