Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator > Class Template Reference

Unordered map from Key to T. More...

#include <concurrent_hash_map.h>

Inheritance diagram for tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >:
Collaboration diagram for tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >:

Classes

class  accessor
 Allows write access to elements and combines data access, locking, and garbage collection. More...
 
struct  accessor_not_used
 
class  bucket_accessor
 bucket accessor is to find, rehash, acquire a lock, and access a bucket More...
 
struct  call_clear_on_leave
 
class  const_accessor
 Combines data access, locking, and garbage collection. More...
 
struct  node
 

Public Types

typedef Key key_type
 
typedef T mapped_type
 
typedef std::pair< const Key, T > value_type
 
typedef hash_map_base::size_type size_type
 
typedef ptrdiff_t difference_type
 
typedef value_typepointer
 
typedef const value_typeconst_pointer
 
typedef value_typereference
 
typedef const value_typeconst_reference
 
typedef internal::hash_map_iterator< concurrent_hash_map, value_typeiterator
 
typedef internal::hash_map_iterator< concurrent_hash_map, const value_typeconst_iterator
 
typedef internal::hash_map_range< iteratorrange_type
 
typedef internal::hash_map_range< const_iteratorconst_range_type
 
typedef Allocator allocator_type
 

Public Member Functions

 concurrent_hash_map (const allocator_type &a=allocator_type())
 Construct empty table. More...
 
 concurrent_hash_map (const HashCompare &compare, const allocator_type &a=allocator_type())
 
 concurrent_hash_map (size_type n, const allocator_type &a=allocator_type())
 Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. More...
 
 concurrent_hash_map (size_type n, const HashCompare &compare, const allocator_type &a=allocator_type())
 
 concurrent_hash_map (const concurrent_hash_map &table, const allocator_type &a=allocator_type())
 Copy constructor. More...
 
 concurrent_hash_map (concurrent_hash_map &&table)
 Move constructor. More...
 
 concurrent_hash_map (concurrent_hash_map &&table, const allocator_type &a)
 Move constructor. More...
 
template<typename I >
 concurrent_hash_map (I first, I last, const allocator_type &a=allocator_type())
 Construction with copying iteration range and given allocator instance. More...
 
template<typename I >
 concurrent_hash_map (I first, I last, const HashCompare &compare, const allocator_type &a=allocator_type())
 
 concurrent_hash_map (std::initializer_list< value_type > il, const allocator_type &a=allocator_type())
 Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. More...
 
 concurrent_hash_map (std::initializer_list< value_type > il, const HashCompare &compare, const allocator_type &a=allocator_type())
 
concurrent_hash_mapoperator= (const concurrent_hash_map &table)
 Assignment. More...
 
concurrent_hash_mapoperator= (concurrent_hash_map &&table)
 Move Assignment. More...
 
concurrent_hash_mapoperator= (std::initializer_list< value_type > il)
 Assignment. More...
 
void rehash (size_type n=0)
 Rehashes and optionally resizes the whole table. More...
 
void clear ()
 Clear table. More...
 
 ~concurrent_hash_map ()
 Clear table and destroy it. More...
 
range_type range (size_type grainsize=1)
 
const_range_type range (size_type grainsize=1) const
 
iterator begin ()
 
iterator end ()
 
const_iterator begin () const
 
const_iterator end () const
 
std::pair< iterator, iteratorequal_range (const Key &key)
 
std::pair< const_iterator, const_iteratorequal_range (const Key &key) const
 
size_type size () const
 Number of items in table. More...
 
bool empty () const
 True if size()==0. More...
 
size_type max_size () const
 Upper bound on size. More...
 
size_type bucket_count () const
 Returns the current number of buckets. More...
 
allocator_type get_allocator () const
 return allocator object More...
 
void swap (concurrent_hash_map &table)
 swap two instances. Iterators are invalidated More...
 
size_type count (const Key &key) const
 Return count of items (0 or 1) More...
 
