1 // Copyright (C) 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef ICING_INDEX_ITERATOR_DOC_HIT_INFO_ITERATOR_OR_H_ 16 #define ICING_INDEX_ITERATOR_DOC_HIT_INFO_ITERATOR_OR_H_ 17 18 #include <cstdint> 19 #include <memory> 20 #include <string> 21 #include <utility> 22 23 #include "icing/index/iterator/doc-hit-info-iterator.h" 24 25 namespace icing { 26 namespace lib { 27 28 // Given n iterators, will decide what the fastest Or-iterator implementation 29 // will be. 30 std::unique_ptr<DocHitInfoIterator> CreateOrIterator( 31 std::vector<std::unique_ptr<DocHitInfoIterator>> iterators); 32 33 // Iterate over a logical OR of two child iterators. 34 class DocHitInfoIteratorOr : public DocHitInfoIterator { 35 public: 36 explicit DocHitInfoIteratorOr(std::unique_ptr<DocHitInfoIterator> left_it, 37 std::unique_ptr<DocHitInfoIterator> right_it); 38 39 libtextclassifier3::StatusOr<TrimmedNode> TrimRightMostNode() && override; 40 41 libtextclassifier3::Status Advance() override; 42 GetCallStats()43 CallStats GetCallStats() const override { 44 return left_->GetCallStats() + right_->GetCallStats(); 45 } 46 47 std::string ToString() const override; 48 MapChildren(const ChildrenMapper & mapper)49 void MapChildren(const ChildrenMapper &mapper) override { 50 left_ = mapper(std::move(left_)); 51 right_ = mapper(std::move(right_)); 52 } 53 54 void PopulateMatchedTermsStats( 55 std::vector<TermMatchInfo> *matched_terms_stats, 56 SectionIdMask filtering_section_mask = kSectionIdMaskAll) const override { 57 if (doc_hit_info_.document_id() == kInvalidDocumentId) { 58 // Current hit isn't valid, return. 59 return; 60 } 61 current_->PopulateMatchedTermsStats(matched_terms_stats, 62 filtering_section_mask); 63 // If equal, then current_ == left_. Combine with results from right_. 64 if (left_document_id_ == right_document_id_) { 65 right_->PopulateMatchedTermsStats(matched_terms_stats, 66 filtering_section_mask); 67 } 68 } 69 70 private: 71 std::unique_ptr<DocHitInfoIterator> left_; 72 std::unique_ptr<DocHitInfoIterator> right_; 73 // Pointer to the chosen iterator that points to the current doc_hit_info_. If 74 // both left_ and right_ point to the same docid, then chosen_ == left. 75 // chosen_ does not own the iterator it points to. 76 DocHitInfoIterator *current_; 77 DocumentId left_document_id_ = kMaxDocumentId; 78 DocumentId right_document_id_ = kMaxDocumentId; 79 }; 80 81 // Iterate over a logical OR of multiple child iterators. 82 // 83 // NOTE: DocHitInfoIteratorOr is a faster alternative to OR exactly 2 iterators. 84 class DocHitInfoIteratorOrNary : public DocHitInfoIterator { 85 public: 86 explicit DocHitInfoIteratorOrNary( 87 std::vector<std::unique_ptr<DocHitInfoIterator>> iterators); 88 89 libtextclassifier3::StatusOr<TrimmedNode> TrimRightMostNode() && override; 90 91 libtextclassifier3::Status Advance() override; 92 93 CallStats GetCallStats() const override; 94 95 std::string ToString() const override; 96 MapChildren(const ChildrenMapper & mapper)97 void MapChildren(const ChildrenMapper &mapper) override { 98 for (int i = 0; i < iterators_.size(); ++i) { 99 iterators_[i] = mapper(std::move(iterators_[i])); 100 } 101 } 102 103 void PopulateMatchedTermsStats( 104 std::vector<TermMatchInfo> *matched_terms_stats, 105 SectionIdMask filtering_section_mask = kSectionIdMaskAll) const override { 106 if (doc_hit_info_.document_id() == kInvalidDocumentId) { 107 // Current hit isn't valid, return. 108 return; 109 } 110 for (size_t i = 0; i < current_iterators_.size(); i++) { 111 current_iterators_.at(i)->PopulateMatchedTermsStats( 112 matched_terms_stats, filtering_section_mask); 113 } 114 } 115 116 private: 117 std::vector<std::unique_ptr<DocHitInfoIterator>> iterators_; 118 // Pointers to the iterators that point to the current doc_hit_info_. 119 // current_iterators_ does not own the iterators it points to. 120 std::vector<DocHitInfoIterator *> current_iterators_; 121 }; 122 123 } // namespace lib 124 } // namespace icing 125 126 #endif // ICING_INDEX_ITERATOR_DOC_HIT_INFO_ITERATOR_OR_H_ 127