iceberg-cpp
Loading...
Searching...
No Matches
partition_value_util.h
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
24
25#include <functional>
26#include <unordered_map>
27#include <unordered_set>
28
30
31namespace iceberg {
32
33constexpr size_t kHashPrime = 0x9e3779b9;
34
35using PartitionKey = std::pair<int32_t, PartitionValues>;
36
40 int32_t spec_id;
41 const PartitionValues& values;
42
43 PartitionKeyRef(int32_t id, const PartitionValues& vals) : spec_id(id), values(vals) {}
44
45 explicit PartitionKeyRef(const PartitionKey& key)
46 : spec_id(key.first), values(key.second) {}
47};
48
51 std::size_t operator()(const PartitionValues& partition) const noexcept {
52 std::size_t hash = 0;
53 LiteralHash literal_hash;
54 for (const auto& literal : partition.values()) {
55 hash ^= literal_hash(literal) + kHashPrime + (hash << 6) + (hash >> 2);
56 }
57 return hash;
58 }
59};
60
63 bool operator()(const PartitionValues& lhs, const PartitionValues& rhs) const {
64 return lhs == rhs;
65 }
66};
67
70 using is_transparent = void;
71
72 std::size_t operator()(const PartitionKey& key) const noexcept {
73 std::size_t hash = std::hash<int32_t>{}(key.first);
74 hash ^= PartitionValuesHash{}(key.second) + kHashPrime + (hash << 6) + (hash >> 2);
75 return hash;
76 }
77
78 std::size_t operator()(const PartitionKeyRef& key) const noexcept {
79 std::size_t hash = std::hash<int32_t>{}(key.spec_id);
80 hash ^= PartitionValuesHash{}(key.values) + kHashPrime + (hash << 6) + (hash >> 2);
81 return hash;
82 }
83};
84
88 using is_transparent = void;
89
90 // Equality for PartitionKey vs PartitionKey
91 bool operator()(const PartitionKey& lhs, const PartitionKey& rhs) const {
92 return lhs.first == rhs.first && lhs.second == rhs.second;
93 }
94
95 // Equality for PartitionKey vs PartitionKeyRef (heterogeneous lookup)
96 bool operator()(const PartitionKey& lhs, const PartitionKeyRef& rhs) const {
97 return lhs.first == rhs.spec_id && lhs.second == rhs.values;
98 }
99
100 // Equality for PartitionKeyRef vs PartitionKey (heterogeneous lookup)
101 bool operator()(const PartitionKeyRef& lhs, const PartitionKey& rhs) const {
102 return lhs.spec_id == rhs.first && lhs.values == rhs.second;
103 }
104
105 // Equality for PartitionKeyRef vs PartitionKeyRef (heterogeneous lookup)
106 bool operator()(const PartitionKeyRef& lhs, const PartitionKeyRef& rhs) const {
107 return lhs.spec_id == rhs.spec_id && lhs.values == rhs.values;
108 }
109};
110
114template <typename V>
116 public:
117 using map_type =
118 std::unordered_map<PartitionKey, V, PartitionKeyHash, PartitionKeyEqual>;
119 using iterator = typename map_type::iterator;
120 using const_iterator = typename map_type::const_iterator;
121
122 PartitionMap() = default;
123
125 size_t size() const { return map_.size(); }
126
128 bool empty() const { return map_.empty(); }
129
131 void clear() { map_.clear(); }
132
137 bool contains(int32_t spec_id, const PartitionValues& values) const {
138 return map_.contains(PartitionKeyRef{spec_id, values});
139 }
140
145 std::optional<std::reference_wrapper<V>> get(int32_t spec_id,
146 const PartitionValues& values) {
147 auto it = map_.find(PartitionKeyRef{spec_id, values});
148 return it != map_.end() ? std::make_optional(std::ref(it->second)) : std::nullopt;
149 }
150
155 std::optional<std::reference_wrapper<const V>> get(
156 int32_t spec_id, const PartitionValues& values) const {
157 auto it = map_.find(PartitionKeyRef{spec_id, values});
158 return it != map_.end() ? std::make_optional(std::cref(it->second)) : std::nullopt;
159 }
160
166 bool put(int32_t spec_id, PartitionValues values, V value) {
167 auto it = map_.find(PartitionKeyRef{spec_id, values});
168 if (it != map_.end()) {
169 it->second = std::move(value);
170 return true;
171 }
172 map_.emplace(PartitionKey{spec_id, std::move(values)}, std::move(value));
173 return false;
174 }
175
180 bool remove(int32_t spec_id, const PartitionValues& values) {
181 auto it = map_.find(PartitionKeyRef{spec_id, values});
182 if (it != map_.end()) {
183 map_.erase(it);
184 return true;
185 }
186 return false;
187 }
188
190 iterator begin() { return map_.begin(); }
191 const_iterator begin() const { return map_.begin(); }
192 const_iterator cbegin() const { return map_.cbegin(); }
193
195 iterator end() { return map_.end(); }
196 const_iterator end() const { return map_.end(); }
197 const_iterator cend() const { return map_.cend(); }
198
199 private:
200 map_type map_;
201};
202
205 public:
206 using set_type = std::unordered_set<PartitionKey, PartitionKeyHash, PartitionKeyEqual>;
207 using iterator = typename set_type::iterator;
208 using const_iterator = typename set_type::const_iterator;
209
210 PartitionSet() = default;
211
213 size_t size() const { return set_.size(); }
214
216 bool empty() const { return set_.empty(); }
217
219 void clear() { set_.clear(); }
220
225 bool contains(int32_t spec_id, const PartitionValues& values) const {
226 return set_.contains(PartitionKeyRef{spec_id, values});
227 }
228
233 bool add(int32_t spec_id, PartitionValues values) {
234 auto [_, inserted] = set_.emplace(spec_id, std::move(values));
235 return inserted;
236 }
237
242 bool remove(int32_t spec_id, const PartitionValues& values) {
243 auto it = set_.find(PartitionKeyRef{spec_id, values});
244 if (it != set_.end()) {
245 set_.erase(it);
246 return true;
247 }
248 return false;
249 }
250
252 iterator begin() { return set_.begin(); }
253 const_iterator begin() const { return set_.begin(); }
254 const_iterator cbegin() const { return set_.cbegin(); }
255
257 iterator end() { return set_.end(); }
258 const_iterator end() const { return set_.end(); }
259 const_iterator cend() const { return set_.cend(); }
260
261 private:
262 set_type set_;
263};
264
265} // namespace iceberg
A map that uses a pair of spec ID and partition tuple as keys.
Definition partition_value_util.h:115
iterator begin()
Get iterator to the beginning.
Definition partition_value_util.h:190
bool contains(int32_t spec_id, const PartitionValues &values) const
Check if the map contains a key.
Definition partition_value_util.h:137
bool put(int32_t spec_id, PartitionValues values, V value)
Insert or update a value in the map.
Definition partition_value_util.h:166
size_t size() const
Get the number of entries in the map.
Definition partition_value_util.h:125
iterator end()
Get iterator to the end.
Definition partition_value_util.h:195
std::optional< std::reference_wrapper< const V > > get(int32_t spec_id, const PartitionValues &values) const
Get the value associated with a key (const version).
Definition partition_value_util.h:155
bool remove(int32_t spec_id, const PartitionValues &values)
Remove an entry from the map.
Definition partition_value_util.h:180
std::optional< std::reference_wrapper< V > > get(int32_t spec_id, const PartitionValues &values)
Get the value associated with a key.
Definition partition_value_util.h:145
void clear()
Clear all entries from the map.
Definition partition_value_util.h:131
bool empty() const
Check if the map is empty.
Definition partition_value_util.h:128
A set that uses a pair of spec ID and partition tuple as elements.
Definition partition_value_util.h:204
bool add(int32_t spec_id, PartitionValues values)
Add an element to the set.
Definition partition_value_util.h:233
iterator begin()
Get iterator to the beginning.
Definition partition_value_util.h:252
size_t size() const
Get the number of elements in the set.
Definition partition_value_util.h:213
iterator end()
Get iterator to the end.
Definition partition_value_util.h:257
void clear()
Clear all elements from the set.
Definition partition_value_util.h:219
bool contains(int32_t spec_id, const PartitionValues &values) const
Check if the set contains an element.
Definition partition_value_util.h:225
bool remove(int32_t spec_id, const PartitionValues &values)
Remove an element from the set.
Definition partition_value_util.h:242
bool empty() const
Check if the set is empty.
Definition partition_value_util.h:216
StructLike wrapper for a vector of literals that represent partition values.
Definition partition_values.h:36
Definition literal.h:178
Transparent equality functor for PartitionKey with heterogeneous lookup support.
Definition partition_value_util.h:87
Transparent hash functor for PartitionKey with heterogeneous lookup support.
Definition partition_value_util.h:69
Lightweight lookup key for heterogeneous lookup without copying PartitionValues.
Definition partition_value_util.h:39
Equality functor for PartitionValues.
Definition partition_value_util.h:62
Hash functor for PartitionValues.
Definition partition_value_util.h:50