xref: /aosp_15_r20/external/icing/icing/join/document-join-id-pair.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_JOIN_DOCUMENT_JOIN_ID_PAIR_H_
16 #define ICING_JOIN_DOCUMENT_JOIN_ID_PAIR_H_
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <functional>
21 #include <limits>
22 
23 #include "icing/schema/joinable-property.h"
24 #include "icing/store/document-id.h"
25 
26 namespace icing {
27 namespace lib {
28 
29 // DocumentJoinIdPair is composed of document_id and joinable_property_id.
30 class DocumentJoinIdPair {
31  public:
32   // The datatype used to encode DocumentJoinIdPair information: the document_id
33   // and joinable_property_id.
34   using Value = uint32_t;
35 
36   struct Hasher {
operatorHasher37     std::size_t operator()(
38         const DocumentJoinIdPair& document_join_id_pair) const {
39       return std::hash<Value>()(document_join_id_pair.value());
40     }
41   };
42 
43   static_assert(kDocumentIdBits + kJoinablePropertyIdBits <= sizeof(Value) * 8,
44                 "Cannot encode document id and joinable property id in "
45                 "DocumentJoinIdPair::Value");
46 
47   // All bits of kInvalidValue are 1, and it contains:
48   // - 0b1 for 4 unused bits.
49   // - kInvalidDocumentId (2^22-1).
50   // - JoinablePropertyId 2^6-1 (valid), which is ok because kInvalidDocumentId
51   //   has already invalidated the value. In fact, we currently use all 2^6
52   //   joinable property ids and there is no "invalid joinable property id", so
53   //   it doesn't matter what JoinablePropertyId we set for kInvalidValue.
54   static constexpr Value kInvalidValue = std::numeric_limits<Value>::max();
55 
56   // Default constexpr constructor to construct an invalid DocumentJoinIdPair.
DocumentJoinIdPair()57   constexpr DocumentJoinIdPair() : value_(kInvalidValue) {}
58 
59   explicit DocumentJoinIdPair(DocumentId document_id,
60                               JoinablePropertyId joinable_property_id);
61 
DocumentJoinIdPair(Value value)62   explicit DocumentJoinIdPair(Value value) : value_(value) {}
63 
64   bool operator==(const DocumentJoinIdPair& other) const {
65     return value_ == other.value_;
66   }
67 
is_valid()68   bool is_valid() const { return value_ != kInvalidValue; }
value()69   Value value() const { return value_; }
70   DocumentId document_id() const;
71   JoinablePropertyId joinable_property_id() const;
72 
73  private:
74   // Value bits layout: 4 unused + 22 document_id + 6 joinable_property_id.
75   Value value_;
76 } __attribute__((packed));
77 static_assert(sizeof(DocumentJoinIdPair) == 4, "");
78 
79 }  // namespace lib
80 }  // namespace icing
81 
82 #endif  // ICING_JOIN_DOCUMENT_JOIN_ID_PAIR_H_
83