bool find (const_accessor &result, const Key &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...
 
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... Args>
bool emplace (const_accessor &result, Args &&... args)
 Insert item by copying if there is no such key present already and acquire a read lock on the item. More...
 
template<typename... Args>
bool emplace (accessor &result, Args &&... args)
 Insert item by copying if there is no such key present already and acquire a write lock on the item. More...
 
template<typename... Args>
bool emplace (Args &&... args)
 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...
 
bool erase (const Key &key)
 Erase item. More...
 
bool erase (const_accessor &item_accessor)
 Erase item by const_accessor. More...
 
bool erase (accessor &item_accessor)
 Erase item by accessor. More...
 

Protected Types

typedef Allocator::template rebind< node >::other node_allocator_type
 
- Protected Types inherited from tbb::interface5::internal::hash_map_base
typedef size_t size_type
 Size type. More...
 
typedef size_t hashcode_t
 Type of a hash code. More...
 
typedef size_t segment_index_t
 Segment index type. More...
 
typedef hash_map_node_base node_base
 Node base type. More...
 
typedef bucketsegment_ptr_t
 Segment pointer. More...
 
typedef segment_ptr_t segments_table_t[pointers_per_table]
 Segment pointers table type. More...
 

Protected Member Functions

void delete_node (node_base *n)
 
nodesearch_bucket (const key_type &key, bucket *b) const
 
void rehash_bucket (bucket *b_new, const hashcode_t h)
 
bool lookup (bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
 Insert or find item and optionally acquire a lock on the item. More...
 
template<typename Accessor >
bool generic_move_insert (Accessor &&result, value_type &&value)
 
template<typename Accessor , typename... Args>
bool generic_emplace (Accessor &&result, Args &&... args)
 
bool exclude (const_accessor &item_accessor)
 delete item by accessor More...
 
template<typename I >
std::pair< I, I > internal_equal_range (const Key &key, I end) const
 Returns an iterator for an item defined by the key, or for the next item after it (if upper==true) More...
 
void internal_copy (const concurrent_hash_map &source)
 Copy "source" to *this, where *this must start out empty. More...
 
template<typename I >
void internal_copy (I first, I last, size_type reserve_size)
 
const_pointer internal_fast_find (const Key &key) const
 Fast find when no concurrent erasure is used. For internal use inside TBB only! More...
 
- Protected Member Functions inherited from tbb::interface5::internal::hash_map_base
 hash_map_base ()
 Constructor. More...
 
void enable_segment (segment_index_t k, bool is_initial=false)
 Enable segment. More...
 
bucketget_bucket (hashcode_t h) const throw ()
 Get bucket by (masked) hashcode. More...
 
void mark_rehashed_levels (hashcode_t h) throw ()
 
bool check_mask_race (const hashcode_t h, hashcode_t &m) const
 Check for mask race. More...
 
bool check_rehashing_collision (const hashcode_t h, hashcode_t m_old, hashcode_t m) const
 Process mask race, check for rehashing collision. More...
 
segment_index_t insert_new_node (bucket *b, node_base *n, hashcode_t mask)
 Insert a node and check for load factor. More...
 
void reserve (size_type buckets)
 Prepare enough segments for number of buckets. More...
 
void internal_swap (hash_map_base &table)
 Swap hash_map_bases. More...
 

Static Protected Member Functions

static nodeallocate_node_copy_construct (node_allocator_type &allocator, const Key &key, const T *t)
 
static nodeallocate_node_move_construct (node_allocator_type &allocator, const Key &key, const T *t)
 
template<typename... Args>
static nodeallocate_node_emplace_construct (node_allocator_type &allocator, Args &&... args)
 
static nodeallocate_node_default_construct (node_allocator_type &allocator, const Key &key, const T *)
 
static nodedo_not_allocate_node (node_allocator_type &, const Key &, const T *)
 
- Static Protected Member Functions inherited from tbb::interface5::internal::hash_map_base
static segment_index_t segment_index_of (size_type index)
 
static segment_index_t segment_base (segment_index_t k)
 
static size_type segment_size (segment_index_t k)
 
static bool is_valid (void *ptr)
 
static void init_buckets (segment_ptr_t ptr, size_type sz, bool is_initial)
 Initialize buckets. More...
 
static void add_to_bucket (bucket *b, node_base *n)
 Add node. More...
 

Protected Attributes

node_allocator_type my_allocator
 
HashCompare my_hash_compare
 
- Protected Attributes inherited from tbb::interface5::internal::hash_map_base
atomic< hashcode_tmy_mask
 Hash mask = sum of allocated segment sizes - 1. More...
 
segments_table_t my_table
 Segment pointers table. Also prevents false sharing between my_mask and my_size. More...
 
atomic< size_typemy_size
 Size of container in stored items. More...
 
bucket my_embedded_segment [embedded_buckets]
 Zero segment. More...
 

Friends

template<typename Container , typename Value >
class internal::hash_map_iterator
 
template<typename I >
class internal::hash_map_range
 
class const_accessor
 
const_accessoraccessor_location (accessor_not_used const &)
 
const_accessoraccessor_location (const_accessor &a)
 
bool is_write_access_needed (accessor const &)
 
bool is_write_access_needed (const_accessor const &)
 
bool is_write_access_needed (accessor_not_used const &)
 

Additional Inherited Members

- Static Protected Attributes inherited from tbb::interface5::internal::hash_map_base
static size_type const embedded_block = 1
 Count of segments in the first block. More...
 
static size_type const embedded_buckets = 1<<embedded_block
 Count of segments in the first block. More...
 
static size_type const first_block = 8
 Count of segments in the first block. More...
 
static size_type const pointers_per_table = sizeof(segment_index_t) * 8
 Size of a pointer / table size. More...
 

Detailed Description

template<typename Key, typename T, typename HashCompare, typename Allocator>
class tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >

Unordered map from Key to T.

concurrent_hash_map is associative container with concurrent access.

Compatibility
The class meets all Container Requirements from C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1).
Exception Safety
  • Hash function is not permitted to throw an exception. User-defined types Key and T are forbidden from throwing an exception in destructors.
  • If exception happens during insert() operations, it has no effect (unless exception raised by HashCompare::hash() function during grow_segment).
  • If exception happens during operator=() operation, the container can have a part of source items, and methods size() and empty() can return wrong results.
Changes since TBB 2.1
  • Replaced internal algorithm and data structure. Patent is pending.
  • Added buckets number argument for constructor
Changes since TBB 2.0

Definition at line 52 of file concurrent_hash_map.h.

Member Typedef Documentation

◆ allocator_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef Allocator tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocator_type

Definition at line 552 of file concurrent_hash_map.h.

◆ const_iterator

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef internal::hash_map_iterator<concurrent_hash_map,const value_type> tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_iterator

Definition at line 549 of file concurrent_hash_map.h.

◆ const_pointer

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef const value_type* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_pointer

Definition at line 545 of file concurrent_hash_map.h.

◆ const_range_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef internal::hash_map_range<const_iterator> tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_range_type

Definition at line 551 of file concurrent_hash_map.h.

◆ const_reference

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef const value_type& tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_reference

Definition at line 547 of file concurrent_hash_map.h.

◆ difference_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef ptrdiff_t tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::difference_type

Definition at line 543 of file concurrent_hash_map.h.

◆ iterator

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef internal::hash_map_iterator<concurrent_hash_map,value_type> tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::iterator

Definition at line 548 of file concurrent_hash_map.h.

◆ key_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef Key tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::key_type

Definition at line 539 of file concurrent_hash_map.h.

◆ mapped_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef T tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::mapped_type

Definition at line 540 of file concurrent_hash_map.h.

◆ node_allocator_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef Allocator::template rebind<node>::other tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::node_allocator_type
protected

Definition at line 556 of file concurrent_hash_map.h.

◆ pointer

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef value_type* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::pointer

Definition at line 544 of file concurrent_hash_map.h.

◆ range_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef internal::hash_map_range<iterator> tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::range_type

Definition at line 550 of file concurrent_hash_map.h.

◆ reference

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef value_type& tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::reference

Definition at line 546 of file concurrent_hash_map.h.

◆ size_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef hash_map_base::size_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::size_type

Definition at line 542 of file concurrent_hash_map.h.

◆ value_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef std::pair<const Key,T> tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::value_type

Definition at line 541 of file concurrent_hash_map.h.

Constructor & Destructor Documentation

◆ concurrent_hash_map() [1/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( const allocator_type a = allocator_type())
inlineexplicit

Construct empty table.

Definition at line 758 of file concurrent_hash_map.h.

759  : internal::hash_map_base(), my_allocator(a)
760  {}

◆ concurrent_hash_map() [2/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( const HashCompare &  compare,
const allocator_type a = allocator_type() 
)
inlineexplicit

Definition at line 762 of file concurrent_hash_map.h.

763  : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare)
764  {}

◆ concurrent_hash_map() [3/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( size_type  n,
const allocator_type a = allocator_type() 
)
inline

Construct empty table with n preallocated buckets. This number serves also as initial concurrency level.

Definition at line 767 of file concurrent_hash_map.h.

768  : internal::hash_map_base(), my_allocator(a)
769  {
770  reserve( n );
771  }
void reserve(size_type buckets)
Prepare enough segments for number of buckets.

References tbb::interface5::internal::hash_map_base::reserve().

Here is the call graph for this function:

◆ concurrent_hash_map() [4/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( size_type  n,
const HashCompare &  compare,
const allocator_type a = allocator_type() 
)
inline

Definition at line 773 of file concurrent_hash_map.h.

774  : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare)
775  {
776  reserve( n );
777  }
void reserve(size_type buckets)
Prepare enough segments for number of buckets.

References tbb::interface5::internal::hash_map_base::reserve().

Here is the call graph for this function:

◆ concurrent_hash_map() [5/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( const concurrent_hash_map< Key, T, HashCompare, Allocator > &  table,
const allocator_type a = allocator_type() 
)
inline

Copy constructor.

Definition at line 780 of file concurrent_hash_map.h.

781  : internal::hash_map_base(), my_allocator(a)
782  {
783  call_clear_on_leave scope_guard(this);
784  internal_copy(table);
785  scope_guard.dismiss();
786  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::call_clear_on_leave::dismiss(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_copy().

Here is the call graph for this function:

◆ concurrent_hash_map() [6/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( concurrent_hash_map< Key, T, HashCompare, Allocator > &&  table)
inline

Move constructor.

Definition at line 790 of file concurrent_hash_map.h.

791  : internal::hash_map_base(), my_allocator(std::move(table.get_allocator()))
792  {
793  swap(table);
794  }
void swap(concurrent_hash_map &table)
swap two instances. Iterators are invalidated
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309

◆ concurrent_hash_map() [7/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( concurrent_hash_map< Key, T, HashCompare, Allocator > &&  table,
const allocator_type a 
)
inline

Move constructor.

Definition at line 797 of file concurrent_hash_map.h.

798  : internal::hash_map_base(), my_allocator(a)
799  {
800  if (a == table.get_allocator()){
801  this->swap(table);
802  }else{
803  call_clear_on_leave scope_guard(this);
804  internal_copy(std::make_move_iterator(table.begin()), std::make_move_iterator(table.end()), table.size());
805  scope_guard.dismiss();
806  }
807  }
void swap(concurrent_hash_map &table)
swap two instances. Iterators are invalidated
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::begin(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::call_clear_on_leave::dismiss(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::end(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::get_allocator(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_copy(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::size(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::swap().

Here is the call graph for this function:

◆ concurrent_hash_map() [8/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename I >
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( first,
last,
const allocator_type a = allocator_type() 
)
inline

Construction with copying iteration range and given allocator instance.

Definition at line 812 of file concurrent_hash_map.h.

813  : internal::hash_map_base(), my_allocator(a)
814  {
815  call_clear_on_leave scope_guard(this);
816  internal_copy(first, last, std::distance(first, last));
817  scope_guard.dismiss();
818  }
auto last(Container &c) -> decltype(begin(c))
auto first(Container &c) -> decltype(begin(c))
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::call_clear_on_leave::dismiss(), tbb::internal::first(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_copy(), and tbb::internal::last().

Here is the call graph for this function:

◆ concurrent_hash_map() [9/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename I >
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( first,
last,
const HashCompare &  compare,
const allocator_type a = allocator_type() 
)
inline

Definition at line 821 of file concurrent_hash_map.h.

822  : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare)
823  {
824  call_clear_on_leave scope_guard(this);
825  internal_copy(first, last, std::distance(first, last));
826  scope_guard.dismiss();
827  }
auto last(Container &c) -> decltype(begin(c))
auto first(Container &c) -> decltype(begin(c))
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::call_clear_on_leave::dismiss(), tbb::internal::first(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_copy(), and tbb::internal::last().

Here is the call graph for this function:

◆ concurrent_hash_map() [10/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( std::initializer_list< value_type il,
const allocator_type a = allocator_type() 
)
inline

Construct empty table with n preallocated buckets. This number serves also as initial concurrency level.

Definition at line 831 of file concurrent_hash_map.h.

832  : internal::hash_map_base(), my_allocator(a)
833  {
834  call_clear_on_leave scope_guard(this);
835  internal_copy(il.begin(), il.end(), il.size());
836  scope_guard.dismiss();
837  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

◆ concurrent_hash_map() [11/11]

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map ( std::initializer_list< value_type il,
const HashCompare &  compare,
const allocator_type a = allocator_type() 
)
inline

Definition at line 839 of file concurrent_hash_map.h.

840  : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare)
841  {
842  call_clear_on_leave scope_guard(this);
843  internal_copy(il.begin(), il.end(), il.size());
844  scope_guard.dismiss();
845  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::call_clear_on_leave::dismiss(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_copy().

Here is the call graph for this function:

◆ ~concurrent_hash_map()

template<typename Key, typename T, typename HashCompare, typename Allocator>
tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::~concurrent_hash_map ( )
inline

Clear table and destroy it.

Definition at line 896 of file concurrent_hash_map.h.

896 { clear(); }

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::clear().

Here is the call graph for this function:

Member Function Documentation

◆ allocate_node_copy_construct()

template<typename Key, typename T, typename HashCompare, typename Allocator>
static node* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_copy_construct ( node_allocator_type allocator,
const Key &  key,
const T *  t 
)
inlinestaticprotected

Definition at line 594 of file concurrent_hash_map.h.

594  {
595  return new( allocator ) node(key, *t);
596  }
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References key.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert().

Here is the caller graph for this function:

◆ allocate_node_default_construct()

template<typename Key, typename T, typename HashCompare, typename Allocator>
static node* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_default_construct ( node_allocator_type allocator,
const Key &  key,
const T *   
)
inlinestaticprotected

Definition at line 610 of file concurrent_hash_map.h.

610  {
611  return new( allocator ) node(key);
612  }
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References key.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert().

Here is the caller graph for this function:

◆ allocate_node_emplace_construct()

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename... Args>
static node* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_emplace_construct ( node_allocator_type allocator,
Args &&...  args 
)
inlinestaticprotected

Definition at line 604 of file concurrent_hash_map.h.

604  {
605  return new( allocator ) node(std::forward<Args>(args)...);
606  }

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_emplace().

Here is the caller graph for this function:

◆ allocate_node_move_construct()

template<typename Key, typename T, typename HashCompare, typename Allocator>
static node* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_move_construct ( node_allocator_type allocator,
const Key &  key,
const T *  t 
)
inlinestaticprotected

Definition at line 599 of file concurrent_hash_map.h.

599  {
600  return new( allocator ) node(key, std::move(*const_cast<T*>(t)));
601  }
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References key, and tbb::move().

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_move_insert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ begin() [1/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
iterator tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::begin ( )
inline

◆ begin() [2/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
const_iterator tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::begin ( ) const
inline

◆ bucket_count()

template<typename Key, typename T, typename HashCompare, typename Allocator>
size_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::bucket_count ( ) const
inline

Returns the current number of buckets.

Definition at line 928 of file concurrent_hash_map.h.

928 { return my_mask+1; }
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.

References tbb::interface5::internal::hash_map_base::my_mask.

◆ clear()

template<typename Key , typename T , typename HashCompare , typename A >
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::clear ( )

Clear table.

Definition at line 1384 of file concurrent_hash_map.h.

1384  {
1385  hashcode_t m = my_mask;
1386  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1387 #if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1388 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1389  int current_size = int(my_size), buckets = int(m)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics
1390  static bool reported = false;
1391 #endif
1392  bucket *bp = 0;
1393  // check consistency
1394  for( segment_index_t b = 0; b <= m; b++ ) {
1395  if( b & (b-2) ) ++bp; // not the beginning of a segment
1396  else bp = get_bucket( b );
1397  node_base *n = bp->node_list;
1398  __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" );
1399  __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during clear() execution" );
1400 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1401  if( n == internal::empty_rehashed ) empty_buckets++;
1402  else if( n == internal::rehash_req ) buckets--;
1403  else if( n->next ) overpopulated_buckets++;
1404 #endif
1405 #if __TBB_EXTRA_DEBUG
1406  for(; is_valid(n); n = n->next ) {
1407  hashcode_t h = my_hash_compare.hash( static_cast<node*>(n)->item.first );
1408  h &= m;
1409  __TBB_ASSERT( h == b || get_bucket(h)->node_list == internal::rehash_req, "hash() function changed for key in table or internal error" );
1410  }
1411 #endif
1412  }
1413 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1414 #if __TBB_STATISTICS
1415  printf( "items=%d buckets: capacity=%d rehashed=%d empty=%d overpopulated=%d"
1416  " concurrent: resizes=%u rehashes=%u restarts=%u\n",
1417  current_size, int(m+1), buckets, empty_buckets, overpopulated_buckets,
1418  unsigned(my_info_resizes), unsigned(my_info_rehashes), unsigned(my_info_restarts) );
1419  my_info_resizes = 0; // concurrent ones
1420  my_info_restarts = 0; // race collisions
1421  my_info_rehashes = 0; // invocations of rehash_bucket
1422 #endif
1423  if( buckets > current_size) empty_buckets -= buckets - current_size;
1424  else overpopulated_buckets -= current_size - buckets; // TODO: load_factor?
1425  if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) {
1427  "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d",
1429  typeid(*this).name(),
1430 #else
1431  "concurrent_hash_map",
1432 #endif
1433  current_size, empty_buckets, overpopulated_buckets );
1434  reported = true;
1435  }
1436 #endif
1437 #endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1438  my_size = 0;
1440  __TBB_ASSERT( s+1 == pointers_per_table || !my_table[s+1], "wrong mask or concurrent grow" );
1441  cache_aligned_allocator<bucket> alloc;
1442  do {
1443  __TBB_ASSERT( is_valid( my_table[s] ), "wrong mask or concurrent grow" );
1444  segment_ptr_t buckets_ptr = my_table[s];
1445  size_type sz = segment_size( s ? s : 1 );
1446  for( segment_index_t i = 0; i < sz; i++ )
1447  for( node_base *n = buckets_ptr[i].node_list; is_valid(n); n = buckets_ptr[i].node_list ) {
1448  buckets_ptr[i].node_list = n->next;
1449  delete_node( n );
1450  }
1451  if( s >= first_block) // the first segment or the next
1452  alloc.deallocate( buckets_ptr, sz );
1453  else if( s == embedded_block && embedded_block != first_block )
1454  alloc.deallocate( buckets_ptr, segment_size(first_block)-embedded_buckets );
1455  if( s >= embedded_block ) my_table[s] = 0;
1456  } while(s-- > 0);
1457  my_mask = embedded_buckets - 1;
1458 }
segments_table_t my_table
Segment pointers table. Also prevents false sharing between my_mask and my_size.
atomic< size_type > my_size
Size of container in stored items.
static size_type const embedded_block
Count of segments in the first block.
hash_map_node_base node_base
Node base type.
void const char const char int ITT_FORMAT __itt_group_sync s
static segment_index_t segment_index_of(size_type index)
static size_type const first_block
Count of segments in the first block.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
static hash_map_node_base *const empty_rehashed
Rehashed empty bucket flag.
static size_type const embedded_buckets
Count of segments in the first block.
void __TBB_EXPORTED_FUNC runtime_warning(const char *format,...)
Report a runtime warning.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
#define __TBB_USE_OPTIONAL_RTTI
Definition: tbb_config.h:126
static size_type segment_size(segment_index_t k)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
static size_type const pointers_per_table
Size of a pointer / table size.

References __TBB_ASSERT, __TBB_USE_OPTIONAL_RTTI, tbb::cache_aligned_allocator< T >::deallocate(), tbb::interface5::internal::empty_rehashed, h, int, tbb::interface5::internal::hash_map_base::bucket::mutex, tbb::interface5::internal::hash_map_node_base::next, tbb::interface5::internal::hash_map_base::bucket::node_list, tbb::interface5::internal::rehash_req, tbb::internal::runtime_warning(), and s.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::operator=(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::call_clear_on_leave::~call_clear_on_leave(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::~concurrent_hash_map().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ count()

template<typename Key, typename T, typename HashCompare, typename Allocator>
size_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::count ( const Key &  key) const
inline

Return count of items (0 or 1)

Definition at line 941 of file concurrent_hash_map.h.

941  {
942  return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false, &do_not_allocate_node );
943  }
static node * do_not_allocate_node(node_allocator_type &, const Key &, const T *)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::do_not_allocate_node(), and key.

Here is the call graph for this function:

◆ delete_node()

template<typename Key, typename T, typename HashCompare, typename Allocator>
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::delete_node ( node_base n)
inlineprotected

Definition at line 589 of file concurrent_hash_map.h.

589  {
590  my_allocator.destroy( static_cast<node*>(n) );
591  my_allocator.deallocate( static_cast<node*>(n), 1);
592  }

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_allocator.

◆ do_not_allocate_node()

template<typename Key, typename T, typename HashCompare, typename Allocator>
static node* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::do_not_allocate_node ( node_allocator_type ,
const Key &  ,
const T *   
)
inlinestaticprotected

Definition at line 614 of file concurrent_hash_map.h.

614  {
615  __TBB_ASSERT(false,"this dummy function should not be called");
616  return NULL;
617  }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169

References __TBB_ASSERT.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::count(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::find(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_emplace().

Here is the caller graph for this function:

◆ emplace() [1/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename... Args>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::emplace ( const_accessor result,
Args &&...  args 
)
inline

Insert item by copying if there is no such key present already and acquire a read lock on the item.

Returns true if item is new.

Definition at line 1016 of file concurrent_hash_map.h.

1016  {
1017  return generic_emplace(result, std::forward<Args>(args)...);
1018  }
bool generic_emplace(Accessor &&result, Args &&... args)

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_emplace().

Here is the call graph for this function:

◆ emplace() [2/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename... Args>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::emplace ( accessor result,
Args &&...  args 
)
inline

Insert item by copying if there is no such key present already and acquire a write lock on the item.

Returns true if item is new.

Definition at line 1023 of file concurrent_hash_map.h.

1023  {
1024  return generic_emplace(result, std::forward<Args>(args)...);
1025  }
bool generic_emplace(Accessor &&result, Args &&... args)

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_emplace().

Here is the call graph for this function:

◆ emplace() [3/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename... Args>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::emplace ( Args &&...  args)
inline

Insert item by copying if there is no such key present already.

Returns true if item is inserted.

Definition at line 1030 of file concurrent_hash_map.h.

1030  {
1031  return generic_emplace(accessor_not_used(), std::forward<Args>(args)...);
1032  }
bool generic_emplace(Accessor &&result, Args &&... args)

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_emplace().

Here is the call graph for this function:

◆ empty()

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::empty ( ) const
inline

True if size()==0.

Definition at line 922 of file concurrent_hash_map.h.

922 { return my_size == 0; }
atomic< size_type > my_size
Size of container in stored items.

References tbb::interface5::internal::hash_map_base::my_size.

◆ end() [1/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
iterator tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::end ( )
inline

◆ end() [2/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
const_iterator tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::end ( ) const
inline

Definition at line 914 of file concurrent_hash_map.h.

914 { return const_iterator( *this, 0, 0, 0 ); }
internal::hash_map_iterator< concurrent_hash_map, const value_type > const_iterator

◆ equal_range() [1/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
std::pair<iterator, iterator> tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::equal_range ( const Key &  key)
inline

Definition at line 915 of file concurrent_hash_map.h.

915 { return internal_equal_range( key, end() ); }
std::pair< I, I > internal_equal_range(const Key &key, I end) const
Returns an iterator for an item defined by the key, or for the next item after it (if upper==true)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::end(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_equal_range(), and key.

Referenced by tbb::operator==().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ equal_range() [2/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
std::pair<const_iterator, const_iterator> tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::equal_range ( const Key &  key) const
inline

Definition at line 916 of file concurrent_hash_map.h.

916 { return internal_equal_range( key, end() ); }
std::pair< I, I > internal_equal_range(const Key &key, I end) const
Returns an iterator for an item defined by the key, or for the next item after it (if upper==true)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::end(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_equal_range(), and key.

Here is the call graph for this function:

◆ erase() [1/3]

template<typename Key , typename T , typename HashCompare , typename A >
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::erase ( const Key &  key)

Erase item.

Return true if item was erased by particularly this call.

Definition at line 1267 of file concurrent_hash_map.h.

1267  {
1268  node_base *n;
1269  hashcode_t const h = my_hash_compare.hash( key );
1271 restart:
1272  {//lock scope
1273  // get bucket
1274  bucket_accessor b( this, h & m );
1275  search:
1276  node_base **p = &b()->node_list;
1277  n = *p;
1278  while( is_valid(n) && !my_hash_compare.equal(key, static_cast<node*>(n)->item.first ) ) {
1279  p = &n->next;
1280  n = *p;
1281  }
1282  if( !n ) { // not found, but mask could be changed
1283  if( check_mask_race( h, m ) )
1284  goto restart;
1285  return false;
1286  }
1287  else if( !b.is_writer() && !b.upgrade_to_writer() ) {
1288  if( check_mask_race( h, m ) ) // contended upgrade, check mask
1289  goto restart;
1290  goto search;
1291  }
1292  *p = n->next;
1293  my_size--;
1294  }
1295  {
1296  typename node::scoped_t item_locker( n->mutex, /*write=*/true );
1297  }
1298  // note: there should be no threads pretending to acquire this mutex again, do not try to upgrade const_accessor!
1299  delete_node( n ); // Only one thread can delete it due to write lock on the bucket
1300  return true;
1301 }
atomic< size_type > my_size
Size of container in stored items.
hash_map_node_base node_base
Node base type.
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
void const char const char int ITT_FORMAT __itt_group_sync p
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References h, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::bucket_accessor::is_writer(), tbb::internal::itt_load_word_with_acquire(), key, tbb::interface5::internal::hash_map_node_base::mutex, tbb::interface5::internal::hash_map_node_base::next, and p.

Here is the call graph for this function:

◆ erase() [2/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::erase ( const_accessor item_accessor)
inline

Erase item by const_accessor.

Return true if item was erased by particularly this call.

Definition at line 1056 of file concurrent_hash_map.h.

1056  {
1057  return exclude( item_accessor );
1058  }
bool exclude(const_accessor &item_accessor)
delete item by accessor

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::exclude().

Here is the call graph for this function:

◆ erase() [3/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::erase ( accessor item_accessor)
inline

Erase item by accessor.

Return true if item was erased by particularly this call.

Definition at line 1062 of file concurrent_hash_map.h.

1062  {
1063  return exclude( item_accessor );
1064  }
bool exclude(const_accessor &item_accessor)
delete item by accessor

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::exclude().

Here is the call graph for this function:

◆ exclude()

template<typename Key , typename T , typename HashCompare , typename A >
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::exclude ( const_accessor item_accessor)
protected

delete item by accessor

Definition at line 1237 of file concurrent_hash_map.h.

1237  {
1238  __TBB_ASSERT( item_accessor.my_node, NULL );
1239  node_base *const n = item_accessor.my_node;
1240  hashcode_t const h = item_accessor.my_hash;
1242  do {
1243  // get bucket
1244  bucket_accessor b( this, h & m, /*writer=*/true );
1245  node_base **p = &b()->node_list;
1246  while( *p && *p != n )
1247  p = &(*p)->next;
1248  if( !*p ) { // someone else was first
1249  if( check_mask_race( h, m ) )
1250  continue;
1251  item_accessor.release();
1252  return false;
1253  }
1254  __TBB_ASSERT( *p == n, NULL );
1255  *p = n->next; // remove from container
1256  my_size--;
1257  break;
1258  } while(true);
1259  if( !item_accessor.is_writer() ) // need to get exclusive lock
1260  item_accessor.upgrade_to_writer(); // return value means nothing here
1261  item_accessor.release();
1262  delete_node( n ); // Only one thread can delete it
1263  return true;
1264 }
atomic< size_type > my_size
Size of container in stored items.
hash_map_node_base node_base
Node base type.
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void const char const char int ITT_FORMAT __itt_group_sync p
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.

References __TBB_ASSERT, h, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::is_writer(), tbb::internal::itt_load_word_with_acquire(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::my_hash, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::my_node, tbb::interface5::internal::hash_map_node_base::next, p, and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release().

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::erase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find() [1/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::find ( const_accessor result,
const Key &  key 
) const
inline

Find item and acquire a read lock on the item.

Return true if item is found, false otherwise.

Definition at line 947 of file concurrent_hash_map.h.

947  {
948  result.release();
949  return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false, &do_not_allocate_node );
950  }
static node * do_not_allocate_node(node_allocator_type &, const Key &, const T *)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::do_not_allocate_node(), key, and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release().

Here is the call graph for this function:

◆ find() [2/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::find ( accessor result,
const Key &  key 
)
inline

Find item and acquire a write lock on the item.

Return true if item is found, false otherwise.

Definition at line 954 of file concurrent_hash_map.h.

954  {
955  result.release();
956  return lookup(/*insert*/false, key, NULL, &result, /*write=*/true, &do_not_allocate_node );
957  }
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
static node * do_not_allocate_node(node_allocator_type &, const Key &, const T *)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::do_not_allocate_node(), key, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release().

Here is the call graph for this function:

◆ generic_emplace()

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename Accessor , typename... Args>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_emplace ( Accessor &&  result,
Args &&...  args 
)
inlineprotected

Definition at line 1087 of file concurrent_hash_map.h.

1087  {
1088  result.release();
1089  node * node_ptr = allocate_node_emplace_construct(my_allocator, std::forward<Args>(args)...);
1090  return lookup(/*insert*/true, node_ptr->item.first, NULL, accessor_location(result), is_write_access_needed(result), &do_not_allocate_node, node_ptr );
1091  }
friend bool is_write_access_needed(accessor const &)
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
friend const_accessor * accessor_location(accessor_not_used const &)
static node * allocate_node_emplace_construct(node_allocator_type &allocator, Args &&... args)
static node * do_not_allocate_node(node_allocator_type &, const Key &, const T *)

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::accessor_location, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_emplace_construct(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::do_not_allocate_node(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::is_write_access_needed, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::node::item, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_allocator.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::emplace().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ generic_move_insert()

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename Accessor >
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_move_insert ( Accessor &&  result,
value_type &&  value 
)
inlineprotected

Definition at line 1080 of file concurrent_hash_map.h.

1080  {
1081  result.release();
1082  return lookup(/*insert*/true, value.first, &value.second, accessor_location(result), is_write_access_needed(result), &allocate_node_move_construct );
1083  }
friend bool is_write_access_needed(accessor const &)
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
friend const_accessor * accessor_location(accessor_not_used const &)
static node * allocate_node_move_construct(node_allocator_type &allocator, const Key &key, const T *t)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::accessor_location, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_move_construct(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::is_write_access_needed, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), and value.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_allocator()

template<typename Key, typename T, typename HashCompare, typename Allocator>
allocator_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::get_allocator ( ) const
inline

return allocator object

Definition at line 931 of file concurrent_hash_map.h.

931 { return this->my_allocator; }

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_allocator.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map().

Here is the caller graph for this function:

◆ insert() [1/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( const_accessor result,
const Key &  key 
)
inline

Insert item (if not already present) and acquire a read lock on the item.

Returns true if item is new.

Definition at line 961 of file concurrent_hash_map.h.

961  {
962  result.release();
963  return lookup(/*insert*/true, key, NULL, &result, /*write=*/false, &allocate_node_default_construct );
964  }
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key
static node * allocate_node_default_construct(node_allocator_type &allocator, const Key &key, const T *)

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_default_construct(), key, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release().

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert() [2/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( accessor result,
const Key &  key 
)
inline

Insert item (if not already present) and acquire a write lock on the item.

Returns true if item is new.

Definition at line 968 of file concurrent_hash_map.h.

968  {
969  result.release();
970  return lookup(/*insert*/true, key, NULL, &result, /*write=*/true, &allocate_node_default_construct );
971  }
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key
static node * allocate_node_default_construct(node_allocator_type &allocator, const Key &key, const T *)

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_default_construct(), key, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release().

Here is the call graph for this function:

◆ insert() [3/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( const_accessor result,
const value_type value 
)
inline

Insert item by copying if there is no such key present already and acquire a read lock on the item.

Returns true if item is new.

Definition at line 975 of file concurrent_hash_map.h.

975  {
976  result.release();
977  return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false, &allocate_node_copy_construct );
978  }
static node * allocate_node_copy_construct(node_allocator_type &allocator, const Key &key, const T *t)
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_copy_construct(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release(), and value.

Here is the call graph for this function:

◆ insert() [4/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( accessor result,
const value_type value 
)
inline

Insert item by copying if there is no such key present already and acquire a write lock on the item.

Returns true if item is new.

Definition at line 982 of file concurrent_hash_map.h.

982  {
983  result.release();
984  return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true, &allocate_node_copy_construct );
985  }
static node * allocate_node_copy_construct(node_allocator_type &allocator, const Key &key, const T *t)
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_copy_construct(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release(), and value.

Here is the call graph for this function:

◆ insert() [5/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( const value_type value)
inline

Insert item by copying if there is no such key present already.

Returns true if item is inserted.

Definition at line 989 of file concurrent_hash_map.h.

989  {
990  return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false, &allocate_node_copy_construct );
991  }
static node * allocate_node_copy_construct(node_allocator_type &allocator, const Key &key, const T *t)
bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node *(*allocate_node)(node_allocator_type &, const Key &, const T *), node *tmp_n=0)
Insert or find item and optionally acquire a lock on the item.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::allocate_node_copy_construct(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::lookup(), and value.

Here is the call graph for this function:

◆ insert() [6/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( const_accessor result,
value_type &&  value 
)
inline

Insert item by copying if there is no such key present already and acquire a read lock on the item.

Returns true if item is new.

Definition at line 996 of file concurrent_hash_map.h.

996  {
997  return generic_move_insert(result, std::move(value));
998  }
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
bool generic_move_insert(Accessor &&result, value_type &&value)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_move_insert(), tbb::move(), and value.

Here is the call graph for this function:

◆ insert() [7/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( accessor result,
value_type &&  value 
)
inline

Insert item by copying if there is no such key present already and acquire a write lock on the item.

Returns true if item is new.

Definition at line 1002 of file concurrent_hash_map.h.

1002  {
1003  return generic_move_insert(result, std::move(value));
1004  }
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
bool generic_move_insert(Accessor &&result, value_type &&value)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_move_insert(), tbb::move(), and value.

Here is the call graph for this function:

◆ insert() [8/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( value_type &&  value)
inline

Insert item by copying if there is no such key present already.

Returns true if item is inserted.

Definition at line 1008 of file concurrent_hash_map.h.

1008  {
1009  return generic_move_insert(accessor_not_used(), std::move(value));
1010  }
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
bool generic_move_insert(Accessor &&result, value_type &&value)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_move_insert(), tbb::move(), and value.

Here is the call graph for this function:

◆ insert() [9/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename I >
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( first,
last 
)
inline

Insert range [first, last)

Definition at line 1038 of file concurrent_hash_map.h.

1038  {
1039  for ( ; first != last; ++first )
1040  insert( *first );
1041  }
auto last(Container &c) -> decltype(begin(c))
auto first(Container &c) -> decltype(begin(c))
bool insert(const_accessor &result, const Key &key)
Insert item (if not already present) and acquire a read lock on the item.

References tbb::internal::first(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert(), and tbb::internal::last().

Here is the call graph for this function:

◆ insert() [10/10]

template<typename Key, typename T, typename HashCompare, typename Allocator>
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert ( std::initializer_list< value_type il)
inline

Insert initializer list.

Definition at line 1045 of file concurrent_hash_map.h.

1045  {
1046  insert( il.begin(), il.end() );
1047  }
bool insert(const_accessor &result, const Key &key)
Insert item (if not already present) and acquire a read lock on the item.

◆ internal_copy() [1/2]

template<typename Key , typename T , typename HashCompare , typename A >
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::internal_copy ( const concurrent_hash_map< Key, T, HashCompare, Allocator > &  source)
protected

Copy "source" to *this, where *this must start out empty.

Definition at line 1461 of file concurrent_hash_map.h.

1461  {
1462  hashcode_t mask = source.my_mask;
1463  if( my_mask == mask ) { // optimized version
1464  reserve( source.my_size ); // TODO: load_factor?
1465  bucket *dst = 0, *src = 0;
1466  bool rehash_required = false;
1467  for( hashcode_t k = 0; k <= mask; k++ ) {
1468  if( k & (k-2) ) ++dst,src++; // not the beginning of a segment
1469  else { dst = get_bucket( k ); src = source.get_bucket( k ); }
1470  __TBB_ASSERT( dst->node_list != internal::rehash_req, "Invalid bucket in destination table");
1471  node *n = static_cast<node*>( src->node_list );
1472  if( n == internal::rehash_req ) { // source is not rehashed, items are in previous buckets
1473  rehash_required = true;
1474  dst->node_list = internal::rehash_req;
1475  } else for(; n; n = static_cast<node*>( n->next ) ) {
1476  add_to_bucket( dst, new( my_allocator ) node(n->item.first, n->item.second) );
1477  ++my_size; // TODO: replace by non-atomic op
1478  }
1479  }
1480  if( rehash_required ) rehash();
1481  } else internal_copy( source.begin(), source.end(), source.my_size );
1482 }
void rehash(size_type n=0)
Rehashes and optionally resizes the whole table.
atomic< size_type > my_size
Size of container in stored items.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
static void add_to_bucket(bucket *b, node_base *n)
Add node.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.
void reserve(size_type buckets)
Prepare enough segments for number of buckets.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int mask

References __TBB_ASSERT, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::begin(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::end(), tbb::interface5::internal::hash_map_base::get_bucket(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::node::item, mask, tbb::interface5::internal::hash_map_base::my_mask, tbb::interface5::internal::hash_map_base::my_size, tbb::interface5::internal::hash_map_base::bucket::node_list, and tbb::interface5::internal::rehash_req.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::operator=().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ internal_copy() [2/2]

template<typename Key , typename T , typename HashCompare , typename A >
template<typename I >
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::internal_copy ( first,
last,
size_type  reserve_size 
)
protected

Definition at line 1486 of file concurrent_hash_map.h.

1486  {
1487  reserve( reserve_size ); // TODO: load_factor?
1488  hashcode_t m = my_mask;
1489  for(; first != last; ++first) {
1490  hashcode_t h = my_hash_compare.hash( (*first).first );
1491  bucket *b = get_bucket( h & m );
1492  __TBB_ASSERT( b->node_list != internal::rehash_req, "Invalid bucket in destination table");
1493  node *n = new( my_allocator ) node(*first);
1494  add_to_bucket( b, n );
1495  ++my_size; // TODO: replace by non-atomic op
1496  }
1497 }
atomic< size_type > my_size
Size of container in stored items.
auto last(Container &c) -> decltype(begin(c))
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
auto first(Container &c) -> decltype(begin(c))
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
static void add_to_bucket(bucket *b, node_base *n)
Add node.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
void reserve(size_type buckets)
Prepare enough segments for number of buckets.

References __TBB_ASSERT, tbb::internal::first(), h, tbb::internal::last(), tbb::interface5::internal::hash_map_base::bucket::node_list, and tbb::interface5::internal::rehash_req.

Here is the call graph for this function:

◆ internal_equal_range()

template<typename Key , typename T , typename HashCompare , typename A >
template<typename I >
std::pair< I, I > tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::internal_equal_range ( const Key &  key,
end 
) const
protected

Returns an iterator for an item defined by the key, or for the next item after it (if upper==true)

Definition at line 1219 of file concurrent_hash_map.h.

1219  {
1220  hashcode_t h = my_hash_compare.hash( key );
1221  hashcode_t m = my_mask;
1222  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1223  h &= m;
1224  bucket *b = get_bucket( h );
1225  while( b->node_list == internal::rehash_req ) {
1226  m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
1227  b = get_bucket( h &= m );
1228  }
1229  node *n = search_bucket( key, b );
1230  if( !n )
1231  return std::make_pair(end_, end_);
1232  iterator lower(*this, h, b, n), upper(lower);
1233  return std::make_pair(lower, ++upper);
1234 }
intptr_t __TBB_Log2(uintptr_t x)
Definition: tbb_machine.h:864
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
node * search_bucket(const key_type &key, bucket *b) const
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
internal::hash_map_iterator< concurrent_hash_map, value_type > iterator
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References __TBB_ASSERT, __TBB_Log2(), h, key, tbb::interface5::internal::hash_map_base::bucket::node_list, and tbb::interface5::internal::rehash_req.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::equal_range().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ internal_fast_find()

template<typename Key, typename T, typename HashCompare, typename Allocator>
const_pointer tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_fast_find ( const Key &  key) const
inlineprotected

Fast find when no concurrent erasure is used. For internal use inside TBB only!

Return pointer to item with given key, or NULL if no such item exists. Must not be called concurrently with erasure operations.

Definition at line 1111 of file concurrent_hash_map.h.

1111  {
1112  hashcode_t h = my_hash_compare.hash( key );
1114  node *n;
1115  restart:
1116  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1117  bucket *b = get_bucket( h & m );
1118  // TODO: actually, notification is unnecessary here, just hiding double-check
1119  if( itt_load_word_with_acquire(b->node_list) == internal::rehash_req )
1120  {
1122  if( lock.try_acquire( b->mutex, /*write=*/true ) ) {
1123  if( b->node_list == internal::rehash_req)
1124  const_cast<concurrent_hash_map*>(this)->rehash_bucket( b, h & m ); //recursive rehashing
1125  }
1126  else lock.acquire( b->mutex, /*write=*/false );
1127  __TBB_ASSERT(b->node_list!=internal::rehash_req,NULL);
1128  }
1129  n = search_bucket( key, b );
1130  if( n )
1131  return &n->item;
1132  else if( check_mask_race( h, m ) )
1133  goto restart;
1134  return 0;
1135  }
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
node * search_bucket(const key_type &key, bucket *b) const
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
mutex_t::scoped_lock scoped_t
Scoped lock type for mutex.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void * lock

References __TBB_ASSERT, tbb::interface5::internal::hash_map_base::check_mask_race(), tbb::interface5::internal::hash_map_base::get_bucket(), h, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::node::item, tbb::internal::itt_load_word_with_acquire(), key, lock, tbb::interface5::internal::hash_map_base::bucket::mutex, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_hash_compare, tbb::interface5::internal::hash_map_base::my_mask, tbb::interface5::internal::hash_map_base::bucket::node_list, tbb::interface5::internal::rehash_req, and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::search_bucket().

Here is the call graph for this function:

◆ lookup()

template<typename Key , typename T , typename HashCompare , typename A >
bool tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::lookup ( bool  op_insert,
const Key &  key,
const T *  t,
const_accessor result,
bool  write,
node *(*)(node_allocator_type &, const Key &, const T *)  allocate_node,
node tmp_n = 0 
)
protected

Insert or find item and optionally acquire a lock on the item.

Definition at line 1139 of file concurrent_hash_map.h.

1139  {
1140  __TBB_ASSERT( !result || !result->my_node, NULL );
1141  bool return_value;
1142  hashcode_t const h = my_hash_compare.hash( key );
1144  segment_index_t grow_segment = 0;
1145  node *n;
1146  restart:
1147  {//lock scope
1148  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1149  return_value = false;
1150  // get bucket
1151  bucket_accessor b( this, h & m );
1152 
1153  // find a node
1154  n = search_bucket( key, b() );
1155  if( op_insert ) {
1156  // [opt] insert a key
1157  if( !n ) {
1158  if( !tmp_n ) {
1159  tmp_n = allocate_node(my_allocator, key, t);
1160  }
1161  if( !b.is_writer() && !b.upgrade_to_writer() ) { // TODO: improved insertion
1162  // Rerun search_list, in case another thread inserted the item during the upgrade.
1163  n = search_bucket( key, b() );
1164  if( is_valid(n) ) { // unfortunately, it did
1165  b.downgrade_to_reader();
1166  goto exists;
1167  }
1168  }
1169  if( check_mask_race(h, m) )
1170  goto restart; // b.release() is done in ~b().
1171  // insert and set flag to grow the container
1172  grow_segment = insert_new_node( b(), n = tmp_n, m );
1173  tmp_n = 0;
1174  return_value = true;
1175  }
1176  } else { // find or count
1177  if( !n ) {
1178  if( check_mask_race( h, m ) )
1179  goto restart; // b.release() is done in ~b(). TODO: replace by continue
1180  return false;
1181  }
1182  return_value = true;
1183  }
1184  exists:
1185  if( !result ) goto check_growth;
1186  // TODO: the following seems as generic/regular operation
1187  // acquire the item
1188  if( !result->try_acquire( n->mutex, write ) ) {
1189  for( tbb::internal::atomic_backoff backoff(true);; ) {
1190  if( result->try_acquire( n->mutex, write ) ) break;
1191  if( !backoff.bounded_pause() ) {
1192  // the wait takes really long, restart the operation
1193  b.release();
1194  __TBB_ASSERT( !op_insert || !return_value, "Can't acquire new item in locked bucket?" );
1195  __TBB_Yield();
1197  goto restart;
1198  }
1199  }
1200  }
1201  }//lock scope
1202  result->my_node = n;
1203  result->my_hash = h;
1204 check_growth:
1205  // [opt] grow the container
1206  if( grow_segment ) {
1207 #if __TBB_STATISTICS
1208  my_info_resizes++; // concurrent ones
1209 #endif
1210  enable_segment( grow_segment );
1211  }
1212  if( tmp_n ) // if op_insert only
1213  delete_node( tmp_n );
1214  return return_value;
1215 }
segment_index_t insert_new_node(bucket *b, node_base *n, hashcode_t mask)
Insert a node and check for load factor.
Class that implements exponential backoff.
Definition: tbb_machine.h:349
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
node * search_bucket(const key_type &key, bucket *b) const
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
void enable_segment(segment_index_t k, bool is_initial=false)
Enable segment.
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
#define __TBB_Yield()
Definition: ibm_aix51.h:48
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References __TBB_ASSERT, __TBB_Yield, h, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::bucket_accessor::is_writer(), tbb::internal::itt_load_word_with_acquire(), key, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::my_hash, and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::my_node.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::find(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_emplace(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::generic_move_insert(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::insert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ max_size()

template<typename Key, typename T, typename HashCompare, typename Allocator>
size_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::max_size ( ) const
inline

Upper bound on size.

Definition at line 925 of file concurrent_hash_map.h.

925 {return (~size_type(0))/sizeof(node);}

◆ operator=() [1/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
concurrent_hash_map& tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::operator= ( const concurrent_hash_map< Key, T, HashCompare, Allocator > &  table)
inline

Assignment.

Definition at line 850 of file concurrent_hash_map.h.

850  {
851  if( this!=&table ) {
852  clear();
853  internal_copy(table);
854  }
855  return *this;
856  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::clear(), and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_copy().

Here is the call graph for this function:

◆ operator=() [2/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
concurrent_hash_map& tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::operator= ( concurrent_hash_map< Key, T, HashCompare, Allocator > &&  table)
inline

Move Assignment.

Definition at line 860 of file concurrent_hash_map.h.

860  {
861  if(this != &table){
863  if(pocma_t::value || this->my_allocator == table.my_allocator) {
864  concurrent_hash_map trash (std::move(*this));
865  //TODO: swapping allocators here may be a problem, replace with single direction moving iff pocma is set
866  this->swap(table);
867  } else {
868  //do per element move
869  concurrent_hash_map moved_copy(std::move(table), this->my_allocator);
870  this->swap(moved_copy);
871  }
872  }
873  return *this;
874  }
void swap(concurrent_hash_map &table)
swap two instances. Iterators are invalidated
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
concurrent_hash_map(const allocator_type &a=allocator_type())
Construct empty table.

◆ operator=() [3/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
concurrent_hash_map& tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::operator= ( std::initializer_list< value_type il)
inline

Assignment.

Definition at line 879 of file concurrent_hash_map.h.

879  {
880  clear();
881  internal_copy(il.begin(), il.end(), il.size());
882  return *this;
883  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.

◆ range() [1/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
range_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::range ( size_type  grainsize = 1)
inline

Definition at line 901 of file concurrent_hash_map.h.

901  {
902  return range_type( *this, grainsize );
903  }
internal::hash_map_range< iterator > range_type

◆ range() [2/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
const_range_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::range ( size_type  grainsize = 1) const
inline

Definition at line 904 of file concurrent_hash_map.h.

904  {
905  return const_range_type( *this, grainsize );
906  }
internal::hash_map_range< const_iterator > const_range_type

◆ rehash()

template<typename Key , typename T , typename HashCompare , typename A >
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::rehash ( size_type  n = 0)

Rehashes and optionally resizes the whole table.

Useful to optimize performance before or after concurrent operations. Also enables using of find() and count() concurrent methods in serial context.

Definition at line 1313 of file concurrent_hash_map.h.

1313  {
1314  reserve( sz ); // TODO: add reduction of number of buckets as well
1316  hashcode_t b = (mask+1)>>1; // size or first index of the last segment
1317  __TBB_ASSERT((b&(b-1))==0, NULL); // zero or power of 2
1318  bucket *bp = get_bucket( b ); // only the last segment should be scanned for rehashing
1319  for(; b <= mask; b++, bp++ ) {
1320  node_base *n = bp->node_list;
1321  __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" );
1322  __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" );
1323  if( n == internal::rehash_req ) { // rehash bucket, conditional because rehashing of a previous bucket may affect this one
1324  hashcode_t h = b; bucket *b_old = bp;
1325  do {
1326  __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" );
1327  hashcode_t m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
1328  b_old = get_bucket( h &= m );
1329  } while( b_old->node_list == internal::rehash_req );
1330  // now h - is index of the root rehashed bucket b_old
1331  mark_rehashed_levels( h ); // mark all non-rehashed children recursively across all segments
1332  for( node_base **p = &b_old->node_list, *q = *p; is_valid(q); q = *p ) {
1333  hashcode_t c = my_hash_compare.hash( static_cast<node*>(q)->item.first );
1334  if( (c & mask) != h ) { // should be rehashed
1335  *p = q->next; // exclude from b_old
1336  bucket *b_new = get_bucket( c & mask );
1337  __TBB_ASSERT( b_new->node_list != internal::rehash_req, "hash() function changed for key in table or internal error" );
1338  add_to_bucket( b_new, q );
1339  } else p = &q->next; // iterate to next item
1340  }
1341  }
1342  }
1343 #if TBB_USE_PERFORMANCE_WARNINGS
1344  int current_size = int(my_size), buckets = int(mask)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics
1345  static bool reported = false;
1346 #endif
1347 #if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
1348  for( b = 0; b <= mask; b++ ) {// only last segment should be scanned for rehashing
1349  if( b & (b-2) ) ++bp; // not the beginning of a segment
1350  else bp = get_bucket( b );
1351  node_base *n = bp->node_list;
1352  __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" );
1353  __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed, "Broken internal structure" );
1354 #if TBB_USE_PERFORMANCE_WARNINGS
1355  if( n == internal::empty_rehashed ) empty_buckets++;
1356  else if( n->next ) overpopulated_buckets++;
1357 #endif
1358 #if TBB_USE_ASSERT
1359  for( ; is_valid(n); n = n->next ) {
1360  hashcode_t h = my_hash_compare.hash( static_cast<node*>(n)->item.first ) & mask;
1361  __TBB_ASSERT( h == b, "hash() function changed for key in table or internal error" );
1362  }
1363 #endif
1364  }
1365 #endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
1366 #if TBB_USE_PERFORMANCE_WARNINGS
1367  if( buckets > current_size) empty_buckets -= buckets - current_size;
1368  else overpopulated_buckets -= current_size - buckets; // TODO: load_factor?
1369  if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) {
1371  "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d",
1373  typeid(*this).name(),
1374 #else
1375  "concurrent_hash_map",
1376 #endif
1377  current_size, empty_buckets, overpopulated_buckets );
1378  reported = true;
1379  }
1380 #endif
1381 }
intptr_t __TBB_Log2(uintptr_t x)
Definition: tbb_machine.h:864
atomic< size_type > my_size
Size of container in stored items.
hash_map_node_base node_base
Node base type.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void const char const char int ITT_FORMAT __itt_group_sync p
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
static hash_map_node_base *const empty_rehashed
Rehashed empty bucket flag.
void __TBB_EXPORTED_FUNC runtime_warning(const char *format,...)
Report a runtime warning.
static void add_to_bucket(bucket *b, node_base *n)
Add node.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
#define __TBB_USE_OPTIONAL_RTTI
Definition: tbb_config.h:126
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
void reserve(size_type buckets)
Prepare enough segments for number of buckets.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int mask

References __TBB_ASSERT, __TBB_Log2(), __TBB_USE_OPTIONAL_RTTI, tbb::interface5::internal::empty_rehashed, h, int, mask, tbb::interface5::internal::hash_map_base::bucket::mutex, tbb::interface5::internal::hash_map_node_base::next, tbb::interface5::internal::hash_map_base::bucket::node_list, p, tbb::interface5::internal::rehash_req, and tbb::internal::runtime_warning().

Here is the call graph for this function:

◆ rehash_bucket()

template<typename Key, typename T, typename HashCompare, typename Allocator>
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::rehash_bucket ( bucket b_new,
const hashcode_t  h 
)
inlineprotected

Definition at line 651 of file concurrent_hash_map.h.

651  {
652  __TBB_ASSERT( *(intptr_t*)(&b_new->mutex), "b_new must be locked (for write)");
653  __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" );
654  __TBB_store_with_release(b_new->node_list, internal::empty_rehashed); // mark rehashed
655  hashcode_t mask = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
656 #if __TBB_STATISTICS
657  my_info_rehashes++; // invocations of rehash_bucket
658 #endif
659 
660  bucket_accessor b_old( this, h & mask );
661 
662  mask = (mask<<1) | 1; // get full mask for new bucket
663  __TBB_ASSERT( (mask&(mask+1))==0 && (h & mask) == h, NULL );
664  restart:
665  for( node_base **p = &b_old()->node_list, *n = __TBB_load_with_acquire(*p); is_valid(n); n = *p ) {
666  hashcode_t c = my_hash_compare.hash( static_cast<node*>(n)->item.first );
667 #if TBB_USE_ASSERT
668  hashcode_t bmask = h & (mask>>1);
669  bmask = bmask==0? 1 : ( 1u<<(__TBB_Log2( bmask )+1 ) ) - 1; // minimal mask of parent bucket
670  __TBB_ASSERT( (c & bmask) == (h & bmask), "hash() function changed for key in table" );
671 #endif
672  if( (c & mask) == h ) {
673  if( !b_old.is_writer() )
674  if( !b_old.upgrade_to_writer() ) {
675  goto restart; // node ptr can be invalid due to concurrent erase
676  }
677  *p = n->next; // exclude from b_old
678  add_to_bucket( b_new, n );
679  } else p = &n->next; // iterate to next item
680  }
681  }
intptr_t __TBB_Log2(uintptr_t x)
Definition: tbb_machine.h:864
hash_map_node_base node_base
Node base type.
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:717
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void const char const char int ITT_FORMAT __itt_group_sync p
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
static hash_map_node_base *const empty_rehashed
Rehashed empty bucket flag.
T __TBB_load_with_acquire(const volatile T &location)
Definition: tbb_machine.h:713
static void add_to_bucket(bucket *b, node_base *n)
Add node.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int mask

References __TBB_ASSERT, tbb::internal::__TBB_load_with_acquire(), __TBB_Log2(), tbb::internal::__TBB_store_with_release(), tbb::interface5::internal::hash_map_base::add_to_bucket(), tbb::interface5::internal::empty_rehashed, h, tbb::interface5::internal::hash_map_base::is_valid(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::bucket_accessor::is_writer(), mask, tbb::interface5::internal::hash_map_base::bucket::mutex, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_hash_compare, tbb::interface5::internal::hash_map_base::bucket::node_list, and p.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::bucket_accessor::acquire().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_bucket()

template<typename Key, typename T, typename HashCompare, typename Allocator>
node* tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::search_bucket ( const key_type key,
bucket b 
) const
inlineprotected

Definition at line 619 of file concurrent_hash_map.h.

619  {
620  node *n = static_cast<node*>( b->node_list );
621  while( is_valid(n) && !my_hash_compare.equal(key, n->item.first) )
622  n = static_cast<node*>( n->next );
623  __TBB_ASSERT(n != internal::rehash_req, "Search can be executed only for rehashed bucket");
624  return n;
625  }
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key

References __TBB_ASSERT, tbb::interface5::internal::hash_map_base::is_valid(), tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::node::item, key, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_hash_compare, tbb::interface5::internal::hash_map_base::bucket::node_list, and tbb::interface5::internal::rehash_req.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::internal_fast_find().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ size()

template<typename Key, typename T, typename HashCompare, typename Allocator>
size_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::size ( ) const
inline

Number of items in table.

Definition at line 919 of file concurrent_hash_map.h.

919 { return my_size; }
atomic< size_type > my_size
Size of container in stored items.

References tbb::interface5::internal::hash_map_base::my_size.

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map(), and tbb::operator==().

Here is the caller graph for this function:

◆ swap()

template<typename Key, typename T, typename HashCompare, typename Allocator>
void tbb::interface5::concurrent_hash_map< Key, T, HashCompare, A >::swap ( concurrent_hash_map< Key, T, HashCompare, Allocator > &  table)

swap two instances. Iterators are invalidated

Definition at line 1304 of file concurrent_hash_map.h.

1304  {
1305  //TODO: respect C++11 allocator_traits<A>::propogate_on_constainer_swap
1306  using std::swap;
1307  swap(this->my_allocator, table.my_allocator);
1308  swap(this->my_hash_compare, table.my_hash_compare);
1309  internal_swap(table);
1310 }
void swap(concurrent_hash_map &table)
swap two instances. Iterators are invalidated
void internal_swap(hash_map_base &table)
Swap hash_map_bases.
void swap(concurrent_hash_map< Key, T, HashCompare, A > &a, concurrent_hash_map< Key, T, HashCompare, A > &b)

References tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_allocator, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_hash_compare, and tbb::swap().

Referenced by tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::concurrent_hash_map(), and tbb::swap().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ accessor_location [1/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
const_accessor* accessor_location ( accessor_not_used const &  )
friend

◆ accessor_location [2/2]

template<typename Key, typename T, typename HashCompare, typename Allocator>
const_accessor* accessor_location ( const_accessor a)
friend

Definition at line 1072 of file concurrent_hash_map.h.

1072 { return &a;}

◆ const_accessor

template<typename Key, typename T, typename HashCompare, typename Allocator>
friend class const_accessor
friend

Definition at line 555 of file concurrent_hash_map.h.

◆ internal::hash_map_iterator

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename Container , typename Value >
friend class internal::hash_map_iterator
friend

Definition at line 533 of file concurrent_hash_map.h.

◆ internal::hash_map_range

template<typename Key, typename T, typename HashCompare, typename Allocator>
template<typename I >
friend class internal::hash_map_range
friend

Definition at line 536 of file concurrent_hash_map.h.

◆ is_write_access_needed [1/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool is_write_access_needed ( accessor const &  )
friend

◆ is_write_access_needed [2/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool is_write_access_needed ( const_accessor const &  )
friend

Definition at line 1075 of file concurrent_hash_map.h.

1075 { return false;}

◆ is_write_access_needed [3/3]

template<typename Key, typename T, typename HashCompare, typename Allocator>
bool is_write_access_needed ( accessor_not_used const &  )
friend

Definition at line 1076 of file concurrent_hash_map.h.

1076 { return false;}

Member Data Documentation

◆ my_allocator

◆ my_hash_compare


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

Copyright © 2005-2018 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.