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 tbb::internal::allocator_rebind< Allocator, node >::type 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 54 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 554 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 551 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 547 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 553 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 549 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 545 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 550 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 541 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 542 of file concurrent_hash_map.h.

◆ node_allocator_type

template<typename Key, typename T, typename HashCompare, typename Allocator>
typedef tbb::internal::allocator_rebind<Allocator, node>::type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::node_allocator_type
protected

Definition at line 558 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 546 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 552 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 548 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 544 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 543 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 760 of file concurrent_hash_map.h.

761  : internal::hash_map_base(), my_allocator(a)
762  {}

◆ 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 764 of file concurrent_hash_map.h.

765  : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare)
766  {}

◆ 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 769 of file concurrent_hash_map.h.

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

◆ 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 775 of file concurrent_hash_map.h.

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

◆ 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 782 of file concurrent_hash_map.h.

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

783  : internal::hash_map_base(), my_allocator(a)
784  {
785  call_clear_on_leave scope_guard(this);
786  internal_copy(table);
787  scope_guard.dismiss();
788  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.
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 792 of file concurrent_hash_map.h.

793  : internal::hash_map_base(), my_allocator(std::move(table.get_allocator()))
794  {
795  swap(table);
796  }
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 799 of file concurrent_hash_map.h.

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 >::size(), and tbb::swap().

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

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

815  : internal::hash_map_base(), my_allocator(a)
816  {
817  call_clear_on_leave scope_guard(this);
818  internal_copy(first, last, std::distance(first, last));
819  scope_guard.dismiss();
820  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.
auto first(Container &c) -> decltype(begin(c))
auto last(Container &c) -> decltype(begin(c))
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 823 of file concurrent_hash_map.h.

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

824  : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare)
825  {
826  call_clear_on_leave scope_guard(this);
827  internal_copy(first, last, std::distance(first, last));
828  scope_guard.dismiss();
829  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.
auto first(Container &c) -> decltype(begin(c))
auto last(Container &c) -> decltype(begin(c))
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 833 of file concurrent_hash_map.h.

834  : internal::hash_map_base(), my_allocator(a)
835  {
836  call_clear_on_leave scope_guard(this);
837  internal_copy(il.begin(), il.end(), il.size());
838  scope_guard.dismiss();
839  }
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 841 of file concurrent_hash_map.h.

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

842  : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare)
843  {
844  call_clear_on_leave scope_guard(this);
845  internal_copy(il.begin(), il.end(), il.size());
846  scope_guard.dismiss();
847  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.
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 898 of file concurrent_hash_map.h.

898 { clear(); }

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 596 of file concurrent_hash_map.h.

596  {
597  return new( allocator ) node(key, *t);
598  }
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

◆ 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 612 of file concurrent_hash_map.h.

612  {
613  return new( allocator ) node(key);
614  }
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

◆ 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 606 of file concurrent_hash_map.h.

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

◆ 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 601 of file concurrent_hash_map.h.

References tbb::move().

601  {
602  return new( allocator ) node(key, std::move(*const_cast<T*>(t)));
603  }
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 move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
Here is the call 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

Definition at line 915 of file concurrent_hash_map.h.

References tbb::interface5::internal::hash_map_base::bucket::node_list.

internal::hash_map_iterator< concurrent_hash_map, const value_type > const_iterator
bucket my_embedded_segment[embedded_buckets]
Zero segment.

◆ 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 930 of file concurrent_hash_map.h.

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

◆ 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 1413 of file concurrent_hash_map.h.

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 >::call_clear_on_leave::~call_clear_on_leave().

1413  {
1414  hashcode_t m = my_mask;
1415  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1416 #if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1417 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1418  int current_size = int(my_size), buckets = int(m)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics
1419  static bool reported = false;
1420 #endif
1421  bucket *bp = 0;
1422  // check consistency
1423  for( segment_index_t b = 0; b <= m; b++ ) {
1424  if( b & (b-2) ) ++bp; // not the beginning of a segment
1425  else bp = get_bucket( b );
1426  node_base *n = bp->node_list;
1427  __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" );
1428  __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during clear() execution" );
1429 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1430  if( n == internal::empty_rehashed ) empty_buckets++;
1431  else if( n == internal::rehash_req ) buckets--;
1432  else if( n->next ) overpopulated_buckets++;
1433 #endif
1434 #if __TBB_EXTRA_DEBUG
1435  for(; is_valid(n); n = n->next ) {
1436  hashcode_t h = my_hash_compare.hash( static_cast<node*>(n)->item.first );
1437  h &= m;
1438  __TBB_ASSERT( h == b || get_bucket(h)->node_list == internal::rehash_req, "hash() function changed for key in table or internal error" );
1439  }
1440 #endif
1441  }
1442 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1443 #if __TBB_STATISTICS
1444  printf( "items=%d buckets: capacity=%d rehashed=%d empty=%d overpopulated=%d"
1445  " concurrent: resizes=%u rehashes=%u restarts=%u\n",
1446  current_size, int(m+1), buckets, empty_buckets, overpopulated_buckets,
1447  unsigned(my_info_resizes), unsigned(my_info_rehashes), unsigned(my_info_restarts) );
1448  my_info_resizes = 0; // concurrent ones
1449  my_info_restarts = 0; // race collisions
1450  my_info_rehashes = 0; // invocations of rehash_bucket
1451 #endif
1452  if( buckets > current_size) empty_buckets -= buckets - current_size;
1453  else overpopulated_buckets -= current_size - buckets; // TODO: load_factor?
1454  if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) {
1456  "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d",
1458  typeid(*this).name(),
1459 #else
1460  "concurrent_hash_map",
1461 #endif
1462  current_size, empty_buckets, overpopulated_buckets );
1463  reported = true;
1464  }
1465 #endif
1466 #endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
1467  my_size = 0;
1469  __TBB_ASSERT( s+1 == pointers_per_table || !my_table[s+1], "wrong mask or concurrent grow" );
1470  cache_aligned_allocator<bucket> alloc;
1471  do {
1472  __TBB_ASSERT( is_valid( my_table[s] ), "wrong mask or concurrent grow" );
1473  segment_ptr_t buckets_ptr = my_table[s];
1474  size_type sz = segment_size( s ? s : 1 );
1475  for( segment_index_t i = 0; i < sz; i++ )
1476  for( node_base *n = buckets_ptr[i].node_list; is_valid(n); n = buckets_ptr[i].node_list ) {
1477  buckets_ptr[i].node_list = n->next;
1478  delete_node( n );
1479  }
1480  if( s >= first_block) // the first segment or the next
1481  alloc.deallocate( buckets_ptr, sz );
1482  else if( s == embedded_block && embedded_block != first_block )
1483  alloc.deallocate( buckets_ptr, segment_size(first_block)-embedded_buckets );
1484  if( s >= embedded_block ) my_table[s] = 0;
1485  } while(s-- > 0);
1486  my_mask = embedded_buckets - 1;
1487 }
void __TBB_EXPORTED_FUNC runtime_warning(const char *format,...)
Report a runtime warning.
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
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
static size_type const first_block
Count of segments in the first block.
static size_type segment_size(segment_index_t k)
static size_type const pointers_per_table
Size of a pointer / table size.
static hash_map_node_base *const empty_rehashed
Rehashed empty bucket flag.
atomic< size_type > my_size
Size of container in stored items.
hash_map_node_base node_base
Node base type.
size_t segment_index_t
Segment index type.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
segments_table_t my_table
Segment pointers table. Also prevents false sharing between my_mask and my_size.
void const char const char int ITT_FORMAT __itt_group_sync s
#define __TBB_USE_OPTIONAL_RTTI
Definition: tbb_config.h:129
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
static size_type const embedded_buckets
Count of segments in the first block.
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 segment_index_t segment_index_of(size_type index)
static size_type const embedded_block
Count of segments in the first block.
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 943 of file concurrent_hash_map.h.

