1 // Copyright (C) 2024 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_SCHEMA_SCORABLE_PROPERTY_MANAGER_H_ 16 #define ICING_SCHEMA_SCORABLE_PROPERTY_MANAGER_H_ 17 18 #include <optional> 19 #include <string> 20 #include <string_view> 21 #include <unordered_map> 22 #include <utility> 23 #include <vector> 24 25 #include "icing/text_classifier/lib3/utils/base/statusor.h" 26 #include "icing/schema/schema-util.h" 27 #include "icing/store/document-filter-data.h" 28 29 namespace icing { 30 namespace lib { 31 32 // This class serves as a cache layer to access schema configs for scorable 33 // properties, with the schema-store being the source of truth. 34 class ScorablePropertyManager { 35 public: 36 struct ScorablePropertyInfo { 37 // Scorable property's property_path in the schema config, eg: 38 // "property_name", "parent_schema.nested_child_schema.property_name". 39 std::string property_path; 40 // Data type of the property. 41 PropertyConfigProto::DataType::Code data_type; 42 }; 43 44 ScorablePropertyManager() = default; 45 46 // Delete copy constructor and assignment operator. 47 ScorablePropertyManager(const ScorablePropertyManager&) = delete; 48 ScorablePropertyManager& operator=(const ScorablePropertyManager&) = delete; 49 50 // Gets the index of the given |property_path|, where the index N means that 51 // it is the Nth scorable property path in the schema config of the given 52 // |schema_type_id|, in lexicographical order. 53 // 54 // Returns: 55 // - Index on success 56 // - std::nullopt if the |property_path| doesnn't point to a scorable 57 // property under the |schema_type_id| 58 // - INVALID_ARGUMENT if |schema_type_id| is invalid 59 libtextclassifier3::StatusOr<std::optional<int>> GetScorablePropertyIndex( 60 SchemaTypeId schema_type_id, std::string_view property_path, 61 const SchemaUtil::TypeConfigMap& type_config_map, 62 const std::unordered_map<SchemaTypeId, std::string>& 63 schema_id_to_type_map); 64 65 // Returns the list of ScorablePropertyInfo for the given |schema_type_id|, 66 // in lexicographical order of its property path. 67 // 68 // Returns: 69 // - Vector of scorable property info on success. The vector can be empty 70 // if no scorable property is found under the schema config of 71 // |schema_type_id|. 72 // - INVALID_ARGUMENT if |schema_type_id| is invalid. 73 libtextclassifier3::StatusOr<const std::vector<ScorablePropertyInfo>*> 74 GetOrderedScorablePropertyInfo( 75 SchemaTypeId schema_type_id, 76 const SchemaUtil::TypeConfigMap& type_config_map, 77 const std::unordered_map<SchemaTypeId, std::string>& 78 schema_id_to_type_map); 79 80 private: 81 struct DerivedScorablePropertySchema { 82 // vector of ScorablePropertyInfo, in lexicographical order of its property 83 // path. 84 std::vector<ScorablePropertyInfo> ordered_scorable_property_info; 85 // Map of scorable property path to its index, where index N means that the 86 // property is the Nth scorable property in the schema config, in 87 // lexicographical order. 88 std::unordered_map<std::string, int> property_path_to_index_map; 89 DerivedScorablePropertySchemaDerivedScorablePropertySchema90 explicit DerivedScorablePropertySchema( 91 std::vector<ScorablePropertyInfo>&& ordered_properties, 92 std::unordered_map<std::string, int>&& index_map) 93 : ordered_scorable_property_info(std::move(ordered_properties)), 94 property_path_to_index_map(std::move(index_map)) {} 95 }; 96 97 // Looks up the entry in |scorable_property_schema_cache_| for the key 98 // |schema_type_id|. If the entry is not found, try to update the cache and 99 // return the iterator of the updated entry. 100 // 101 // Returns: 102 // - INVALID_ARGUMENT if |schema_type_id| is not found from the schema. 103 libtextclassifier3::StatusOr< 104 std::unordered_map<SchemaTypeId, DerivedScorablePropertySchema>::iterator> 105 LookupAndMaybeUpdateCache(SchemaTypeId schema_type_id, 106 const SchemaUtil::TypeConfigMap& type_config_map, 107 const std::unordered_map<SchemaTypeId, std::string>& 108 schema_id_to_type_map); 109 110 // Updates the entry in |scorable_property_schema_cache_| for the key 111 // |schema_type_id|. 112 // 113 // Returns true if an entry is successfully inserted to the cache. 114 bool UpdateCache(SchemaTypeId schema_type_id, 115 const SchemaUtil::TypeConfigMap& type_config_map, 116 const std::unordered_map<SchemaTypeId, std::string>& 117 schema_id_to_type_map); 118 119 std::unordered_map<SchemaTypeId, DerivedScorablePropertySchema> 120 scorable_property_schema_cache_; 121 }; 122 123 } // namespace lib 124 } // namespace icing 125 126 #endif // ICING_SCHEMA_SCORABLE_PROPERTY_MANAGER_H_ 127