22 static constexpr size_t index_mask_bits = 5;
23 static constexpr size_t index_mask = (1 << index_mask_bits) - 1;
26 static constexpr size_t hash_bits =
sizeof(
Hash) * 8;
29 static constexpr size_t small_index_bits =
sizeof(
SmallIndex) * 8;
30 static_assert(small_index_bits > index_mask_bits);
32 static constexpr size_t collision_node_bits = hash_bits % index_mask_bits;
33 static_assert(collision_node_bits > 0);
34 static constexpr SmallIndex collision_depth = hash_bits / index_mask_bits;
35 static constexpr size_t collision_bins = 1 << collision_node_bits;
39 return (hash >> ((
Hash)depth * index_mask_bits)) & index_mask;
42 template <
class K,
class V,
class H = std::hash<K>>
52 constexpr Bitmap(uint32_t bits) : _bits(bits) {}
56 return Bitmap(_bits & other._bits);
61 return __builtin_popcount(_bits);
66 return Bitmap(_bits | ((uint32_t)1 << idx));
71 return Bitmap(_bits & ~((uint32_t)1 << idx));
76 return (_bits & ((uint32_t)1 << idx)) != 0;
80 template <
class K,
class V,
class H>
83 template <
class K,
class V>
91 const V*
getp(
const K& k)
const
100 template <
class K,
class V,
class H>
101 using Node = std::shared_ptr<void>;
103 template <
class K,
class V,
class H>
106 std::array<std::vector<std::shared_ptr<Entry<K, V>>>, collision_bins>
bins;
110 const auto idx = mask(hash, collision_depth);
111 const auto& bin =
bins[idx];
112 for (
const auto& node : bin)
122 const auto idx = mask(hash, collision_depth);
123 auto& bin =
bins[idx];
124 for (
size_t i = 0; i < bin.size(); ++i)
126 const auto& entry = bin[i];
129 const auto diff = map::get_serialized_size_with_padding(entry->key) +
130 map::get_serialized_size_with_padding(entry->value);
131 bin[i] = std::make_shared<Entry<K, V>>(k, v);
135 bin.push_back(std::make_shared<
Entry<K, V>>(k, v));
141 const auto idx = mask(hash, collision_depth);
142 auto& bin =
bins[idx];
143 for (
size_t i = 0; i < bin.size(); ++i)
145 const auto& entry = bin[i];
148 const auto diff = map::get_serialized_size_with_padding(entry->key) +
149 map::get_serialized_size_with_padding(entry->value);
150 bin.erase(bin.begin() + i);
158 bool foreach(F&& f)
const
160 for (
const auto& bin :
bins)
162 for (
const auto& entry : bin)
163 if (!f(entry->key, entry->value))
170 template <
class K,
class V,
class H>
192 const auto mask =
Bitmap(~((uint32_t)-1 << idx));
201 const auto idx = mask(hash, depth);
208 return node_as<Entry<K, V>>(c_idx)->
getp(k);
210 if (depth == (collision_depth - 1))
211 return node_as<Collisions<K, V, H>>(c_idx)->
getp(hash, k);
213 return node_as<SubNodes<K, V, H>>(c_idx)->
getp(depth + 1, hash, k);
219 const auto idx = mask(hash, depth);
234 if (depth < (collision_depth - 1))
236 auto sn = *node_as<SubNodes<K, V, H>>(c_idx);
237 insert = sn.put_mut(depth + 1, hash, k, v);
238 nodes[c_idx] = std::make_shared<SubNodes<K, V, H>>(std::move(sn));
242 auto sn = *node_as<Collisions<K, V, H>>(c_idx);
243 insert = sn.put_mut(hash, k, v);
244 nodes[c_idx] = std::make_shared<Collisions<K, V, H>>(std::move(sn));
249 const auto& entry0 = node_as<Entry<K, V>>(c_idx);
250 if (k == entry0->key)
252 auto current_size = map::get_serialized_size_with_padding(entry0->key) +
253 map::get_serialized_size_with_padding(entry0->value);
254 nodes[c_idx] = std::make_shared<Entry<K, V>>(k, v);
258 if (depth < (collision_depth - 1))
260 const auto hash0 = H()(entry0->key);
261 const auto idx0 = mask(hash0, depth + 1);
264 sub_node.
put_mut(depth + 1, hash, k, v);
271 nodes.begin() + c_idx,
277 const auto hash0 = H()(entry0->key);
278 const auto idx0 = mask(hash0, collision_depth);
279 sub_node.bins[idx0].push_back(entry0);
280 const auto idx1 = mask(hash, collision_depth);
281 sub_node.bins[idx1].push_back(std::make_shared<
Entry<K, V>>(k, v));
288 nodes.begin() + c_idx,
294 std::pair<std::shared_ptr<SubNodes<K, V, H>>,
size_t>
put(
298 auto r = node.put_mut(depth, hash, k, v);
299 return std::make_pair(
306 const auto idx = mask(hash, depth);
314 const auto& entry = node_as<Entry<K, V>>(c_idx);
318 const auto diff = map::get_serialized_size_with_padding(entry->key) +
319 map::get_serialized_size_with_padding(entry->value);
325 if (depth == (collision_depth - 1))
327 auto sn = *node_as<Collisions<K, V, H>>(c_idx);
328 const auto diff = sn.remove_mut(hash, k);
329 nodes[c_idx] = std::make_shared<Collisions<K, V, H>>(std::move(sn));
333 auto sn = *node_as<SubNodes<K, V, H>>(c_idx);
334 const auto diff = sn.remove_mut(depth + 1, hash, k);
335 nodes[c_idx] = std::make_shared<SubNodes<K, V, H>>(std::move(sn));
339 std::pair<std::shared_ptr<SubNodes<K, V, H>>,
size_t>
remove(
343 auto r = node.remove_mut(depth, hash, k);
344 return std::make_pair(
354 const auto& entry = node_as<Entry<K, V>>(i);
355 if (!f(entry->key, entry->value))
358 for (
size_t i = entries; i <
nodes.size(); ++i)
360 if (depth == (collision_depth - 1))
368 depth + 1, std::forward<F>(f)))
377 const std::shared_ptr<A>& node_as(
SmallIndex c_idx)
const
379 return reinterpret_cast<const std::shared_ptr<A>&
>(
nodes[c_idx]);
383 template <
class K,
class V,
class H = std::hash<K>>
387 std::shared_ptr<SubNodes<K, V, H>> root;
389 size_t serialized_size = 0;
394 size_t serialized_size_) :
395 root(std::move(root_)),
397 serialized_size(serialized_size_)
414 return serialized_size;
419 return map_size == 0;
422 std::optional<V>
get(
const K& key)
const
424 auto v = root->getp(0, H()(key), key);
432 const V*
getp(
const K& key)
const
434 return root->getp(0, H()(key), key);
439 auto r = root->
put(0, H()(key), key, value);
440 auto size_ = map_size;
444 const auto size_change = (map::get_serialized_size_with_padding(key) +
445 map::get_serialized_size_with_padding(value)) -
448 return Map(std::move(r.first), size_, size_change + serialized_size);
453 auto r = root->
remove(0, H()(key), key);
454 auto size_ = map_size;
458 return Map(std::move(r.first), size_, serialized_size - r.second);
462 bool foreach(F&& f)
const
464 return root->foreach(0, std::forward<F>(f));
469 return std::make_unique<Snapshot>(*
this);
473 template <
class K,
class V,
class H>
485 KVTuple(K* k_,
Hash h_k_, V* v_) : k(k_), h_k(h_k_), v(v_) {}
493 return map.get_serialized_size();
498 std::vector<KVTuple> ordered_state;
499 ordered_state.reserve(
map.size());
500 size_t serialized_size = 0;
502 map.foreach([&ordered_state, &serialized_size](
auto& key,
auto& value) {
505 uint32_t key_size = map::get_serialized_size_with_padding(key);
506 uint32_t value_size = map::get_serialized_size_with_padding(value);
507 serialized_size += (key_size + value_size);
509 ordered_state.emplace_back(k,
static_cast<Hash>(H()(key)), v);
517 ordered_state.begin(), ordered_state.end(), [](KVTuple& i, KVTuple& j) {
518 return i.h_k < j.h_k;
522 serialized_size ==
map.get_serialized_size(),
523 "Serialized size:{}, map.get_serialized_size():{} (map count:{}, "
524 "ordered state count:{})",
526 map.get_serialized_size(),
528 ordered_state.size());
530 for (
const auto& p : ordered_state)
534 map::add_padding(key_size, data, serialized_size);
537 uint32_t value_size =
map::serialize(*p.v, data, serialized_size);
538 map::add_padding(value_size, data, serialized_size);
542 serialized_size == 0,
543 "Serialization buffer is not complete, remaining:{}/{}",
545 map.get_serialized_size());
#define CCF_ASSERT_FMT(expr,...)
Definition ccf_assert.h:10
Definition champ_map.h:46
constexpr Bitmap operator&(const Bitmap &other) const
Definition champ_map.h:54
constexpr Bitmap()
Definition champ_map.h:50
constexpr Bitmap clear(SmallIndex idx) const
Definition champ_map.h:69
constexpr Bitmap set(SmallIndex idx) const
Definition champ_map.h:64
constexpr bool check(SmallIndex idx) const
Definition champ_map.h:74
constexpr Bitmap(uint32_t bits)
Definition champ_map.h:52
constexpr SmallIndex pop() const
Definition champ_map.h:59
Definition champ_map.h:385
std::unique_ptr< Snapshot > make_snapshot() const
Definition champ_map.h:467
Map()
Definition champ_map.h:405
V ValueType
Definition champ_map.h:402
const Map< K, V, H > put(const K &key, const V &value) const
Definition champ_map.h:437
K KeyType
Definition champ_map.h:401
std::optional< V > get(const K &key) const
Definition champ_map.h:422
size_t get_serialized_size() const
Definition champ_map.h:412
Snapshot< K, V, H > Snapshot
Definition champ_map.h:403
const Map< K, V, H > remove(const K &key) const
Definition champ_map.h:451
size_t size() const
Definition champ_map.h:407
const V * getp(const K &key) const
Definition champ_map.h:432
bool empty() const
Definition champ_map.h:417
Definition champ_map.h:475
Snapshot(const Map< K, V, H > &map_)
Definition champ_map.h:489
size_t get_serialized_size()
Definition champ_map.h:491
void serialize(uint8_t *data)
Definition champ_map.h:496
Definition champ_map.h:16
std::shared_ptr< void > Node
Definition champ_map.h:101
uint32_t Hash
Definition champ_map.h:25
uint8_t SmallIndex
Definition champ_map.h:28
Definition map_serializers.h:11
size_t serialize(const T &t, uint8_t *&data, size_t &size)
Definition map_serializers.h:48
Definition champ_map.h:105
const V * getp(Hash hash, const K &k) const
Definition champ_map.h:108
bool foreach(F &&f) const
Definition champ_map.h:158
size_t put_mut(Hash hash, const K &k, const V &v)
Definition champ_map.h:120
std::array< std::vector< std::shared_ptr< Entry< K, V > > >, collision_bins > bins
Definition champ_map.h:106
size_t remove_mut(Hash hash, const K &k)
Definition champ_map.h:139
Definition champ_map.h:85
K key
Definition champ_map.h:86
Entry(K k, V v)
Definition champ_map.h:89
V value
Definition champ_map.h:87
const V * getp(const K &k) const
Definition champ_map.h:91
Definition champ_map.h:172
SmallIndex compressed_idx(SmallIndex idx) const
Definition champ_map.h:187
SubNodes()
Definition champ_map.h:177
std::pair< std::shared_ptr< SubNodes< K, V, H > >, size_t > put(SmallIndex depth, Hash hash, const K &k, const V &v) const
Definition champ_map.h:294
Bitmap data_map
Definition champ_map.h:175
size_t remove_mut(SmallIndex depth, Hash hash, const K &k)
Definition champ_map.h:304
size_t put_mut(SmallIndex depth, Hash hash, const K &k, const V &v)
Definition champ_map.h:217
bool foreach(SmallIndex depth, F &&f) const
Definition champ_map.h:349
std::vector< Node< K, V, H > > nodes
Definition champ_map.h:173
const V * getp(SmallIndex depth, Hash hash, const K &k) const
Definition champ_map.h:199
Bitmap node_map
Definition champ_map.h:174
std::pair< std::shared_ptr< SubNodes< K, V, H > >, size_t > remove(SmallIndex depth, Hash hash, const K &k) const
Definition champ_map.h:339
SubNodes(std::vector< Node< K, V, H > > &&ns)
Definition champ_map.h:179
SubNodes(std::vector< Node< K, V, H > > &&ns, Bitmap nm, Bitmap dm)
Definition champ_map.h:181