943  {
944  return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false, &do_not_allocate_node );
945  }
static node * do_not_allocate_node(node_allocator_type &, const Key &, const T *)
concurrent_hash_map(const allocator_type &a=allocator_type())
Construct empty table.
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
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.

◆ 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 591 of file concurrent_hash_map.h.

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

◆ 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 616 of file concurrent_hash_map.h.

References __TBB_ASSERT.

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

◆ 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 1018 of file concurrent_hash_map.h.

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

◆ 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 1025 of file concurrent_hash_map.h.

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

◆ 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 1032 of file concurrent_hash_map.h.

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

◆ 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 924 of file concurrent_hash_map.h.

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

◆ end() [1/2]

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

Definition at line 914 of file concurrent_hash_map.h.

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

914 { return iterator( *this, 0, 0, 0 ); }
internal::hash_map_iterator< concurrent_hash_map, value_type > iterator
Here is the caller graph for this function:

◆ 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 916 of file concurrent_hash_map.h.

916 { 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 917 of file concurrent_hash_map.h.

References end.

Referenced by tbb::operator==().

917 { 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
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 918 of file concurrent_hash_map.h.

References end.

918 { 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

◆ 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 1296 of file concurrent_hash_map.h.

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

1296  {
1297  node_base *n;
1298  hashcode_t const h = my_hash_compare.hash( key );
1300 restart:
1301  {//lock scope
1302  // get bucket
1303  bucket_accessor b( this, h & m );
1304  search:
1305  node_base **p = &b()->node_list;
1306  n = *p;
1307  while( is_valid(n) && !my_hash_compare.equal(key, static_cast<node*>(n)->item.first ) ) {
1308  p = &n->next;
1309  n = *p;
1310  }
1311  if( !n ) { // not found, but mask could be changed
1312  if( check_mask_race( h, m ) )
1313  goto restart;
1314  return false;
1315  }
1316  else if( !b.is_writer() && !b.upgrade_to_writer() ) {
1317  if( check_mask_race( h, m ) ) // contended upgrade, check mask
1318  goto restart;
1319  goto search;
1320  }
1321  *p = n->next;
1322  my_size--;
1323  }
1324  {
1325  typename node::scoped_t item_locker( n->mutex, /*write=*/true );
1326  }
1327  // note: there should be no threads pretending to acquire this mutex again, do not try to upgrade const_accessor!
1328  delete_node( n ); // Only one thread can delete it due to write lock on the bucket
1329  return true;
1330 }
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)
void const char const char int ITT_FORMAT __itt_group_sync p
atomic< size_type > my_size
Size of container in stored items.
hash_map_node_base node_base
Node base type.
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
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
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 1058 of file concurrent_hash_map.h.

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

◆ 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 1064 of file concurrent_hash_map.h.

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

◆ 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 1266 of file concurrent_hash_map.h.

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().

1266  {
1267  __TBB_ASSERT( item_accessor.my_node, NULL );
1268  node_base *const n = item_accessor.my_node;
1269  hashcode_t const h = item_accessor.my_hash;
1271  do {
1272  // get bucket
1273  bucket_accessor b( this, h & m, /*writer=*/true );
1274  node_base **p = &b()->node_list;
1275  while( *p && *p != n )
1276  p = &(*p)->next;
1277  if( !*p ) { // someone else was first
1278  if( check_mask_race( h, m ) )
1279  continue;
1280  item_accessor.release();
1281  return false;
1282  }
1283  __TBB_ASSERT( *p == n, NULL );
1284  *p = n->next; // remove from container
1285  my_size--;
1286  break;
1287  } while(true);
1288  if( !item_accessor.is_writer() ) // need to get exclusive lock
1289  item_accessor.upgrade_to_writer(); // return value means nothing here
1290  item_accessor.release();
1291  delete_node( n ); // Only one thread can delete it
1292  return true;
1293 }
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
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
void const char const char int ITT_FORMAT __itt_group_sync p
atomic< size_type > my_size
Size of container in stored items.
hash_map_node_base node_base
Node base type.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
Here is the call 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 949 of file concurrent_hash_map.h.

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

949  {
950  result.release();
951  return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false, &do_not_allocate_node );
952  }
static node * do_not_allocate_node(node_allocator_type &, const Key &, const T *)
concurrent_hash_map(const allocator_type &a=allocator_type())
Construct empty table.
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
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.
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 956 of file concurrent_hash_map.h.

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

956  {
957  result.release();
958  return lookup(/*insert*/false, key, NULL, &result, /*write=*/true, &do_not_allocate_node );
959  }
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
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.
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 1089 of file concurrent_hash_map.h.

References end, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::node::item, and tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::const_accessor::release().

1089  {
1090  result.release();
1091  node * node_ptr = allocate_node_emplace_construct(my_allocator, std::forward<Args>(args)...);
1092  return lookup(/*insert*/true, node_ptr->item.first, NULL, accessor_location(result), is_write_access_needed(result), &do_not_allocate_node, node_ptr );
1093  }
friend bool is_write_access_needed(accessor const &)
static node * do_not_allocate_node(node_allocator_type &, const Key &, const T *)
static node * allocate_node_emplace_construct(node_allocator_type &allocator, Args &&... args)
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 &)
Here is the call 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 1082 of file concurrent_hash_map.h.

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

