Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node > Class Template Reference

Intrusive hash table. More...

#include <hashmap.h>

Inheritance diagram for roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >:
Collaboration diagram for roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >:

Public Types

typedef OwnershipPolicy< T >::Pointer Pointer
 Pointer type. More...
 

Public Member Functions

 Hashmap (IArena &arena)
 Initialize empty hashmap with arena. More...
 
 ~Hashmap ()
 Release ownership of all elements. More...
 
size_t capacity () const
 Get maximum number of elements that can be added to hashmap before grow() should be called. More...
 
size_t size () const
 Get number of elements added to hashmap. More...
 
bool is_empty () const
 Check if size is zero. More...
 
bool contains (const T &elem) const
 Check if element belongs to hashmap. More...
 
template<class Key >
Pointer find (const Key &key) const
 Find element in the hashmap by key. More...
 
Pointer front () const
 Get first element in hashmap. Elements are ordered by insertion. More...
 
Pointer back () const
 Get last element in hashmap. Elements are ordered by insertion. More...
 
Pointer nextof (T &elem) const
 Get hashmap element next to given one. Elements are ordered by insertion. More...
 
Pointer prevof (T &elem) const
 Get hashmap element previous to given one. Elements are ordered by insertion. More...
 
ROC_ATTR_NODISCARD bool insert (T &elem)
 Insert element into hashmap. More...
 
void remove (T &elem)
 Remove element from hashmap. More...
 
ROC_ATTR_NODISCARD bool grow ()
 Grow hashtable capacity. More...
 

Detailed Description

template<class T, size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
class roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >

Intrusive hash table.

Characteristics: 1) Intrusive. Hash table nodes are stored directly in elements. No allocations are needed to insert a node. Arena is used only to allocate an array of buckets. 2) Collision-chaining. Implemented as an array of buckets, where a bucket is the head of a doubly-linked lists of bucket elements. 3) Controllable allocations. Allocations and deallocations are performed only when the hash table is explicitly growed. All other operations don't touch arena. 4) Zero allocations for small hash tables. A fixed number of buckets can be embedded directly into hash table object. 5) Incremental rehashing. After hash table growth, rehashing is performed incrementally when inserting and removing elements. The slower hash table size growth is, the less overhead rehashing adds to each operation. 6) Allows to iterate elements in insertion order. Implements safe iteration with regards to element insertion and deletion. Elements deleted during iteration won't be visited. Elements inserted during iteration will be visited.

Incremental rehashing technique is inspired by Go's map implementation, though there are differences. Load factor value is taken from it as well. Prime numbers for sizes are from https://planetmath.org/goodhashtableprimes.

Template Parameters
Tdefines object type, it must inherit HashmapNode and additionally implement three methods:
// get object key
Key key() const;
// compute key hash
static core::hashsum_t key_hash(Key key);
// compare two keys for equality
static bool key_equal(Key key1, Key key2);
size_t hashsum_t
Hash type.
Definition: hashsum.h:21

"Key" can be any type. Hashmap doesn't use it directly. It is never stored and is always accessed via the three methods above. The hash is computed for a key only once when an object is inserted into hash table.

Template Parameters
EmbeddedCapacitydefines the capacity embedded directly into Hashmap. It is used instead of dynamic memory while the number of elements is smaller than this capacity. The actual object size occupied to provide the requested capacity is implementation defined.
OwnershipPolicydefines ownership policy which is used to acquire an element ownership when it's added to the hashmap and release ownership when it's removed from the hashmap.
Nodedefines base class of hashmap nodes. It is needed if HashmapNode is used with non-default tag.

Definition at line 87 of file hashmap.h.

Member Typedef Documentation

◆ Pointer

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
typedef OwnershipPolicy<T>::Pointer roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::Pointer

Pointer type.

Remarks
either raw or smart pointer depending on the ownership policy.

Definition at line 92 of file hashmap.h.

Constructor & Destructor Documentation

◆ Hashmap()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::Hashmap ( IArena arena)
inlineexplicit

Initialize empty hashmap with arena.

Remarks
Hashmap capacity may grow using arena.

Definition at line 97 of file hashmap.h.

