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