PMDK C++ bindings
1.12-git53.g67ba2be4
This is the C++ bindings documentation for PMDK's libpmemobj.
|
Persistent memory aware implementation of Intel TBB concurrent_hash_map. More...
#include <libpmemobj++/container/concurrent_hash_map.hpp>
Classes | |
class | accessor |
Allows write access to elements and combines data access, locking, and garbage collection. More... | |
class | bucket_accessor |
Bucket accessor is to find, rehash, acquire a lock, and access a bucket. More... | |
class | const_accessor |
Combines data access, locking, and garbage collection. More... | |
class | mutex_vector |
Vector of locks to be unlocked at the destruction time. More... | |
class | serial_bucket_accessor |
Serial bucket accessor used to access bucket in a serial operations. More... | |
Public Member Functions | |
concurrent_hash_map () | |
Construct empty table. | |
concurrent_hash_map (size_type n) | |
Construct empty table with n preallocated buckets. More... | |
concurrent_hash_map (const concurrent_hash_map &table) | |
Copy constructor. | |
concurrent_hash_map (concurrent_hash_map &&table) | |
Move constructor. | |
template<typename I > | |
concurrent_hash_map (I first, I last) | |
Construction table with copying iteration range. | |
concurrent_hash_map (std::initializer_list< value_type > il) | |
Construct table with initializer list. | |
void | runtime_initialize () |
Initialize persistent concurrent hash map after process restart. More... | |
concurrent_hash_map & | operator= (const concurrent_hash_map &table) |
Assignment Not thread safe. More... | |
concurrent_hash_map & | operator= (std::initializer_list< value_type > il) |
Assignment Not thread safe. More... | |
void | rehash (size_type n=0) |
Rehashes and optionally resizes the whole table. More... | |
void | clear () |
Clear hash map content Not thread safe. More... | |
void | free_data () |
Destroys the concurrent_hash_map. More... | |
~concurrent_hash_map () | |
free_data should be called before concurrent_hash_map destructor is called. More... | |
iterator | begin () |
iterator | end () |
const_iterator | begin () const |
const_iterator | end () const |
size_type | size () const |
bool | empty () const |
size_type | max_size () const |
Upper bound on size. | |
size_type | bucket_count () const |
void | swap (concurrent_hash_map &table) |
Swap two instances. More... | |
size_type | count (const Key &key) const |
template<typename K , typename = typename std::enable_if< concurrent_hash_map_internal:: has_transparent_key_equal<hasher>::value, K>::type> | |
size_type | count (const K &key) const |
This overload only participates in overload resolution if the qualified-id Hash::transparent_key_equal is valid and denotes a type. More... | |
bool | find (const_accessor &result, const Key &key) const |
Find item and acquire a read lock on the item. More... | |
template<typename K , typename = typename std::enable_if< concurrent_hash_map_internal:: has_transparent_key_equal<hasher>::value, K>::type> | |
bool | find (const_accessor &result, const K &key) const |
Find item and acquire a read lock on the item. More... | |
bool | find (accessor &result, const Key &key) |
Find item and acquire a write lock on the item. More... | |
template<typename K , typename = typename std::enable_if< concurrent_hash_map_internal:: has_transparent_key_equal<hasher>::value, K>::type> | |
bool | find (accessor &result, const K &key) |
Find item and acquire a write lock on the item. More... | |
bool | insert (const_accessor &result, const Key &key) |
Insert item (if not already present) and acquire a read lock on the item. More... | |
bool | insert (accessor &result, const Key &key) |
Insert item (if not already present) and acquire a write lock on the item. More... | |
bool | insert (const_accessor &result, const value_type &value) |
Insert item by copying if there is no such key present already and acquire a read lock on the item. More... | |
bool | insert (accessor &result, const value_type &value) |
Insert item by copying if there is no such key present already and acquire a write lock on the item. More... | |
bool | insert (const value_type &value) |
Insert item by copying if there is no such key present already. More... | |
bool | insert (const_accessor &result, value_type &&value) |
Insert item by copying if there is no such key present already and acquire a read lock on the item. More... | |
bool | insert (accessor &result, value_type &&value) |
Insert item by copying if there is no such key present already and acquire a write lock on the item. More... | |
bool | insert (value_type &&value) |
Insert item by copying if there is no such key present already. More... | |
template<typename I > | |
void | insert (I first, I last) |
Insert range [first, last) More... | |
void | insert (std::initializer_list< value_type > il) |
Insert initializer list. More... | |
template<typename M > | |
bool | insert_or_assign (const key_type &key, M &&obj) |
Inserts item if there is no such key present already, assigns provided value otherwise. More... | |
template<typename M > | |
bool | insert_or_assign (key_type &&key, M &&obj) |
Inserts item if there is no such key present already, assigns provided value otherwise. More... | |
template<typename K , typename M , typename = typename std::enable_if< concurrent_hash_map_internal::has_transparent_key_equal< hasher>::value && std::is_constructible<key_type, K>::value, K>::type> | |
bool | insert_or_assign (K &&key, M &&obj) |
Inserts item if there is no such key-comparable type present already, assigns provided value otherwise. More... | |
bool | erase (const Key &key) |
Remove element with corresponding key. More... | |
pobj_defrag_result | defragment (double start_percent=0, double amount_percent=100) |
Defragment the given (by 'start_percent' and 'amount_percent') part of buckets of the hash map. More... | |
template<typename K , typename = typename std::enable_if< concurrent_hash_map_internal:: has_transparent_key_equal<hasher>::value, K>::type> | |
bool | erase (const K &key) |
Remove element with corresponding key. More... | |
Protected Member Functions | |
void | internal_copy (const concurrent_hash_map &source) |
Copy "source" to *this, where *this must start out empty. | |
void | defrag_save_nodes (bucket *b, pmem::obj::defrag &defrag) |
Internal method used by defragment(). More... | |
Persistent memory aware implementation of Intel TBB concurrent_hash_map.
The implementation is based on a concurrent hash table algorithm (https://arxiv.org/ftp/arxiv/papers/1509/1509.02235.pdf) where elements are assigned to buckets based on a hash code calculated from a key. In addition to concurrent find, insert, and erase operations, the algorithm employs resizing and on-demand per-bucket rehashing. The hash table consists of an array of buckets, and each bucket consists of a list of nodes and a read-write lock to control concurrent access by multiple threads.
Each time, the pool with concurrent_hash_map is being opened, the concurrent_hash_map requires runtime_initialize() to be called (in order to recalculate mask and restore the size).
find(), insert(), erase() (and all overloads) are guaranteed to be thread-safe.
When a thread holds accessor to an element with a certain key, it is not allowed to call find, insert nor erase with that key.
MutexType defines type of read write lock used in concurrent_hash_map. ScopedLockType defines a mutex wrapper that provides RAII-style mechanism for owning a mutex. It should implement following methods and constructors: ScopedLockType() ScopedLockType(rw_mutex_type &m, bool write = true) void acquire(rw_mutex_type &m, bool write) void release() bool try_acquire(rw_mutex_type &m, bool write)
and optionally: bool upgrade_to_writer() bool downgrade_to_reader() bool is_writer (variable)
Implementing all optional methods and supplying is_writer variable can improve performance if MutexType supports efficient upgrading and downgrading operations.
Testing note: In some case, helgrind and drd might report lock ordering errors for concurrent_hash_map. This might happen when calling find, insert or erase while already holding an accessor to some element.
The typical usage example would be:
The example of storing strings without necessity of using transactions would be:
|
inline |
Construct empty table with n preallocated buckets.
This number serves also as initial concurrency level.
|
inline |
free_data should be called before concurrent_hash_map destructor is called.
Otherwise, program can terminate if an exception occurs while freeing memory inside dtor.
Hash map can NOT be used after free_data() was called (unless it was called in a transaction and that transaction aborted).
|
inline |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
|
inline |
void pmem::obj::concurrent_hash_map< Key, T, Hash, KeyEqual, MutexType, ScopedLockType >::clear |
Clear hash map content Not thread safe.
pmem::transaction_error | in case of PMDK transaction failure |
|
inline |
This overload only participates in overload resolution if the qualified-id Hash::transparent_key_equal is valid and denotes a type.
This assumes that such Hash is callable with both K and Key type, and that its key_equal is transparent, which, together, allows calling this function without constructing an instance of Key
pmem::transaction_scope_error | if called inside transaction |
|
inline |
pmem::transaction_scope_error | if called inside transaction |
|
inlineprotected |
Internal method used by defragment().
Adds nodes to the defragmentation list.
|
inline |
Defragment the given (by 'start_percent' and 'amount_percent') part of buckets of the hash map.
The algorithm is 'opportunistic' - if it is not able to lock a bucket it will just skip it.
std::range_error | if the range: [start_percent, start_percent + amount_percent] is incorrect. |
rethrows | pmem::defrag_error when a failure during defragmentation occurs. Even if this error is thrown, some of objects could have been relocated, see in such case defrag_error.result for summary stats. |
|
inline |
|
inline |
|
inline |
|
inline |
Remove element with corresponding key.
This overload only participates in overload resolution if the qualified-id Hash::transparent_key_equal is valid and denotes a type. This assumes that such Hash is callable with both K and Key type, and that its key_equal is transparent, which, together, allows calling this function without constructing an instance of Key
pmem::transaction_free_error | in case of PMDK unable to free the memory |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Remove element with corresponding key.
pmem::transaction_free_error | in case of PMDK unable to free the memory |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Find item and acquire a write lock on the item.
This overload only participates in overload resolution if the qualified-id Hash::transparent_key_equal is valid and denotes a type. This assumes that such Hash is callable with both K and Key type, and that its key_equal is transparent, which, together, allows calling this function without constructing an instance of Key
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Find item and acquire a write lock on the item.
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Find item and acquire a read lock on the item.
This overload only participates in overload resolution if the qualified-id Hash::transparent_key_equal is valid and denotes a type. This assumes that such Hash is callable with both K and Key type, and that its key_equal is transparent, which, together, allows calling this function without constructing an instance of Key
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Find item and acquire a read lock on the item.
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Destroys the concurrent_hash_map.
Unlike destructor it will throw an exception in case of any failure (e.g. not enough space for a transactional data). If that happens, it might be necessary to free some other data in the pool.
Should be called before concurrent_hash_map destructor is called. Otherwise, program can terminate if an exception occurs while freeing memory inside dtor.
Hash map can NOT be used after free_data() was called (unless this was done in a transaction and transaction aborted).
std::transaction_error | in case of PMDK transaction failure |
pmem::transaction_free_error | when freeing underlying memory failed. |
|
inline |
Insert item (if not already present) and acquire a write lock on the item.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert item by copying if there is no such key present already and acquire a write lock on the item.
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert item by copying if there is no such key present already and acquire a write lock on the item.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert item by copying if there is no such key present already.
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert item (if not already present) and acquire a read lock on the item.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert item by copying if there is no such key present already and acquire a read lock on the item.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert item by copying if there is no such key present already and acquire a read lock on the item.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert range [first, last)
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert initializer list.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Insert item by copying if there is no such key present already.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Inserts item if there is no such key present already, assigns provided value otherwise.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Inserts item if there is no such key-comparable type present already, assigns provided value otherwise.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Inserts item if there is no such key present already, assigns provided value otherwise.
pmem::transaction_alloc_error | on allocation failure. |
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Assignment Not thread safe.
std::transaction_error | in case of PMDK transaction failure |
pmem::transaction_alloc_error | when allocating new memory failed. |
pmem::transaction_free_error | when freeing old underlying array failed. |
rethrows | constructor's exception. |
|
inline |
Assignment Not thread safe.
std::transaction_error | in case of PMDK transaction failure |
pmem::transaction_alloc_error | when allocating new memory failed. |
pmem::transaction_free_error | when freeing old underlying array failed. |
rethrows | constructor's exception. |
void pmem::obj::concurrent_hash_map< Key, T, Hash, KeyEqual, MutexType, ScopedLockType >::rehash | ( | size_type | n = 0 | ) |
Rehashes and optionally resizes the whole table.
Useful to optimize performance before or after concurrent operations. Not thread safe.
pmem::transaction_scope_error | if called inside transaction |
|
inline |
Initialize persistent concurrent hash map after process restart.
MUST be called every time after process restart. Not thread safe.
pmem::layout_error | if hashmap was created using incompatible version of libpmemobj-cpp |
|
inline |
void pmem::obj::concurrent_hash_map< Key, T, Hash, KeyEqual, MutexType, ScopedLockType >::swap | ( | concurrent_hash_map< Key, T, Hash, KeyEqual, MutexType, ScopedLockType > & | table | ) |
Swap two instances.
Iterators are invalidated. Not thread safe.