diff --git a/include/filter.h b/include/filter.h index 239a7e77..d11a8f9d 100644 --- a/include/filter.h +++ b/include/filter.h @@ -12,21 +12,21 @@ private: filter_result_iterator_t* left_it = nullptr; filter_result_iterator_t* right_it = nullptr; - // Used in case of id and reference filter. + /// Used in case of id and reference filter. uint32_t result_index = 0; - // Stores the result of the filters that cannot be iterated. + /// Stores the result of the filters that cannot be iterated. filter_result_t filter_result; - // Initialized in case of filter on string field. - // Sample filter values: ["foo bar", "baz"]. Each filter value is split into tokens. We get posting list iterator - // for each token. - // - // Multiple filter values: Multiple tokens: posting list iterator + /// Initialized in case of filter on string field. + /// Sample filter values: ["foo bar", "baz"]. Each filter value is split into tokens. We get posting list iterator + /// for each token. + /// + /// Multiple filter values: Multiple tokens: posting list iterator std::vector> posting_list_iterators; std::vector expanded_plists; - // Set to false when this iterator or it's subtree becomes invalid. + /// Set to false when this iterator or it's subtree becomes invalid. bool is_valid = true; /// Initializes the state of iterator node after it's creation. @@ -73,9 +73,16 @@ public: delete right_it; } + /// Returns true when doc and reference hold valid values. Used in conjunction with next() and skip_to(id). [[nodiscard]] bool valid(); + /// Returns true when id is a match to the filter. Handles moving the individual iterators internally. + [[nodiscard]] bool valid(uint32_t id); + + /// Advances the iterator to get the next value of doc and reference. The iterator may become invalid during this + /// operation. void next(); + /// Advances the iterator until the doc value is less than 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 804e19a4..a8fa1eeb 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -361,11 +361,12 @@ void filter_result_iterator_t::skip_to(uint32_t id) { if (filter_node->isOperator) { // Skip the subtrees to id and then apply operators to arrive at the next valid doc. + left_it->skip_to(id); + right_it->skip_to(id); + if (filter_node->filter_operator == AND) { - left_it->skip_to(id); and_filter_iterators(); } else { - right_it->skip_to(id); or_filter_iterators(); } @@ -428,3 +429,24 @@ void filter_result_iterator_t::skip_to(uint32_t id) { return; } } + +bool filter_result_iterator_t::valid(uint32_t id) { + if (!is_valid) { + return false; + } + + if (filter_node->isOperator) { + if (filter_node->filter_operator == AND) { + auto and_is_valid = left_it->valid(id) && right_it->valid(id); + is_valid = left_it->is_valid && right_it->is_valid; + return and_is_valid; + } else { + auto or_is_valid = left_it->valid(id) || right_it->valid(id); + is_valid = left_it->is_valid || right_it->is_valid; + return or_is_valid; + } + } + + skip_to(id); + return is_valid && doc == id; +}