• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
JoinablePropertyMetadataJoinablePropertyMetadata73   explicit JoinablePropertyMetadata(
74       JoinablePropertyId id_in,
75       PropertyConfigProto::DataType::Code data_type_in,
76       JoinableConfig::ValueType::Code value_type_in, std::string&& path_in)
77       : path(std::move(path_in)),
78         id(id_in),
79         data_type(data_type_in),
80         value_type(value_type_in) {}
81 
82   JoinablePropertyMetadata(const JoinablePropertyMetadata& other) = default;
83   JoinablePropertyMetadata& operator=(const JoinablePropertyMetadata& other) =
84       default;
85 
86   JoinablePropertyMetadata(JoinablePropertyMetadata&& other) = default;
87   JoinablePropertyMetadata& operator=(JoinablePropertyMetadata&& other) =
88       default;
89 
90   bool operator==(const JoinablePropertyMetadata& rhs) const {
91     return path == rhs.path && id == rhs.id && data_type == rhs.data_type &&
92            value_type == rhs.value_type;
93   }
94 };
95 
96 // JoinableProperty is an icing internal concept similar to document property
97 // values (contents), but with extra metadata. the data type of value is
98 // specified by template.
99 //
100 // Current supported data types:
101 // - std::string_view (PropertyConfigProto::DataType::STRING)
102 template <typename T>
103 struct JoinableProperty {
104   JoinablePropertyMetadata metadata;
105   std::vector<T> values;
106 
JoinablePropertyJoinableProperty107   explicit JoinableProperty(JoinablePropertyMetadata&& metadata_in,
108                             std::vector<T>&& values_in)
109       : metadata(std::move(metadata_in)), values(std::move(values_in)) {}
110 
data_typeJoinableProperty111   PropertyConfigProto::DataType::Code data_type() const {
112     return metadata.data_type;
113   }
114 
value_typeJoinableProperty115   JoinableConfig::ValueType::Code value_type() const {
116     return metadata.value_type;
117   }
118 };
119 
120 // Groups of different type joinable properties. Callers can access joinable
121 // properties with types they want and avoid going through non-desired ones.
122 //
123 // REQUIRES: lifecycle of the property must be longer than this object, since we
124 //   use std::string_view for extracting its string_values.
125 struct JoinablePropertyGroup {
126   std::vector<JoinableProperty<std::string_view>> qualified_id_properties;
127 };
128 
129 }  // namespace lib
130 }  // namespace icing
131 
132 #endif  // ICING_SCHEMA_JOINABLE_PROPERTY_H_
133