◆ ~Hashmap()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::~Hashmap ( )
inline

Release ownership of all elements.

Definition at line 102 of file hashmap.h.

Member Function Documentation

◆ back()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
Pointer roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::back ( ) const
inline

Get last element in hashmap. Elements are ordered by insertion.

Returns
last element or NULL if hashmap is empty.

Definition at line 177 of file hashmap.h.

◆ capacity()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
size_t roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::capacity ( ) const
inline

Get maximum number of elements that can be added to hashmap before grow() should be called.

Definition at line 115 of file hashmap.h.

◆ contains()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
bool roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::contains ( const T &  elem) const
inline

Check if element belongs to hashmap.

Note
  • has O(1) complexity
  • doesn't compute key hashes

Definition at line 134 of file hashmap.h.

◆ find()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
template<class Key >
Pointer roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::find ( const Key &  key) const
inline

Find element in the hashmap by key.

Returns
Pointer to the element with given key or NULL if it's not found.
Note
  • has O(1) complexity in average and O(n) in the worst case
  • computes key hash
The worst case is achieved when the hash function produces many collisions.

Definition at line 150 of file hashmap.h.

◆ front()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
Pointer roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::front ( ) const
inline

Get first element in hashmap. Elements are ordered by insertion.

Returns
first element or NULL if hashmap is empty.

Definition at line 165 of file hashmap.h.

◆ grow()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
ROC_ATTR_NODISCARD bool roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::grow ( )
inline

Grow hashtable capacity.

Remarks
Check if hash table is full (size is equal to capacity), and if so, increase hash table capacity and initiate incremental rehashing. Rehashing will be performed during subsequent insertions and removals.
Returns
  • true if no growth needed or growth succeeded
  • false if allocation failed
Note
  • has O(1) complexity
  • doesn't computes key hashes
  • makes allocations and deallocations
  • doesn't proceed lazy rehashing

Definition at line 287 of file hashmap.h.

◆ insert()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
ROC_ATTR_NODISCARD bool roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::insert ( T &  elem)
inline

Insert element into hashmap.

Remarks
  • acquires ownership of elem
Returns
false if the allocation failed
Precondition
  • elem should not be member of any hashmap
  • hashmap shouldn't have an element with the same key
Note
  • has O(1) complexity in average and O(n) in the worst case
  • computes key hash
  • doesn't make allocations or deallocations
  • proceeds lazy rehashing
Insertion speed is higher when insert to remove ratio is close to one or lower, and slows down when it becomes higher than one. The slow down is caused by the incremental rehashing algorithm.

Definition at line 243 of file hashmap.h.

◆ is_empty()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
bool roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::is_empty ( ) const
inline

Check if size is zero.

Definition at line 125 of file hashmap.h.

◆ nextof()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
Pointer roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::nextof ( T &  elem) const
inline

Get hashmap element next to given one. Elements are ordered by insertion.

Returns
hashmap element following elem if elem is not last, or NULL otherwise.
Precondition
elem should be member of this hashmap.

Definition at line 194 of file hashmap.h.

◆ prevof()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
Pointer roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::prevof ( T &  elem) const
inline

Get hashmap element previous to given one. Elements are ordered by insertion.

Returns
hashmap element preceding elem if elem is not first, or NULL otherwise.
Precondition
elem should be member of this hashmap.

Definition at line 212 of file hashmap.h.

◆ remove()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
void roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::remove ( T &  elem)
inline

Remove element from hashmap.

Remarks
  • releases ownership of elem
Precondition
elem should be member of this hashmap.
Note
  • has O(1) complexity
  • doesn't compute key hash
  • doesn't make allocations or deallocations
  • proceeds lazy rehashing

Definition at line 265 of file hashmap.h.

◆ size()

template<class T , size_t EmbeddedCapacity = 0, template< class TT > class OwnershipPolicy = RefCountedOwnership, class Node = HashmapNode<>>
size_t roc::core::Hashmap< T, EmbeddedCapacity, OwnershipPolicy, Node >::size ( ) const
inline

Get number of elements added to hashmap.

Definition at line 120 of file hashmap.h.


The documentation for this class was generated from the following file: