xref: /aosp_15_r20/external/icing/icing/schema/joinable-property.h (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 #ifndef ICING_SCHEMA_JOINABLE_PROPERTY_H_
16 #define ICING_SCHEMA_JOINABLE_PROPERTY_H_
17 
18 #include <cstdint>
19 #include <string>
20 #include <string_view>
21 #include <utility>
22 #include <vector>
23 
24 #include "icing/proto/schema.pb.h"
25 
26 namespace icing {
27 namespace lib {
28 
29 using JoinablePropertyId = int8_t;
30 
31 // 6 bits for 64 values.
32 inline constexpr int kJoinablePropertyIdBits = 6;
33 inline constexpr JoinablePropertyId kTotalNumJoinableProperties =
34     (INT8_C(1) << kJoinablePropertyIdBits);
35 inline constexpr JoinablePropertyId kInvalidJoinablePropertyId =
36     kTotalNumJoinableProperties;
37 inline constexpr JoinablePropertyId kMaxJoinablePropertyId =
38     kTotalNumJoinableProperties - 1;
39 inline constexpr JoinablePropertyId kMinJoinablePropertyId = 0;
40 
IsJoinablePropertyIdValid(JoinablePropertyId joinable_property_id)41 constexpr bool IsJoinablePropertyIdValid(
42     JoinablePropertyId joinable_property_id) {
43   return joinable_property_id >= kMinJoinablePropertyId &&
44          joinable_property_id <= kMaxJoinablePropertyId;
45 }
46 
47 static_assert(
48     kJoinablePropertyIdBits < 8 * sizeof(JoinablePropertyId),
49     "Cannot exhaust all bits of JoinablePropertyId since it is a signed "
50     "integer and the most significant bit should be preserved.");
51 
52 struct JoinablePropertyMetadata {
53   // Dot-joined property names, representing the location of joinable property
54   // inside an document. E.g. "property1.property2".
55   std::string path;
56 
57   // A unique id of joinable property.
58   JoinablePropertyId id;
59 
60   // Data type of this joinable property values. Currently we only support
61   // STRING.
62   PropertyConfigProto::DataType::Code data_type;
63 
64   // How values will be used as a joining matcher.
65   //
66   // JoinableConfig::ValueType::QUALIFIED_ID:
67   //   Value in this property is a joinable (string) qualified id. Qualified id
68   //   is composed of namespace and uri, and it will be used as the identifier
69   //   of the parent document. Note: it is invalid to use this value type with
70   //   non-string DataType.
71   JoinableConfig::ValueType::Code value_type;
72 
73   // How to propagate the deletion between the document and the referenced
74   // joinable document.
75   //
76   // JoinableConfig::DeletePropagationType::NONE:
77   //   No propagation.
78   //
79   // JoinableConfig::DeletePropagationType::PROPAGATE_FROM:
80   //   Delete the document when the referenced (parent) document is deleted.
81   //
82   // This is only applicable to joinable properties with value type
83   // JoinableConfig::ValueType::QUALIFIED_ID.
84   JoinableConfig::DeletePropagationType::Code delete_propagation_type;
85 
JoinablePropertyMetadataJoinablePropertyMetadata86   explicit JoinablePropertyMetadata(
87       JoinablePropertyId id_in,
88       PropertyConfigProto::DataType::Code data_type_in,
89       JoinableConfig::ValueType::Code value_type_in,
90       JoinableConfig::DeletePropagationType::Code delete_propagation_type_in,
91       std::string&& path_in)
92       : path(std::move(path_in)),
93         id(id_in),
94         data_type(data_type_in),
95         value_type(value_type_in),
96         delete_propagation_type(delete_propagation_type_in) {}
97 
98   JoinablePropertyMetadata(const JoinablePropertyMetadata& other) = default;
99   JoinablePropertyMetadata& operator=(const JoinablePropertyMetadata& other) =
100       default;
101 
102   JoinablePropertyMetadata(JoinablePropertyMetadata&& other) = default;
103   JoinablePropertyMetadata& operator=(JoinablePropertyMetadata&& other) =
104       default;
105 
106   bool operator==(const JoinablePropertyMetadata& rhs) const {
107     return path == rhs.path && id == rhs.id && data_type == rhs.data_type &&
108            value_type == rhs.value_type &&
109            delete_propagation_type == rhs.delete_propagation_type;
110   }
111 };
112 
113 // JoinableProperty is an icing internal concept similar to document property
114 // values (contents), but with extra metadata. the data type of value is
115 // specified by template.
116 //
117 // Current supported data types:
118 // - std::string_view (PropertyConfigProto::DataType::STRING)
119 template <typename T>
120 struct JoinableProperty {
121   JoinablePropertyMetadata metadata;
122   std::vector<T> values;
123 
JoinablePropertyJoinableProperty124   explicit JoinableProperty(JoinablePropertyMetadata&& metadata_in,
125                             std::vector<T>&& values_in)
126       : metadata(std::move(metadata_in)), values(std::move(values_in)) {}
127 
data_typeJoinableProperty128   PropertyConfigProto::DataType::Code data_type() const {
129     return metadata.data_type;
130   }
131 
value_typeJoinableProperty132   JoinableConfig::ValueType::Code value_type() const {
133     return metadata.value_type;
134   }
135 
delete_propagation_typeJoinableProperty136   JoinableConfig::DeletePropagationType::Code delete_propagation_type() const {
137     return metadata.delete_propagation_type;
138   }
139 };
140 
141 // Groups of different type joinable properties. Callers can access joinable
142 // properties with types they want and avoid going through non-desired ones.
143 //
144 // REQUIRES: lifecycle of the property must be longer than this object, since we
145 //   use std::string_view for extracting its string_values.
146 struct JoinablePropertyGroup {
147   std::vector<JoinableProperty<std::string_view>> qualified_id_properties;
148 };
149 
150 }  // namespace lib
151 }  // namespace icing
152 
153 #endif  // ICING_SCHEMA_JOINABLE_PROPERTY_H_
154