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 #include "icing/index/iterator/doc-hit-info-iterator-section-restrict.h"
16
17 #include <cstdint>
18 #include <memory>
19 #include <string>
20 #include <string_view>
21 #include <utility>
22
23 #include "icing/text_classifier/lib3/utils/base/status.h"
24 #include "icing/text_classifier/lib3/utils/base/statusor.h"
25 #include "icing/absl_ports/canonical_errors.h"
26 #include "icing/absl_ports/str_cat.h"
27 #include "icing/index/hit/doc-hit-info.h"
28 #include "icing/index/iterator/doc-hit-info-iterator.h"
29 #include "icing/schema/schema-store.h"
30 #include "icing/schema/section.h"
31 #include "icing/store/document-filter-data.h"
32 #include "icing/store/document-id.h"
33 #include "icing/store/document-store.h"
34
35 namespace icing {
36 namespace lib {
37
DocHitInfoIteratorSectionRestrict(std::unique_ptr<DocHitInfoIterator> delegate,const DocumentStore * document_store,const SchemaStore * schema_store,std::string_view target_section)38 DocHitInfoIteratorSectionRestrict::DocHitInfoIteratorSectionRestrict(
39 std::unique_ptr<DocHitInfoIterator> delegate,
40 const DocumentStore* document_store, const SchemaStore* schema_store,
41 std::string_view target_section)
42 : delegate_(std::move(delegate)),
43 document_store_(*document_store),
44 schema_store_(*schema_store),
45 target_section_(target_section) {}
46
Advance()47 libtextclassifier3::Status DocHitInfoIteratorSectionRestrict::Advance() {
48 while (delegate_->Advance().ok()) {
49 DocumentId document_id = delegate_->doc_hit_info().document_id();
50
51 SectionIdMask section_id_mask =
52 delegate_->doc_hit_info().hit_section_ids_mask();
53
54 auto data_or = document_store_.GetDocumentFilterData(document_id);
55 if (!data_or.ok()) {
56 // Ran into some error retrieving information on this hit, skip
57 continue;
58 }
59
60 // Guaranteed that the DocumentFilterData exists at this point
61 DocumentFilterData data = std::move(data_or).ValueOrDie();
62 SchemaTypeId schema_type_id = data.schema_type_id();
63
64 // A hit can be in multiple sections at once, need to check that at least
65 // one of the confirmed section ids match the name of the target section
66 while (section_id_mask != 0) {
67 // There was a hit in this section id
68 SectionId section_id = __builtin_ctz(section_id_mask);
69
70 auto section_metadata_or =
71 schema_store_.GetSectionMetadata(schema_type_id, section_id);
72
73 if (section_metadata_or.ok()) {
74 const SectionMetadata* section_metadata =
75 section_metadata_or.ValueOrDie();
76
77 if (section_metadata->path == target_section_) {
78 // The hit was in the target section name, return OK/found
79 doc_hit_info_ = delegate_->doc_hit_info();
80 hit_intersect_section_ids_mask_ = 1u << section_id;
81 return libtextclassifier3::Status::OK;
82 }
83 }
84
85 // Mark this section as checked
86 section_id_mask &= ~(1U << section_id);
87 }
88
89 // Didn't find a matching section name for this hit. Continue.
90 }
91
92 // Didn't find anything on the delegate iterator.
93 doc_hit_info_ = DocHitInfo(kInvalidDocumentId);
94 hit_intersect_section_ids_mask_ = kSectionIdMaskNone;
95 return absl_ports::ResourceExhaustedError("No more DocHitInfos in iterator");
96 }
97
GetNumBlocksInspected() const98 int32_t DocHitInfoIteratorSectionRestrict::GetNumBlocksInspected() const {
99 return delegate_->GetNumBlocksInspected();
100 }
101
GetNumLeafAdvanceCalls() const102 int32_t DocHitInfoIteratorSectionRestrict::GetNumLeafAdvanceCalls() const {
103 return delegate_->GetNumLeafAdvanceCalls();
104 }
105
ToString() const106 std::string DocHitInfoIteratorSectionRestrict::ToString() const {
107 return absl_ports::StrCat(target_section_, ": ", delegate_->ToString());
108 }
109
110 } // namespace lib
111 } // namespace icing
112