diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2020-06-24 19:40:32 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2020-06-25 15:11:33 +0200 |
commit | 07344e04b5628b52da54aaeaed6a28fe979e83f1 (patch) | |
tree | d876a4c85ff43e66e6412c4bd965877193e24493 /searchlib/src/tests | |
parent | 8109d90cf0249356c21a1f65d009381646e2540b (diff) |
Add filter iterators for weighted set blueprints.
Diffstat (limited to 'searchlib/src/tests')
2 files changed, 213 insertions, 0 deletions
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 new file mode 100644 index 00000000000..660cfbaefff --- /dev/null +++ b/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +find_package(GTest REQUIRED) +vespa_add_executable(searchlib_document_weight_or_filter_search_test_app TEST + SOURCES + document_weight_or_filter_search_test.cpp + DEPENDS + searchlib + 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 new file mode 100644 index 00000000000..c8e799a8f10 --- /dev/null +++ b/searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp @@ -0,0 +1,203 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/vespalib/gtest/gtest.h> +#include <vespa/searchlib/attribute/i_document_weight_attribute.h> +#include <vespa/searchlib/attribute/document_weight_or_filter_search.h> +#include <vespa/searchlib/queryeval/searchiterator.h> +#include <vespa/searchlib/common/bitvector.h> + +using PostingList = search::attribute::PostingListTraits<int32_t>::PostingStoreBase; +using Iterator = search::attribute::PostingListTraits<int32_t>::const_iterator; +using KeyData = PostingList::KeyDataType; +using search::BitVector; +using search::attribute::DocumentWeightOrFilterSearch; +using search::queryeval::SearchIterator; +using vespalib::datastore::EntryRef; + +class DocumentWeightOrFilterSearchTest : public ::testing::Test { + PostingList _postings; + vespalib::GenerationHandler _gens; + std::vector<EntryRef> _trees; + uint32_t _range_start; + uint32_t _range_end; +protected: + DocumentWeightOrFilterSearchTest(); + ~DocumentWeightOrFilterSearchTest(); + void inc_generation(); + size_t num_trees() const { return _trees.size(); } + Iterator get_tree(size_t idx) const { + if (idx < _trees.size()) { + return _postings.beginFrozen(_trees[idx]); + } else { + return Iterator(); + } + } + void ensure_tree(size_t idx) { + if (idx <= _trees.size()) { + _trees.resize(idx + 1); + } + } + void add_tree(size_t idx, std::vector<uint32_t> keys) { + ensure_tree(idx); + std::vector<KeyData> adds; + std::vector<uint32_t> removes; + adds.reserve(keys.size()); + for (auto& key : keys) { + adds.emplace_back(KeyData(key, 1)); + } + _postings.apply(_trees[idx], &*adds.begin(), &*adds.end(), &*removes.begin(), &*removes.end()); + } + + std::unique_ptr<SearchIterator> make_iterator() const { + std::vector<Iterator> iterators; + for (size_t i = 0; i < num_trees(); ++i) { + iterators.emplace_back(get_tree(i)); + } + auto result = DocumentWeightOrFilterSearch::create(std::move(iterators)); + result->initRange(_range_start, _range_end); + return result; + }; + + std::vector<uint32_t> eval_daat(SearchIterator &iterator) { + std::vector<uint32_t> result; + uint32_t doc_id = _range_start; + while (doc_id < _range_end) { + if (iterator.seek(doc_id)) { + result.emplace_back(doc_id); + ++doc_id; + } else { + doc_id = std::max(doc_id + 1, iterator.getDocId()); + } + } + return result; + } + + std::vector<uint32_t> frombv(const BitVector &bv) { + std::vector<uint32_t> result; + uint32_t doc_id = _range_start; + doc_id = bv.getNextTrueBit(doc_id); + while (doc_id < _range_end) { + result.emplace_back(doc_id); + ++doc_id; + doc_id = bv.getNextTrueBit(doc_id); + } + return result; + } + + std::unique_ptr<BitVector> tobv(std::vector<uint32_t> values) { + auto bv = BitVector::create(_range_start, _range_end); + for (auto value : values) { + bv->setBit(value); + } + bv->invalidateCachedCount(); + return bv; + } + + void expect_result(std::vector<uint32_t> exp, std::vector<uint32_t> act) + { + EXPECT_EQ(exp, act); + } + + void make_sample_data() { + add_tree(0, { 10, 11 }); + add_tree(1, { 14, 17, 20 }); + add_tree(2, { 3 }); + add_tree(3, { 17 }); + } + + uint32_t get_range_start() const { return _range_start; } + void set_range(uint32_t start, uint32_t end) { + _range_start = start; + _range_end = end; + } +}; + +DocumentWeightOrFilterSearchTest::DocumentWeightOrFilterSearchTest() + : _postings(true), + _gens(), + _range_start(1), + _range_end(10000) +{ +} + +DocumentWeightOrFilterSearchTest::~DocumentWeightOrFilterSearchTest() +{ + for (auto& tree : _trees) { + _postings.clear(tree); + } + _postings.clearBuilder(); + _postings.clearHoldLists(); + inc_generation(); +} + +void +DocumentWeightOrFilterSearchTest::inc_generation() +{ + _postings.freeze(); + _postings.transferHoldLists(_gens.getCurrentGeneration()); + _gens.incGeneration(); + _gens.updateFirstUsedGeneration(); + _postings.trimHoldLists(_gens.getFirstUsedGeneration()); +} + +TEST_F(DocumentWeightOrFilterSearchTest, daat_or) +{ + make_sample_data(); + expect_result(eval_daat(*make_iterator()), { 3, 10, 11, 14, 17, 20 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_get_hits) +{ + make_sample_data(); + expect_result(frombv(*make_iterator()->get_hits(get_range_start())), { 3, 10, 11, 14, 17, 20 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_or_hits_into) +{ + make_sample_data(); + auto bv = tobv({13, 14}); + make_iterator()->or_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 3, 10, 11, 13, 14, 17, 20 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_and_hits_into) +{ + make_sample_data(); + auto bv = tobv({13, 14}); + make_iterator()->and_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, daat_or_ranged) +{ + make_sample_data(); + set_range(4, 15); + expect_result(eval_daat(*make_iterator()), {10, 11, 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_get_hits_ranged) +{ + make_sample_data(); + set_range(4, 15); + expect_result(frombv(*make_iterator()->get_hits(get_range_start())), { 10, 11, 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_or_hits_into_ranged) +{ + make_sample_data(); + set_range(4, 15); + auto bv = tobv({13, 14}); + make_iterator()->or_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 10, 11, 13, 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_and_hits_into_ranged) +{ + make_sample_data(); + set_range(4, 15); + auto bv = tobv({13, 14}); + make_iterator()->and_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 14 }); +} + +GTEST_MAIN_RUN_ALL_TESTS() |