1082  {
1083  result.release();
1084  return lookup(/*insert*/true, value.first, &value.second, accessor_location(result), is_write_access_needed(result), &allocate_node_move_construct );
1085  }
friend bool is_write_access_needed(accessor 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 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
static node * allocate_node_move_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.
friend const_accessor * accessor_location(accessor_not_used const &)
Here is the call 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 933 of file concurrent_hash_map.h.

References tbb::swap().

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

933 { return this->my_allocator; }
Here is the call graph for this function:
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 963 of file concurrent_hash_map.h.

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

963  {
964  result.release();
965  return lookup(/*insert*/true, key, NULL, &result, /*write=*/false, &allocate_node_default_construct );
966  }
static node * allocate_node_default_construct(node_allocator_type &allocator, const Key &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
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.
Here is the call 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 970 of file concurrent_hash_map.h.

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

970  {
971  result.release();
972  return lookup(/*insert*/true, key, NULL, &result, /*write=*/true, &allocate_node_default_construct );
973  }
static node * allocate_node_default_construct(node_allocator_type &allocator, const Key &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
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.
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 977 of file concurrent_hash_map.h.

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

977  {
978  result.release();
979  return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false, &allocate_node_copy_construct );
980  }
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
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.
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 984 of file concurrent_hash_map.h.

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

984  {
985  result.release();
986  return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true, &allocate_node_copy_construct );
987  }
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
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.
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 991 of file concurrent_hash_map.h.

991  {
992  return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false, &allocate_node_copy_construct );
993  }
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
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.

