From 3a3814aba500d51594ebbd5cbd19a83d54751960 Mon Sep 17 00:00:00 2001 From: Harpreet Sangar Date: Wed, 5 Apr 2023 10:10:13 +0530 Subject: [PATCH] Add `to_filter_id_array` and `and_scalar` methods. --- include/filter.h | 16 +++++++++++++--- src/filter.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ test/filter_test.cpp | 39 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/include/filter.h b/include/filter.h index 5deca7b5..4103f49f 100644 --- a/include/filter.h +++ b/include/filter.h @@ -2,10 +2,14 @@ #include #include +#include #include "posting_list.h" #include "index.h" class Index; +struct filter_node_t; +struct reference_filter_result_t; +struct filter_result_t; class filter_result_iterator_t { private: @@ -52,9 +56,9 @@ public: explicit filter_result_iterator_t(const std::string collection_name, Index const* const index, filter_node_t const* const filter_node) : - collection_name(collection_name), - index(index), - filter_node(filter_node) { + collection_name(collection_name), + index(index), + filter_node(filter_node) { if (filter_node == nullptr) { is_valid = false; return; @@ -143,4 +147,10 @@ public: /// Returns to the initial state of the iterator. void reset(); + + /// Iterates and collects all the filter ids into filter_array. + /// \return size of the filter array + uint32_t to_filter_id_array(uint32_t*& filter_array); + + uint32_t and_scalar(const uint32_t* A, const uint32_t& lenA, uint32_t*& results); }; diff --git a/src/filter.cpp b/src/filter.cpp index 27c21198..77ef5d5d 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -594,3 +594,48 @@ void filter_result_iterator_t::reset() { return; } } + +uint32_t filter_result_iterator_t::to_filter_id_array(uint32_t*& filter_array) { + if (!valid()) { + return 0; + } + + std::vector filter_ids; + do { + filter_ids.push_back(seq_id); + next(); + } while (valid()); + + filter_array = new uint32_t[filter_ids.size()]; + std::copy(filter_ids.begin(), filter_ids.end(), filter_array); + + return filter_ids.size(); +} + +uint32_t filter_result_iterator_t::and_scalar(const uint32_t* A, const uint32_t& lenA, uint32_t*& results) { + if (!valid()) { + return 0; + } + + std::vector filter_ids; + for (uint32_t i = 0; i < lenA; i++) { + auto result = valid(A[i]); + + if (result == -1) { + break; + } + + if (result == 1) { + filter_ids.push_back(A[i]); + } + } + + if (filter_ids.empty()) { + return 0; + } + + results = new uint32_t[filter_ids.size()]; + std::copy(filter_ids.begin(), filter_ids.end(), results); + + return filter_ids.size(); +} diff --git a/test/filter_test.cpp b/test/filter_test.cpp index 91dd81c8..b4f836f1 100644 --- a/test/filter_test.cpp +++ b/test/filter_test.cpp @@ -377,4 +377,43 @@ TEST_F(FilterTest, FilterTreeIterator) { ASSERT_FALSE(iter_move_assignment_test.valid()); delete filter_tree_root; + filter_tree_root = nullptr; + filter_op = filter::parse_filter_query("tags: gold", coll->get_schema(), store, doc_id_prefix, + filter_tree_root); + ASSERT_TRUE(filter_op.ok()); + + auto iter_to_array_test = filter_result_iterator_t(coll->get_name(), coll->_get_index(), filter_tree_root); + ASSERT_TRUE(iter_to_array_test.init_status().ok()); + + uint32_t* filter_ids = nullptr; + uint32_t filter_ids_length; + + filter_ids_length = iter_to_array_test.to_filter_id_array(filter_ids); + ASSERT_EQ(3, filter_ids_length); + + expected = {0, 2, 4}; + for (uint32_t i = 0; i < filter_ids_length; i++) { + ASSERT_EQ(expected[i], filter_ids[i]); + } + ASSERT_FALSE(iter_to_array_test.valid()); + + delete filter_ids; + + auto iter_and_scalar_test = filter_result_iterator_t(coll->get_name(), coll->_get_index(), filter_tree_root); + ASSERT_TRUE(iter_and_scalar_test.init_status().ok()); + + uint32_t a_ids[6] = {0, 1, 3, 4, 5, 6}; + uint32_t* and_result = nullptr; + uint32_t and_result_length; + and_result_length = iter_and_scalar_test.and_scalar(a_ids, 6, and_result); + ASSERT_EQ(2, and_result_length); + + expected = {0, 4}; + for (uint32_t i = 0; i < and_result_length; i++) { + ASSERT_EQ(expected[i], and_result[i]); + } + ASSERT_FALSE(iter_and_test.valid()); + + delete and_result; + delete filter_tree_root; } \ No newline at end of file