23 static constexpr size_t index_mask_bits = 5;
24 static constexpr size_t index_mask = (1 << index_mask_bits) - 1;
27 static constexpr size_t hash_bits =
sizeof(
Hash) * 8;
30 static constexpr size_t small_index_bits =
sizeof(
SmallIndex) * 8;
31 static_assert(small_index_bits > index_mask_bits);
33 static constexpr size_t collision_node_bits = hash_bits % index_mask_bits;
34 static_assert(collision_node_bits > 0);
35 static constexpr SmallIndex collision_depth = hash_bits / index_mask_bits;
36 static constexpr size_t collision_bins = 1 << collision_node_bits;
40 return (hash >> ((
Hash)depth * index_mask_bits)) & index_mask;
43 template <
class K,
class V,
class H = std::hash<K>>
53 constexpr Bitmap(uint32_t bits) : _bits(bits) {}
57 return {_bits & other._bits};
62 return __builtin_popcount(_bits);
67 return {_bits | (
static_cast<uint32_t
>(1) << idx)};
72 return {_bits & ~(
static_cast<uint32_t
>(1) << idx)};
77 return (_bits & (
static_cast<uint32_t
>(1) << idx)) != 0;
81 template <
class K,
class V,
class H>
84 template <
class K,
class V>
92 [[nodiscard]]
const V*
getp(
const K& k)
const
102 template <
class K,
class V,
class H>
103 using Node = std::shared_ptr<void>;
105 template <
class K,
class V,
class H>
108 std::array<std::vector<std::shared_ptr<Entry<K, V>>>, collision_bins>
bins;
110 [[nodiscard]]
const V*
getp(
Hash hash,
const K& k)
const
112 const auto idx = mask(hash, collision_depth);
113 const auto& bin =
bins[idx];
114 for (
const auto& node : bin)
126 const auto idx = mask(hash, collision_depth);
127 auto& bin =
bins[idx];
128 for (
size_t i = 0; i < bin.size(); ++i)
130 const auto& entry = bin[i];
133 const auto diff = map::get_serialized_size_with_padding(entry->key) +
134 map::get_serialized_size_with_padding(entry->value);
135 bin[i] = std::make_shared<Entry<K, V>>(k, v);
139 bin.push_back(std::make_shared<
Entry<K, V>>(k, v));
145 const auto idx = mask(hash, collision_depth);
146 auto& bin =
bins[idx];
147 for (
size_t i = 0; i < bin.size(); ++i)
149 const auto& entry = bin[i];
152 const auto diff = map::get_serialized_size_with_padding(entry->key) +
153 map::get_serialized_size_with_padding(entry->value);
154 bin.erase(bin.begin() + i);
162 bool foreach(F&& f)
const
164 for (
const auto& bin :
bins)
166 for (
const auto& entry : bin)
168 if (!std::forward<F>(f)(entry->key, entry->value))
178 template <
class K,
class V,
class H>
202 const auto mask =
Bitmap(~(
static_cast<uint32_t
>(-1) << idx));
213 const auto idx = mask(hash, depth);
223 return node_as<Entry<K, V>>(c_idx)->
getp(k);
226 if (depth == (collision_depth - 1))
228 return node_as<Collisions<K, V, H>>(c_idx)->
getp(hash, k);
231 return node_as<SubNodes<K, V, H>>(c_idx)->
getp(depth + 1, hash, k);
237 const auto idx = mask(hash, depth);
252 if (depth < (collision_depth - 1))
254 auto sn = *node_as<SubNodes<K, V, H>>(c_idx);
255 insert = sn.put_mut(depth + 1, hash, k, v);
256 nodes[c_idx] = std::make_shared<SubNodes<K, V, H>>(std::move(sn));
260 auto sn = *node_as<Collisions<K, V, H>>(c_idx);
261 insert = sn.put_mut(hash, k, v);
262 nodes[c_idx] = std::make_shared<Collisions<K, V, H>>(std::move(sn));
267 const auto& entry0 = node_as<Entry<K, V>>(c_idx);
268 if (k == entry0->key)
270 auto current_size = map::get_serialized_size_with_padding(entry0->key) +
271 map::get_serialized_size_with_padding(entry0->value);
272 nodes[c_idx] = std::make_shared<Entry<K, V>>(k, v);
276 if (depth < (collision_depth - 1))
278 const auto hash0 = H()(entry0->key);
279 const auto idx0 = mask(hash0, depth + 1);
282 sub_node.
put_mut(depth + 1, hash, k, v);
289 nodes.begin() + c_idx,
295 const auto hash0 = H()(entry0->key);
296 const auto idx0 = mask(hash0, collision_depth);
297 sub_node.bins[idx0].push_back(entry0);
298 const auto idx1 = mask(hash, collision_depth);
299 sub_node.bins[idx1].push_back(std::make_shared<
Entry<K, V>>(k, v));
306 nodes.begin() + c_idx,
312 [[nodiscard]] std::pair<std::shared_ptr<SubNodes<K, V, H>>,
size_t>
put(
316 auto r = node.put_mut(depth, hash, k, v);
317 return std::make_pair(
324 const auto idx = mask(hash, depth);
334 const auto& entry = node_as<Entry<K, V>>(c_idx);
340 const auto diff = map::get_serialized_size_with_padding(entry->key) +
341 map::get_serialized_size_with_padding(entry->value);
347 if (depth == (collision_depth - 1))
349 auto sn = *node_as<Collisions<K, V, H>>(c_idx);
350 const auto diff = sn.remove_mut(hash, k);
351 nodes[c_idx] = std::make_shared<Collisions<K, V, H>>(std::move(sn));
355 auto sn = *node_as<SubNodes<K, V, H>>(c_idx);
356 const auto diff = sn.remove_mut(depth + 1, hash, k);
357 nodes[c_idx] = std::make_shared<SubNodes<K, V, H>>(std::move(sn));
361 [[nodiscard]] std::pair<std::shared_ptr<SubNodes<K, V, H>>,
size_t>
remove(
365 auto r = node.remove_mut(depth, hash, k);
366 return std::make_pair(
376 const auto& entry = node_as<Entry<K, V>>(i);
377 if (!std::forward<F>(f)(entry->key, entry->value))
382 for (
size_t i = entries; i <
nodes.size(); ++i)
384 if (depth == (collision_depth - 1))
394 depth + 1, std::forward<F>(f)))
405 [[nodiscard]]
const std::shared_ptr<A>& node_as(
SmallIndex c_idx)
const
407 return reinterpret_cast<const std::shared_ptr<A>&
>(
nodes[c_idx]);
411 template <
class K,
class V,
class H = std::hash<K>>
415 std::shared_ptr<SubNodes<K, V, H>> root;
417 size_t serialized_size = 0;
422 size_t serialized_size_) :
423 root(std::move(root_)),
425 serialized_size(serialized_size_)
435 [[nodiscard]]
size_t size()
const
442 return serialized_size;
447 return map_size == 0;
450 [[nodiscard]] std::optional<V>
get(
const K& key)
const
452 auto v = root->getp(0, H()(key), key);
461 [[nodiscard]]
const V*
getp(
const K& key)
const
463 return root->getp(0, H()(key), key);
468 auto r = root->
put(0, H()(key), key, value);
469 auto size_ = map_size;
475 const auto size_change = (map::get_serialized_size_with_padding(key) +
476 map::get_serialized_size_with_padding(value)) -
479 return Map(std::move(r.first), size_, size_change + serialized_size);
484 auto r = root->
remove(0, H()(key), key);
485 auto size_ = map_size;
491 return Map(std::move(r.first), size_, serialized_size - r.second);
495 bool foreach(F&& f)
const
497 return root->foreach(0, std::forward<F>(f));
502 return std::make_unique<Snapshot>(*
this);
506 template <
class K,
class V,
class H>
518 KVTuple(K* k_,
Hash h_k_, V* v_) : k(k_), h_k(h_k_), v(v_) {}
526 return map.get_serialized_size();
531 std::vector<KVTuple> ordered_state;
532 ordered_state.reserve(
map.size());
533 size_t serialized_size = 0;
535 map.foreach([&ordered_state, &serialized_size](
auto& key,
auto& value) {
538 uint32_t key_size = map::get_serialized_size_with_padding(key);
539 uint32_t value_size = map::get_serialized_size_with_padding(value);
540 serialized_size += (key_size + value_size);
542 ordered_state.emplace_back(k,
static_cast<Hash>(H()(key)), v);
550 ordered_state.begin(), ordered_state.end(), [](KVTuple& i, KVTuple& j) {
551 return i.h_k < j.h_k;
555 serialized_size ==
map.get_serialized_size(),
556 "Serialized size:{}, map.get_serialized_size():{} (map count:{}, "
557 "ordered state count:{})",
559 map.get_serialized_size(),
561 ordered_state.size());
563 for (
const auto& p : ordered_state)
567 map::add_padding(key_size, data, serialized_size);
570 uint32_t value_size =
map::serialize(*p.v, data, serialized_size);
571 map::add_padding(value_size, data, serialized_size);
575 serialized_size == 0,
576 "Serialization buffer is not complete, remaining:{}/{}",
578 map.get_serialized_size());
#define CCF_ASSERT_FMT(expr,...)
Definition ccf_assert.h:10
Definition champ_map.h:47
constexpr Bitmap operator&(const Bitmap &other) const
Definition champ_map.h:55
constexpr Bitmap()
Definition champ_map.h:51
constexpr Bitmap clear(SmallIndex idx) const
Definition champ_map.h:70
constexpr Bitmap set(SmallIndex idx) const
Definition champ_map.h:65
constexpr bool check(SmallIndex idx) const
Definition champ_map.h:75
constexpr Bitmap(uint32_t bits)
Definition champ_map.h:53
constexpr SmallIndex pop() const
Definition champ_map.h:60
Definition champ_map.h:413
Map< K, V, H > remove(const K &key) const
Definition champ_map.h:482
std::unique_ptr< Snapshot > make_snapshot() const
Definition champ_map.h:500
Map()
Definition champ_map.h:433
V ValueType
Definition champ_map.h:430
K KeyType
Definition champ_map.h:429
std::optional< V > get(const K &key) const
Definition champ_map.h:450
size_t get_serialized_size() const
Definition champ_map.h:440
Snapshot< K, V, H > Snapshot
Definition champ_map.h:431
Map< K, V, H > put(const K &key, const V &value) const
Definition champ_map.h:466
size_t size() const
Definition champ_map.h:435
const V * getp(const K &key) const
Definition champ_map.h:461
bool empty() const
Definition champ_map.h:445
Definition champ_map.h:508
Snapshot(const Map< K, V, H > &map_)
Definition champ_map.h:522
size_t get_serialized_size()
Definition champ_map.h:524
void serialize(uint8_t *data)
Definition champ_map.h:529
Definition champ_map.h:17
std::shared_ptr< void > Node
Definition champ_map.h:103
uint32_t Hash
Definition champ_map.h:26
uint8_t SmallIndex
Definition champ_map.h:29
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:107
const V * getp(Hash hash, const K &k) const
Definition champ_map.h:110
bool foreach(F &&f) const
Definition champ_map.h:162
size_t put_mut(Hash hash, const K &k, const V &v)
Definition champ_map.h:124
std::array< std::vector< std::shared_ptr< Entry< K, V > > >, collision_bins > bins
Definition champ_map.h:108
size_t remove_mut(Hash hash, const K &k)
Definition champ_map.h:143
Definition champ_map.h:86
K key
Definition champ_map.h:87
Entry(K k, V v)
Definition champ_map.h:90
V value
Definition champ_map.h:88
const V * getp(const K &k) const
Definition champ_map.h:92
Definition champ_map.h:180
SmallIndex compressed_idx(SmallIndex idx) const
Definition champ_map.h:195
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:312
Bitmap data_map
Definition champ_map.h:183
size_t remove_mut(SmallIndex depth, Hash hash, const K &k)
Definition champ_map.h:322
size_t put_mut(SmallIndex depth, Hash hash, const K &k, const V &v)
Definition champ_map.h:235
bool foreach(SmallIndex depth, F &&f) const
Definition champ_map.h:371
std::vector< Node< K, V, H > > nodes
Definition champ_map.h:181
const V * getp(SmallIndex depth, Hash hash, const K &k) const
Definition champ_map.h:211
Bitmap node_map
Definition champ_map.h:182
std::pair< std::shared_ptr< SubNodes< K, V, H > >, size_t > remove(SmallIndex depth, Hash hash, const K &k) const
Definition champ_map.h:361
SubNodes(std::vector< Node< K, V, H > > &&ns)
Definition champ_map.h:187
SubNodes(std::vector< Node< K, V, H > > &&ns, Bitmap nm, Bitmap dm)
Definition champ_map.h:189