1 // Copyright (C) 2021 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_STORE_SUGGESTION_RESULT_CHECKER_IMPL_H_ 16 #define ICING_STORE_SUGGESTION_RESULT_CHECKER_IMPL_H_ 17 18 #include "icing/schema/section.h" 19 #include "icing/store/document-id.h" 20 #include "icing/store/document-store.h" 21 #include "icing/store/namespace-id.h" 22 #include "icing/store/suggestion-result-checker.h" 23 24 namespace icing { 25 namespace lib { 26 27 class SuggestionResultCheckerImpl : public SuggestionResultChecker { 28 public: SuggestionResultCheckerImpl(const DocumentStore * document_store,const SchemaStore * schema_store,std::unordered_set<NamespaceId> target_namespace_ids,std::unordered_map<NamespaceId,std::unordered_set<DocumentId>> document_id_filter_map,std::unordered_set<SchemaTypeId> target_schema_type_ids,std::unordered_map<SchemaTypeId,SectionIdMask> property_filter_map,std::string target_section,std::unordered_set<DocumentId> search_base,int64_t current_time_ms)29 explicit SuggestionResultCheckerImpl( 30 const DocumentStore* document_store, const SchemaStore* schema_store, 31 std::unordered_set<NamespaceId> target_namespace_ids, 32 std::unordered_map<NamespaceId, std::unordered_set<DocumentId>> 33 document_id_filter_map, 34 std::unordered_set<SchemaTypeId> target_schema_type_ids, 35 std::unordered_map<SchemaTypeId, SectionIdMask> property_filter_map, 36 std::string target_section, std::unordered_set<DocumentId> search_base, 37 int64_t current_time_ms) 38 : document_store_(*document_store), 39 schema_store_(*schema_store), 40 target_namespace_ids_(std::move(target_namespace_ids)), 41 document_id_filter_map_(std::move(document_id_filter_map)), 42 target_schema_type_ids_(std::move(target_schema_type_ids)), 43 property_filter_map_(std::move(property_filter_map)), 44 target_section_(std::move(target_section)), 45 search_base_(std::move(search_base)), 46 current_time_ms_(current_time_ms) {} 47 MatchesTargetNamespace(NamespaceId namespace_id)48 bool MatchesTargetNamespace(NamespaceId namespace_id) const { 49 return target_namespace_ids_.empty() || 50 target_namespace_ids_.find(namespace_id) != 51 target_namespace_ids_.end(); 52 } 53 MatchesTargetDocumentIds(NamespaceId namespace_id,DocumentId document_id)54 bool MatchesTargetDocumentIds(NamespaceId namespace_id, 55 DocumentId document_id) const { 56 if (document_id_filter_map_.empty()) { 57 return true; 58 } 59 auto document_ids_itr = document_id_filter_map_.find(namespace_id); 60 // The client doesn't set desired document ids in this namespace, or the 61 // client doesn't want this document. 62 return document_ids_itr == document_id_filter_map_.end() || 63 document_ids_itr->second.find(document_id) != 64 document_ids_itr->second.end(); 65 } 66 MatchesTargetSchemaType(SchemaTypeId schema_type_id)67 bool MatchesTargetSchemaType(SchemaTypeId schema_type_id) const { 68 return target_schema_type_ids_.empty() || 69 target_schema_type_ids_.find(schema_type_id) != 70 target_schema_type_ids_.end(); 71 } 72 MatchesTargetSection(SchemaTypeId schema_type_id,SectionId section_id)73 bool MatchesTargetSection(SchemaTypeId schema_type_id, 74 SectionId section_id) const { 75 if (target_section_.empty()) { 76 return true; 77 } 78 auto section_metadata_or = 79 schema_store_.GetSectionMetadata(schema_type_id, section_id); 80 if (!section_metadata_or.ok()) { 81 // cannot find the target section metadata. 82 return false; 83 } 84 const SectionMetadata* section_metadata = section_metadata_or.ValueOrDie(); 85 return section_metadata->path == target_section_; 86 } 87 MatchesSearchBase(DocumentId document_id)88 bool MatchesSearchBase(DocumentId document_id) const { 89 return search_base_.empty() || 90 search_base_.find(document_id) != search_base_.end(); 91 } 92 MatchesPropertyFilter(SchemaTypeId schema_type_id,SectionId section_id)93 bool MatchesPropertyFilter(SchemaTypeId schema_type_id, 94 SectionId section_id) const { 95 if (property_filter_map_.empty()) { 96 return true; 97 } 98 auto section_mask_itr = property_filter_map_.find(schema_type_id); 99 return section_mask_itr == property_filter_map_.end() || 100 (section_mask_itr->second & (UINT64_C(1) << section_id)) != 0; 101 } 102 BelongsToTargetResults(DocumentId document_id,SectionId section_id)103 bool BelongsToTargetResults(DocumentId document_id, 104 SectionId section_id) const override { 105 // Get the document filter data first. 106 auto document_filter_data_optional_ = 107 document_store_.GetAliveDocumentFilterData(document_id, 108 current_time_ms_); 109 if (!document_filter_data_optional_) { 110 // The document doesn't exist. 111 return false; 112 } 113 DocumentFilterData document_filter_data = 114 document_filter_data_optional_.value(); 115 116 if (!MatchesTargetNamespace(document_filter_data.namespace_id())) { 117 return false; 118 } 119 if (!MatchesTargetDocumentIds(document_filter_data.namespace_id(), 120 document_id)) { 121 return false; 122 } 123 if (!MatchesTargetSchemaType(document_filter_data.schema_type_id())) { 124 return false; 125 } 126 if (!MatchesTargetSection(document_filter_data.schema_type_id(), 127 section_id)) { 128 return false; 129 } 130 if (!MatchesSearchBase(document_id)) { 131 return false; 132 } 133 if (!MatchesPropertyFilter(document_filter_data.schema_type_id(), 134 section_id)) { 135 return false; 136 } 137 return true; 138 } 139 const DocumentStore& document_store_; 140 const SchemaStore& schema_store_; 141 std::unordered_set<NamespaceId> target_namespace_ids_; 142 std::unordered_map<NamespaceId, std::unordered_set<DocumentId>> 143 document_id_filter_map_; 144 std::unordered_set<SchemaTypeId> target_schema_type_ids_; 145 std::unordered_map<SchemaTypeId, SectionIdMask> property_filter_map_; 146 std::string target_section_; 147 std::unordered_set<DocumentId> search_base_; 148 int64_t current_time_ms_; 149 }; 150 151 } // namespace lib 152 } // namespace icing 153 154 #endif // ICING_STORE_SUGGESTION_RESULT_CHECKER_IMPL_H_