xref: /aosp_15_r20/external/icing/icing/index/iterator/section-restrict-data.cc (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2023 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/section-restrict-data.h"
16 
17 #include <set>
18 #include <string>
19 #include <unordered_map>
20 #include <utility>
21 
22 #include "icing/text_classifier/lib3/utils/base/statusor.h"
23 #include "icing/schema/schema-store.h"
24 #include "icing/schema/section.h"
25 #include "icing/store/document-filter-data.h"
26 #include "icing/store/document-id.h"
27 
28 namespace icing {
29 namespace lib {
30 
GenerateSectionMask(const std::string & schema_type,const std::set<std::string> & target_sections) const31 SectionIdMask SectionRestrictData::GenerateSectionMask(
32     const std::string& schema_type,
33     const std::set<std::string>& target_sections) const {
34   SectionIdMask section_mask = kSectionIdMaskNone;
35   auto section_metadata_list = schema_store_.GetSectionMetadata(schema_type);
36   if (!section_metadata_list.ok()) {
37     // The current schema doesn't have section metadata.
38     return kSectionIdMaskNone;
39   }
40   for (const SectionMetadata& section_metadata :
41        *section_metadata_list.ValueOrDie()) {
42     if (target_sections.find(section_metadata.path) != target_sections.end()) {
43       section_mask |= UINT64_C(1) << section_metadata.id;
44     }
45   }
46   return section_mask;
47 }
48 
ComputeAllowedSectionsMask(const std::string & schema_type)49 SectionIdMask SectionRestrictData::ComputeAllowedSectionsMask(
50     const std::string& schema_type) {
51   if (const auto type_property_mask_itr =
52           type_property_masks_.find(schema_type);
53       type_property_mask_itr != type_property_masks_.end()) {
54     return type_property_mask_itr->second;
55   }
56 
57   // Section id mask of schema_type is never calculated before, so
58   // calculate it here and put it into type_property_masks_.
59   // - If type property filters of schema_type or wildcard (*) are
60   //   specified, then create a mask according to the filters.
61   // - Otherwise, create a mask to match all properties.
62   SectionIdMask new_section_id_mask = kSectionIdMaskAll;
63   if (const auto itr = type_property_filters_.find(schema_type);
64       itr != type_property_filters_.end()) {
65     // Property filters defined for given schema type
66     new_section_id_mask = GenerateSectionMask(schema_type, itr->second);
67   } else if (const auto wildcard_itr = type_property_filters_.find(
68                  std::string(SchemaStore::kSchemaTypeWildcard));
69              wildcard_itr != type_property_filters_.end()) {
70     // Property filters defined for wildcard entry
71     new_section_id_mask =
72         GenerateSectionMask(schema_type, wildcard_itr->second);
73   } else {
74     // Do not cache the section mask if no property filters apply to this schema
75     // type to avoid taking up unnecessary space.
76     return kSectionIdMaskAll;
77   }
78 
79   type_property_masks_[schema_type] = new_section_id_mask;
80   return new_section_id_mask;
81 }
82 
ComputeAllowedSectionsMask(DocumentId document_id)83 SectionIdMask SectionRestrictData::ComputeAllowedSectionsMask(
84     DocumentId document_id) {
85   auto data_optional =
86       document_store_.GetAliveDocumentFilterData(document_id, current_time_ms_);
87   if (!data_optional) {
88     // Ran into some error retrieving information on this document, skip
89     return kSectionIdMaskNone;
90   }
91   // Guaranteed that the DocumentFilterData exists at this point
92   SchemaTypeId schema_type_id = data_optional.value().schema_type_id();
93   auto schema_type_or = schema_store_.GetSchemaType(schema_type_id);
94   if (!schema_type_or.ok()) {
95     // Ran into error retrieving schema type, skip
96     return kSectionIdMaskNone;
97   }
98   const std::string* schema_type = std::move(schema_type_or).ValueOrDie();
99   return ComputeAllowedSectionsMask(*schema_type);
100 }
101 
102 }  // namespace lib
103 }  // namespace icing
104