From 0a022382ce7fa62764be620ca4ea181cbb43d6d9 Mon Sep 17 00:00:00 2001 From: Harpreet Sangar Date: Tue, 21 Mar 2023 12:56:53 +0530 Subject: [PATCH] Add test cases for `AND` and `OR`. --- include/filter.h | 3 ++- src/filter.cpp | 24 ++++++++++++++++++------ test/filter_test.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/include/filter.h b/include/filter.h index d11a8f9d..643c5006 100644 --- a/include/filter.h +++ b/include/filter.h @@ -83,6 +83,7 @@ public: /// operation. void next(); - /// Advances the iterator until the doc value is less than id. The iterator may become invalid during this operation. + /// Advances the iterator until the doc value reaches or just overshoots id. The iterator may become invalid during + /// this operation. void skip_to(uint32_t id); }; diff --git a/src/filter.cpp b/src/filter.cpp index a8fa1eeb..b42c3e5d 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -4,10 +4,10 @@ #include "filter.h" void filter_result_iterator_t::and_filter_iterators() { - while (left_it->valid() && right_it->valid()) { + while (left_it->is_valid && right_it->is_valid) { while (left_it->doc < right_it->doc) { left_it->next(); - if (!left_it->valid()) { + if (!left_it->is_valid) { is_valid = false; return; } @@ -15,7 +15,7 @@ void filter_result_iterator_t::and_filter_iterators() { while (left_it->doc > right_it->doc) { right_it->next(); - if (!right_it->valid()) { + if (!right_it->is_valid) { is_valid = false; return; } @@ -40,7 +40,7 @@ void filter_result_iterator_t::and_filter_iterators() { } void filter_result_iterator_t::or_filter_iterators() { - if (left_it->valid() && right_it->valid()) { + if (left_it->is_valid && right_it->is_valid) { if (left_it->doc < right_it->doc) { doc = left_it->doc; reference.clear(); @@ -76,7 +76,7 @@ void filter_result_iterator_t::or_filter_iterators() { return; } - if (left_it->valid()) { + if (left_it->is_valid) { doc = left_it->doc; reference.clear(); @@ -87,7 +87,7 @@ void filter_result_iterator_t::or_filter_iterators() { return; } - if (right_it->valid()) { + if (right_it->is_valid) { doc = right_it->doc; reference.clear(); @@ -133,9 +133,21 @@ void filter_result_iterator_t::next() { } if (filter_node->isOperator) { + // Advance the subtrees and then apply operators to arrive at the next valid doc. if (filter_node->filter_operator == AND) { + left_it->next(); + right_it->next(); and_filter_iterators(); } else { + if (left_it->doc == doc && right_it->doc == doc) { + left_it->next(); + right_it->next(); + } else if (left_it->doc == doc) { + left_it->next(); + } else { + right_it->next(); + } + or_filter_iterators(); } diff --git a/test/filter_test.cpp b/test/filter_test.cpp index 60cff669..99edf27f 100644 --- a/test/filter_test.cpp +++ b/test/filter_test.cpp @@ -178,5 +178,49 @@ TEST_F(FilterTest, FilterTreeIterator) { ASSERT_FALSE(iter_skip_test.valid()); ASSERT_TRUE(iter_op.ok()); + delete filter_tree_root; + filter_tree_root = nullptr; + filter_op = filter::parse_filter_query("name: jeremy && tags: fine platinum", coll->get_schema(), store, doc_id_prefix, + filter_tree_root); + ASSERT_TRUE(filter_op.ok()); + + auto iter_and_test = filter_result_iterator_t(coll->get_name(), coll->_get_index(), filter_tree_root, iter_op); + + ASSERT_TRUE(iter_and_test.valid()); + ASSERT_EQ(1, iter_and_test.doc); + iter_and_test.next(); + + ASSERT_FALSE(iter_and_test.valid()); + ASSERT_TRUE(iter_op.ok()); + + delete filter_tree_root; + filter_tree_root = nullptr; + filter_op = filter::parse_filter_query("name: James || tags: bronze", coll->get_schema(), store, doc_id_prefix, + filter_tree_root); + ASSERT_TRUE(filter_op.ok()); + + auto doc = + R"({ + "name": "James Rowdy", + "age": 36, + "years": [2005, 2022], + "rating": 6.03, + "tags": ["copper"] + })"_json; + auto add_op = coll->add(doc.dump()); + ASSERT_TRUE(add_op.ok()); + + auto iter_or_test = filter_result_iterator_t(coll->get_name(), coll->_get_index(), filter_tree_root, iter_op); + + expected = {2, 4, 5}; + for (auto const& i : expected) { + ASSERT_TRUE(iter_or_test.valid()); + ASSERT_EQ(i, iter_or_test.doc); + iter_or_test.next(); + } + + ASSERT_FALSE(iter_or_test.valid()); + ASSERT_TRUE(iter_op.ok()); + delete filter_tree_root; } \ No newline at end of file