|
Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
|
Sharded concurrent hash map: Shards independently-locked DynMapHashTable partitions, no single global lock.
More...
#include <tpl_concurrent_hash_map.H>
Classes | |
| struct | Shard |
Public Types | |
| using | Hash_Fct_Ptr = typename Map::Hash_Fct_Ptr |
Hash function pointer type, matching DynMapHashTable's own. | |
Public Member Functions | |
| ConcurrentHashMap (Hash_Fct_Ptr hash_fct=dft_hash_ptr_fct< Key >, const Cmp &cmp=Cmp()) | |
Construct an empty map with Shards independently-locked partitions. | |
| ConcurrentHashMap (const ConcurrentHashMap &)=delete | |
Deleted copy constructor: shards own non-copyable std::shared_mutex instances. | |
| ConcurrentHashMap & | operator= (const ConcurrentHashMap &)=delete |
| Deleted copy assignment operator. | |
| ConcurrentHashMap (ConcurrentHashMap &&)=delete | |
| Deleted move constructor: no defined ordering exists to safely transfer locked shards out from under concurrent callers. | |
| ConcurrentHashMap & | operator= (ConcurrentHashMap &&)=delete |
| Deleted move assignment operator. | |
| bool | insert (const Key &key, const T &value) |
Insert key with a copy of value, only if key is absent. | |
| bool | insert (const Key &key, T &&value) |
Insert key with value moved in, only if key is absent. | |
| void | insert_or_assign (const Key &key, T value) |
Insert key with value, or overwrite the existing value if key is already present. | |
| bool | erase (const Key &key) |
Remove key if present. | |
| bool | contains (const Key &key) const |
Check whether key is present. | |
| std::optional< T > | find_copy (const Key &key) const |
Look up key and return a copy of its value, if present. | |
| template<typename F > | |
| bool | with_value (const Key &key, F &&f) const |
Invoke f with a const reference to key's value, while the owning shard is read-locked. | |
| template<typename F > | |
| bool | with_value_mut (const Key &key, F &&f) |
Invoke f with a mutable reference to key's value, while the owning shard is write-locked. | |
| void | clear () |
| Remove every entry from every shard. | |
| size_t | size () const |
| Return the total number of entries across all shards. | |
| bool | is_empty () const |
| Check whether every shard is currently empty. | |
Private Types | |
| using | Map = DynMapHashTable< Key, T, LhashTable, Cmp > |
Private Member Functions | |
| Shard & | shard_for (const Key &key) noexcept |
Resolve which shard owns key. | |
| const Shard & | shard_for (const Key &key) const noexcept |
const overload of shard_for(const Key&). | |
Private Attributes | |
| std::array< std::unique_ptr< Shard >, Shards > | shards_ |
| Hash_Fct_Ptr | hash_fct_ |
Sharded concurrent hash map: Shards independently-locked DynMapHashTable partitions, no single global lock.
See the file-level documentation in tpl_concurrent_hash_map.H for the full design rationale, thread-safety contract, and the specific consistency model of size()/snapshot().
| Key | Key type. Must satisfy whatever Cmp and the hash function require (typically equality-comparable and hashable). |
| T | Mapped value type. |
| Cmp | Key equality comparator, defaulting to Aleph::equal_to<Key>. |
| Shards | Number of independently-locked partitions. Must be at least 1; higher values reduce lock contention between keys that hash to different shards at the cost of Shards separate (smaller) hash tables and mutexes. |
Definition at line 153 of file tpl_concurrent_hash_map.H.
| using Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::Hash_Fct_Ptr = typename Map::Hash_Fct_Ptr |
Hash function pointer type, matching DynMapHashTable's own.
Definition at line 161 of file tpl_concurrent_hash_map.H.
|
private |
Definition at line 157 of file tpl_concurrent_hash_map.H.
|
inlineexplicit |
Construct an empty map with Shards independently-locked partitions.
| [in] | hash_fct | Hash function applied to keys to pick a shard and to place entries within it. Defaults to the same dft_hash_ptr_fct<Key> used by DynMapHashTable's own default constructor. |
| [in] | cmp | Key equality comparator, copied into every shard. |
| std::bad_alloc | if allocating any of the Shards shards fails. |
Definition at line 222 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), cmp(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shards_.
|
delete |
Deleted copy constructor: shards own non-copyable std::shared_mutex instances.
|
delete |
Deleted move constructor: no defined ordering exists to safely transfer locked shards out from under concurrent callers.
|
inline |
Remove every entry from every shard.
| std::system_error | if acquiring a shard's std::shared_mutex fails at the OS level; nothing otherwise (not noexcept specifically because that lock acquisition is not). |
Definition at line 467 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shards_.
Check whether key is present.
| [in] | key | Key to look up. |
true if present at the moment of the check. | std::system_error | if acquiring the shard's std::shared_mutex fails at the OS level; nothing otherwise. |
Definition at line 360 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for().
Referenced by TEST().
Remove key if present.
| [in] | key | Key to remove. |
true if key was present and removed, false otherwise. | std::system_error | if acquiring the shard's std::shared_mutex fails at the OS level; nothing else (unlinking a located entry does not move- or copy-construct T, only destroys it). |
Definition at line 331 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for().
Referenced by TEST().
|
inline |
Look up key and return a copy of its value, if present.
| [in] | key | Key to look up. |
key is present, std::nullopt otherwise. | Whatever | T's copy constructor throws. Also throws std::system_error if acquiring the shard's std::shared_mutex fails at the OS level. |
Definition at line 378 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for().
|
inline |
Insert key with a copy of value, only if key is absent.
| [in] | key | Key to insert. |
| [in] | value | Value to copy in. |
true if inserted, false if key was already present (the existing value is left untouched). | Whatever | Key's or T's copy constructor throws, or std::bad_alloc. If it throws, the map is left exactly as it was before the call. Also throws std::system_error if acquiring the shard's std::shared_mutex fails at the OS level. |
Definition at line 255 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for(), and value.
Referenced by TEST().
Insert key with value moved in, only if key is absent.
| [in] | key | Key to insert. |
| [in,out] | value | Value to move in. |
true if inserted, false if key was already present. | Whatever | Key's copy constructor or T's move constructor throws, or std::bad_alloc. If it throws, the map is left exactly as it was before the call. Also throws std::system_error if acquiring the shard's std::shared_mutex fails at the OS level. |
false return (duplicate key), value has still been moved from: the underlying table constructs the entry's Pair (moving value into it) before discovering the key already exists and discarding that entry. Do not read value after a false return; if you need to reuse it, check contains(key) first, or capture a copy before calling insert. Definition at line 282 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for(), and value.
|
inline |
Insert key with value, or overwrite the existing value if key is already present.
| [in] | key | Key to insert or update. |
| [in] | value | New value, moved into the map either as a fresh entry or via move-assignment over the existing one. |
| Whatever | Key's copy constructor, T's move constructor, or T's move assignment throws, or std::bad_alloc. If updating an existing entry's move assignment throws, that entry is left in whatever state T::operator=(T&&) leaves a failed assignment in (the map itself remains structurally valid: the key is still present). Also throws std::system_error if acquiring the shard's std::shared_mutex fails at the OS level. |
Definition at line 306 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for(), and value.
|
inline |
Check whether every shard is currently empty.
true if no shard held any entry at the moment each was checked. | std::system_error | if acquiring a shard's std::shared_mutex fails at the OS level; nothing otherwise. |
size(). Definition at line 505 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shards_.
|
delete |
Deleted move assignment operator.
|
delete |
Deleted copy assignment operator.
|
inlineprivatenoexcept |
const overload of shard_for(const Key&).
Definition at line 204 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::hash_fct_, and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shards_.
|
inlineprivatenoexcept |
Resolve which shard owns key.
| [in] | key | Key to hash. |
key. hash_fct_ is a deterministic, pure function of key alone: calling it twice with an equal key must yield the same shard index, or a key can effectively "move" between shards between calls and become invisible to later lookups. hash_fct_ must not throw: this function is noexcept but calls hash_fct_(key) directly, so a throwing hash function would call std::terminate() here instead of propagating. Definition at line 198 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::hash_fct_, and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shards_.
Referenced by Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::contains(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::erase(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::find_copy(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::insert(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::insert(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::insert_or_assign(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::with_value(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::with_value_mut().
|
inline |
Return the total number of entries across all shards.
| std::system_error | if acquiring a shard's std::shared_mutex fails at the OS level; nothing otherwise. |
size()/snapshot() consistency. Definition at line 486 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shards_.
|
inline |
Invoke f with a const reference to key's value, while the owning shard is read-locked.
| F | Callable, invocable as f(const T&), whose return value (if any) must not be a reference. |
| [in] | key | Key to look up. |
| [in] | f | Callback invoked with the value if key is present. |
true if key was present and f was invoked, false otherwise. | Whatever | f throws, propagated after the lock is released. Also throws std::system_error if acquiring the shard's std::shared_mutex fails at the OS level (before f is ever invoked). |
f runs with the shard locked: keep it short, and never call back into this same ConcurrentHashMap from within f (that would deadlock if it targets the same shard). Definition at line 409 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for().
|
inline |
Invoke f with a mutable reference to key's value, while the owning shard is write-locked.
| F | Callable, invocable as f(T&), whose return value (if any) must not be a reference. |
| [in] | key | Key to look up. |
| [in] | f | Callback invoked with the value if key is present; may mutate it in place. |
true if key was present and f was invoked, false otherwise. | Whatever | f throws, propagated after the lock is released. Also throws std::system_error if acquiring the shard's std::shared_mutex fails at the OS level (before f is ever invoked). |
f runs with the shard exclusively locked: keep it short, and never call back into this same ConcurrentHashMap from within f. Definition at line 442 of file tpl_concurrent_hash_map.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for().
|
private |
Definition at line 184 of file tpl_concurrent_hash_map.H.
Referenced by Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for().
|
private |
Definition at line 183 of file tpl_concurrent_hash_map.H.
Referenced by Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::ConcurrentHashMap(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::clear(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::is_empty(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for(), Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::shard_for(), and Aleph::ConcurrentHashMap< Key, T, Cmp, Shards >::size().