◆ 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 998 of file concurrent_hash_map.h.

References tbb::move(), and value.

998  {
999  return generic_move_insert(result, std::move(value));
1000  }
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
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
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 1004 of file concurrent_hash_map.h.

References tbb::move(), and value.

1004  {
1005  return generic_move_insert(result, std::move(value));
1006  }
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
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
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 1010 of file concurrent_hash_map.h.

References tbb::move(), and value.

1010  {
1011  return generic_move_insert(accessor_not_used(), std::move(value));
1012  }
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
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
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 1040 of file concurrent_hash_map.h.

References tbb::internal::first(), key, and tbb::internal::last().

1040  {
1041  for ( ; first != last; ++first )
1042  insert( *first );
1043  }
auto first(Container &c) -> decltype(begin(c))
auto last(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.
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 1047 of file concurrent_hash_map.h.

1047  {
1048  insert( il.begin(), il.end() );
1049  }
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 1490 of file concurrent_hash_map.h.

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.

1490  {
1491  hashcode_t mask = source.my_mask;
1492  if( my_mask == mask ) { // optimized version
1493  reserve( source.my_size ); // TODO: load_factor?
1494  bucket *dst = 0, *src = 0;
1495  bool rehash_required = false;
1496  for( hashcode_t k = 0; k <= mask; k++ ) {
1497  if( k & (k-2) ) ++dst,src++; // not the beginning of a segment
1498  else { dst = get_bucket( k ); src = source.get_bucket( k ); }
1499  __TBB_ASSERT( dst->node_list != internal::rehash_req, "Invalid bucket in destination table");
1500  node *n = static_cast<node*>( src->node_list );
1501  if( n == internal::rehash_req ) { // source is not rehashed, items are in previous buckets
1502  rehash_required = true;
1503  dst->node_list = internal::rehash_req;
1504  } else for(; n; n = static_cast<node*>( n->next ) ) {
1505  add_to_bucket( dst, new( my_allocator ) node(n->item.first, n->item.second) );
1506  ++my_size; // TODO: replace by non-atomic op
1507  }
1508  }
1509  if( rehash_required ) rehash();
1510  } else internal_copy( source.begin(), source.end(), source.my_size );
1511 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.
static void add_to_bucket(bucket *b, node_base *n)
Add node.
void rehash(size_type n=0)
Rehashes and optionally resizes the whole table.
atomic< size_type > my_size
Size of container in stored items.
void reserve(size_type buckets)
Prepare enough segments for number of buckets.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
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 mask
Here is the call 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 1515 of file concurrent_hash_map.h.

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.

1515  {
1516  reserve( reserve_size ); // TODO: load_factor?
1517  hashcode_t m = my_mask;
1518  for(; first != last; ++first) {
1519  hashcode_t h = my_hash_compare.hash( (*first).first );
1520  bucket *b = get_bucket( h & m );
1521  __TBB_ASSERT( b->node_list != internal::rehash_req, "Invalid bucket in destination table");
1522  node *n = new( my_allocator ) node(*first);
1523  add_to_bucket( b, n );
1524  ++my_size; // TODO: replace by non-atomic op
1525  }
1526 }
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
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
auto first(Container &c) -> decltype(begin(c))
static void add_to_bucket(bucket *b, node_base *n)
Add node.
auto last(Container &c) -> decltype(begin(c))
atomic< size_type > my_size
Size of container in stored items.
void reserve(size_type buckets)
Prepare enough segments for number of buckets.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
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 1248 of file concurrent_hash_map.h.

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

1248  {
1249  hashcode_t h = my_hash_compare.hash( key );
1250  hashcode_t m = my_mask;
1251  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1252  h &= m;
1253  bucket *b = get_bucket( h );
1254  while( b->node_list == internal::rehash_req ) {
1255  m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
1256  b = get_bucket( h &= m );
1257  }
1258  node *n = search_bucket( key, b );
1259  if( !n )
1260  return std::make_pair(end_, end_);
1261  iterator lower(*this, h, b, n), upper(lower);
1262  return std::make_pair(lower, ++upper);
1263 }
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
node * search_bucket(const key_type &key, bucket *b) const
internal::hash_map_iterator< concurrent_hash_map, value_type > iterator
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
intptr_t __TBB_Log2(uintptr_t x)
Definition: tbb_machine.h:867
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
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
Here is the call 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 1113 of file concurrent_hash_map.h.

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

1113  {
1114  hashcode_t h = my_hash_compare.hash( key );
1116  node *n;
1117  restart:
1118  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1119  bucket *b = get_bucket( h & m );
1120  // TODO: actually, notification is unnecessary here, just hiding double-check
1121  if( itt_load_word_with_acquire(b->node_list) == internal::rehash_req )
1122  {
1124  if( lock.try_acquire( b->mutex, /*write=*/true ) ) {
1125  if( b->node_list == internal::rehash_req)
1126  const_cast<concurrent_hash_map*>(this)->rehash_bucket( b, h & m ); //recursive rehashing
1127  }
1128  else lock.acquire( b->mutex, /*write=*/false );
1129  __TBB_ASSERT(b->node_list!=internal::rehash_req,NULL);
1130  }
1131  n = search_bucket( key, b );
1132  if( n )
1133  return &n->item;
1134  else if( check_mask_race( h, m ) )
1135  goto restart;
1136  return 0;
1137  }
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
node * search_bucket(const key_type &key, bucket *b) const
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
concurrent_hash_map(const allocator_type &a=allocator_type())
Construct empty table.
void rehash_bucket(bucket *b_new, const hashcode_t h)
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
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
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
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
bucket * get_bucket(hashcode_t h) const
Get bucket by (masked) hashcode.
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
mutex_t::scoped_lock scoped_t
Scoped lock type for mutex.
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 1168 of file concurrent_hash_map.h.

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(), 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.

1168  {
1169  __TBB_ASSERT( !result || !result->my_node, NULL );
1170  bool return_value;
1171  hashcode_t const h = my_hash_compare.hash( key );
1173  segment_index_t grow_segment = 0;
1174  node *n;
1175  restart:
1176  {//lock scope
1177  __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
1178  return_value = false;
1179  // get bucket
1180  bucket_accessor b( this, h & m );
1181 
1182  // find a node
1183  n = search_bucket( key, b() );
1184  if( op_insert ) {
1185  // [opt] insert a key
1186  if( !n ) {
1187  if( !tmp_n ) {
1188  tmp_n = allocate_node(my_allocator, key, t);
1189  }
1190  if( !b.is_writer() && !b.upgrade_to_writer() ) { // TODO: improved insertion
1191  // Rerun search_list, in case another thread inserted the item during the upgrade.
1192  n = search_bucket( key, b() );
1193  if( is_valid(n) ) { // unfortunately, it did
1194  b.downgrade_to_reader();
1195  goto exists;
1196  }
1197  }
1198  if( check_mask_race(h, m) )
1199  goto restart; // b.release() is done in ~b().
1200  // insert and set flag to grow the container
1201  grow_segment = insert_new_node( b(), n = tmp_n, m );
1202  tmp_n = 0;
1203  return_value = true;
1204  }
1205  } else { // find or count
1206  if( !n ) {
1207  if( check_mask_race( h, m ) )
1208  goto restart; // b.release() is done in ~b(). TODO: replace by continue
1209  return false;
1210  }
1211  return_value = true;
1212  }
1213  exists:
1214  if( !result ) goto check_growth;
1215  // TODO: the following seems as generic/regular operation
1216  // acquire the item
1217  if( !result->try_acquire( n->mutex, write ) ) {
1218  for( tbb::internal::atomic_backoff backoff(true);; ) {
1219  if( result->try_acquire( n->mutex, write ) ) break;
1220  if( !backoff.bounded_pause() ) {
1221  // the wait takes really long, restart the operation
1222  b.release();
1223  __TBB_ASSERT( !op_insert || !return_value, "Can't acquire new item in locked bucket?" );
1224  __TBB_Yield();
1226  goto restart;
1227  }
1228  }
1229  }
1230  }//lock scope
1231  result->my_node = n;
1232  result->my_hash = h;
1233 check_growth:
1234  // [opt] grow the container
1235  if( grow_segment ) {
1236 #if __TBB_STATISTICS
1237  my_info_resizes++; // concurrent ones
1238 #endif
1239  enable_segment( grow_segment );
1240  }
1241  if( tmp_n ) // if op_insert only
1242  delete_node( tmp_n );
1243  return return_value;
1244 }
Class that implements exponential backoff.
Definition: tbb_machine.h:352
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
node * search_bucket(const key_type &key, bucket *b) const
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
#define __TBB_Yield()
Definition: ibm_aix51.h:48
size_t segment_index_t
Segment index type.
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
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
segment_index_t insert_new_node(bucket *b, node_base *n, hashcode_t mask)
Insert a node and check for load factor.
bool check_mask_race(const hashcode_t h, hashcode_t &m) const
Check for mask race.
void enable_segment(segment_index_t k, bool is_initial=false)
Enable segment.
Here is the call 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 927 of file concurrent_hash_map.h.

927 {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 852 of file concurrent_hash_map.h.

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

852  {
853  if( this!=&table ) {
854  clear();
855  internal_copy(table);
856  }
857  return *this;
858  }
void internal_copy(const concurrent_hash_map &source)
Copy "source" to *this, where *this must start out empty.
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 862 of file concurrent_hash_map.h.

862  {
863  if(this != &table) {
865  if(pocma_t::value || this->my_allocator == table.my_allocator) {
866  concurrent_hash_map trash (std::move(*this));
867  //TODO: swapping allocators here may be a problem, replace with single direction moving iff pocma is set
868  this->swap(table);
869  } else {
870  //do per element move
871  concurrent_hash_map moved_copy(std::move(table), this->my_allocator);
872  this->swap(moved_copy);
873  }
874  }
875  return *this;
876  }
void swap(concurrent_hash_map &table)
swap two instances. Iterators are invalidated
concurrent_hash_map(const allocator_type &a=allocator_type())
Construct empty table.
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
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309

◆ 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 881 of file concurrent_hash_map.h.

881  {
882  clear();
883  internal_copy(il.begin(), il.end(), il.size());
884  return *this;
885  }
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 903 of file concurrent_hash_map.h.

903  {
904  return range_type( *this, grainsize );
905  }
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 906 of file concurrent_hash_map.h.

906  {
907  return const_range_type( *this, grainsize );
908  }
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 1342 of file concurrent_hash_map.h.

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().

1342  {
1343  reserve( sz ); // TODO: add reduction of number of buckets as well
1345  hashcode_t b = (mask+1)>>1; // size or first index of the last segment
1346  __TBB_ASSERT((b&(b-1))==0, NULL); // zero or power of 2
1347  bucket *bp = get_bucket( b ); // only the last segment should be scanned for rehashing
1348  for(; b <= mask; b++, bp++ ) {
1349  node_base *n = bp->node_list;
1350  __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" );
1351  __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" );
1352  if( n == internal::rehash_req ) { // rehash bucket, conditional because rehashing of a previous bucket may affect this one
1353  hashcode_t h = b; bucket *b_old = bp;
1354  do {
1355  __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" );
1356  hashcode_t m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
1357  b_old = get_bucket( h &= m );
1358  } while( b_old->node_list == internal::rehash_req );
1359  // now h - is index of the root rehashed bucket b_old
1360  mark_rehashed_levels( h ); // mark all non-rehashed children recursively across all segments
1361  for( node_base **p = &b_old->node_list, *q = *p; is_valid(q); q = *p ) {
1362  hashcode_t c = my_hash_compare.hash( static_cast<node*>(q)->item.first );
1363  if( (c & mask) != h ) { // should be rehashed
1364  *p = q->next; // exclude from b_old
1365  bucket *b_new = get_bucket( c & mask );
1366  __TBB_ASSERT( b_new->node_list != internal::rehash_req, "hash() function changed for key in table or internal error" );
1367  add_to_bucket( b_new, q );
1368  } else p = &q->next; // iterate to next item
1369  }
1370  }
1371  }
1372 #if TBB_USE_PERFORMANCE_WARNINGS
1373  int current_size = int(my_size), buckets = int(mask)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics
1374  static bool reported = false;
1375 #endif
1376 #if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
1377  for( b = 0; b <= mask; b++ ) {// only last segment should be scanned for rehashing
1378  if( b & (b-2) ) ++bp; // not the beginning of a segment
1379  else bp = get_bucket( b );
1380  node_base *n = bp->node_list;
1381  __TBB_ASSERT( *reinterpret_cast<intptr_t*>(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" );
1382  __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed, "Broken internal structure" );
1383 #if TBB_USE_PERFORMANCE_WARNINGS
1384  if( n == internal::empty_rehashed ) empty_buckets++;
1385  else if( n->next ) overpopulated_buckets++;
1386 #endif
1387 #if TBB_USE_ASSERT
1388  for( ; is_valid(n); n = n->next ) {
1389  hashcode_t h = my_hash_compare.hash( static_cast<node*>(n)->item.first ) & mask;
1390  __TBB_ASSERT( h == b, "hash() function changed for key in table or internal error" );
1391  }
1392 #endif
1393  }
1394 #endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS
1395 #if TBB_USE_PERFORMANCE_WARNINGS
1396  if( buckets > current_size) empty_buckets -= buckets - current_size;
1397  else overpopulated_buckets -= current_size - buckets; // TODO: load_factor?
1398  if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) {
1400  "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d",
1402  typeid(*this).name(),
1403 #else
1404  "concurrent_hash_map",
1405 #endif
1406  current_size, empty_buckets, overpopulated_buckets );
1407  reported = true;
1408  }
1409 #endif
1410 }
void __TBB_EXPORTED_FUNC runtime_warning(const char *format,...)
Report a runtime warning.
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
#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.
void const char const char int ITT_FORMAT __itt_group_sync p
intptr_t __TBB_Log2(uintptr_t x)
Definition: tbb_machine.h:867
static hash_map_node_base *const empty_rehashed
Rehashed empty bucket flag.
atomic< size_type > my_size
Size of container in stored items.
hash_map_node_base node_base
Node base type.
void reserve(size_type buckets)
Prepare enough segments for number of buckets.
atomic< hashcode_t > my_mask
Hash mask = sum of allocated segment sizes - 1.
static hash_map_node_base *const rehash_req
Incompleteness flag value.
#define __TBB_USE_OPTIONAL_RTTI
Definition: tbb_config.h:129
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 __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 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
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 653 of file concurrent_hash_map.h.

References __TBB_ASSERT, tbb::internal::__TBB_load_with_acquire(), __TBB_Log2(), tbb::internal::__TBB_store_with_release(), tbb::interface5::internal::empty_rehashed, tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::bucket_accessor::is_writer(), mask, tbb::interface5::internal::hash_map_base::bucket::mutex, 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().

653  {
654  __TBB_ASSERT( *(intptr_t*)(&b_new->mutex), "b_new must be locked (for write)");
655  __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" );
656  __TBB_store_with_release(b_new->node_list, internal::empty_rehashed); // mark rehashed
657  hashcode_t mask = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit
658 #if __TBB_STATISTICS
659  my_info_rehashes++; // invocations of rehash_bucket
660 #endif
661 
662  bucket_accessor b_old( this, h & mask );
663 
664  mask = (mask<<1) | 1; // get full mask for new bucket
665  __TBB_ASSERT( (mask&(mask+1))==0 && (h & mask) == h, NULL );
666  restart:
667  for( node_base **p = &b_old()->node_list, *n = __TBB_load_with_acquire(*p); is_valid(n); n = *p ) {
668  hashcode_t c = my_hash_compare.hash( static_cast<node*>(n)->item.first );
669 #if TBB_USE_ASSERT
670  hashcode_t bmask = h & (mask>>1);
671  bmask = bmask==0? 1 : ( 1u<<(__TBB_Log2( bmask )+1 ) ) - 1; // minimal mask of parent bucket
672  __TBB_ASSERT( (c & bmask) == (h & bmask), "hash() function changed for key in table" );
673 #endif
674  if( (c & mask) == h ) {
675  if( !b_old.is_writer() )
676  if( !b_old.upgrade_to_writer() ) {
677  goto restart; // node ptr can be invalid due to concurrent erase
678  }
679  *p = n->next; // exclude from b_old
680  add_to_bucket( b_new, n );
681  } else p = &n->next; // iterate to next item
682  }
683  }
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 __TBB_load_with_acquire(const volatile T &location)
Definition: tbb_machine.h:716
#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.
void const char const char int ITT_FORMAT __itt_group_sync p
intptr_t __TBB_Log2(uintptr_t x)
Definition: tbb_machine.h:867
static hash_map_node_base *const empty_rehashed
Rehashed empty bucket flag.
hash_map_node_base node_base
Node base type.
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
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:720
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 621 of file concurrent_hash_map.h.

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

621  {
622  node *n = static_cast<node*>( b->node_list );
623  while( is_valid(n) && !my_hash_compare.equal(key, n->item.first) )
624  n = static_cast<node*>( n->next );
625  __TBB_ASSERT(n != internal::rehash_req, "Search can be executed only for rehashed bucket");
626  return n;
627  }
#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
static hash_map_node_base *const rehash_req
Incompleteness flag value.

◆ 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 921 of file concurrent_hash_map.h.

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

921 { return my_size; }
atomic< size_type > my_size
Size of container in stored items.
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 1333 of file concurrent_hash_map.h.

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::swap().

1333  {
1334  //TODO: respect C++11 allocator_traits<A>::propogate_on_constainer_swap
1335  using std::swap;
1336  swap(this->my_allocator, table.my_allocator);
1337  swap(this->my_hash_compare, table.my_hash_compare);
1338  internal_swap(table);
1339 }
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)
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

Definition at line 1073 of file concurrent_hash_map.h.

1073 { return NULL;}

◆ accessor_location [2/2]

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

Definition at line 1074 of file concurrent_hash_map.h.

1074 { return &a;}

◆ const_accessor

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

Definition at line 557 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 535 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 538 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

Definition at line 1076 of file concurrent_hash_map.h.

1076 { return true;}

◆ 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 1077 of file concurrent_hash_map.h.

1077 { 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 1078 of file concurrent_hash_map.h.

1078 { return false;}

Member Data Documentation

◆ my_allocator

template<typename Key, typename T, typename HashCompare, typename Allocator>
node_allocator_type tbb::interface5::concurrent_hash_map< Key, T, HashCompare, Allocator >::my_allocator
protected

◆ my_hash_compare

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

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

Copyright © 2005-2019 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.