同時アクセスを含む結合コンテナー用のテンプレート・クラス。
template < typename Key, typename T,
typename HashCompare = tbb_hash_compare<Key>,
typename A=tbb_allocator<std::pair<Key, T> > >
class concurrent_hash_map;
#include "tbb/concurrent_hash_map.h"
concurrent_hash_map は、複数のスレッドが同時に値にアクセスすることを許可する方法で、キーを値にマップします。キーは順序付けされません。concurrent_hash_map には、キーごとに最大 1 つの要素があります。並列操作で説明されているように、キーにはマップ以外で処理を行っているほかの要素がある可能性があります。インターフェイスは、典型的な STL の結合コンテナーに似ていますが、同時アクセスのサポートで重大ないくつかの相違点があります。ISO C++ 標準のコンテナー要件を満たしています。Key 型および T 型は、CopyConstructible コンセプトをモデル化しなければなりません。HashCompare 型は、同等にするため、キーがどのようにハッシュされ比較されるかを指定します。次の表の HashCompare コンセプトをモデル化しなければなりません。
|
擬似署名 |
意味 |
|---|---|
|
HashCompare::HashCompare( const HashCompare& ) |
コピー・コンストラクター。 |
|
HashCompare::~HashCompare() |
デストラクター。 |
|
bool HashCompare::equal( const Key& j, const Key& k ) const |
キーが等しい場合は true。 |
|
size_t HashCompare::hash( const Key& k ) const |
キーのハッシュコード。 |
ほとんどのハッシュテーブルでは、2 つのキーが等しい場合、同じハッシュコードにハッシュしなければなりません。つまり、指定された HashCompare インスタンス h と任意の 2 つのキー j および k について、次のアサーションは "!h.equal(j,k) || h.hash(j)==h.hash(k)" を保持しなければなりません。このプロパティーの重要性は、concurrent_hash_map を別々のオブジェクトで維持する代わりに、単一オブジェクトにキーの等価性とハッシュを組み合わせる点にあります。キーのハッシュコードは、ハッシュテーブルが空でない間は変更してはなりません。
パフォーマンスは、ハッシュコードの下位ビットの擬似ランダム性が優れているかどうかに依存します。
キーがポインターの場合、ポインターをハッシュコードにキャストするだけでは、アライメントの規制がある型を指すポインターはハッシュコードの下位ビットが常にゼロになるため、良いパフォーマンスが得られません。この問題を回避するには、次に太字斜体で示すように、キャストされたポインターを型のサイズで割ります。
size_t MyHashCompare::hash( Key* key ) const {
return reinterpret_cast<size_t>(key) / sizeof(Key);
}
次のコード例で、太字 のメソッドは同時に呼び出すことができます。
namespace tbb {
template<typename Key, typename T, typename HashCompare,
typename Alloc = tbb_allocator<std::pair<Key, T> > >
class concurrent_hash_map {
public:
// 型
typedef Key key_type;
typedef T mapped_type;
typedef std::pair<const Key, T> value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef Alloc allocator_type;
// テーブル全体の操作
concurrent_hash_map( const allocator_type& a=allocator_type() );
concurrent_hash_map( size_type n, const allocator_type &a = allocator_type() );
concurrent_hash_map( const concurrent_hash_map&,
const allocator_type& a = allocator_type() );
template<typename InputIterator>
concurrent_hash_map( InputIterator first, InputIterator last,
const allocator_type& a = allocator_type() );
// C++11 仕様
concurrent_hash_map( concurrent_hash_map&& );
concurrent_hash_map( concurrent_hash_map&&, const allocator_type& );
concurrent_hash_map( std::initializer_list<value_type> il,
const allocator_type& a = allocator_type() );
~concurrent_hash_map();
concurrent_hash_map operator=( const concurrent_hash_map& );
// C++11 仕様
concurrent_hash_map& operator=( concurrent_hash_map&& );
concurrent_hash_map operator=( std::initializer_list<value_type> il );
void rehash( size_type n = 0 );
void clear();
allocator_type get_allocator() const;
// 同時アクセス
class const_accessor;
class accessor;
// テーブルの同時操作
bool find( const_accessor& result, const Key& key ) const;
bool find( accessor& result, const Key& key );
bool insert( const_accessor& result, const Key& key );
bool insert( accessor& result, const Key& key );
bool insert( const_accessor& result, const value_type& value );
bool insert( accessor& result, const value_type& value );
bool insert( const value_type& value );
template<typename I>
void insert( I first, I last );
// C++11 仕様
void insert( std::initializer_list<value_type> il );
bool erase( const Key& key );
bool erase( const_accessor& item_accessor );
bool erase( accessor& item_accessor );
// 並列反復
typedef implementation-defined range_type;
typedef implementation-defined const_range_type;
range_type range( size_t grainsize = 1 );
const_range_type range( size_t grainsize = 1 ) const;
// キャパシティー
size_type size() const;
bool empty() const;
size_type max_size() const;
size_type bucket_count() const;
// イテレーター
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
std::pair<iterator, iterator> equal_range( const Key& key );
std::pair<const_iterator, const_iterator> equal_range( const Key& key ) const;
};
template<typename Key, typename T, typename HashCompare, typename A1, typename A2>
bool operator==( const concurrent_hash_map<Key,T,HashCompare,A1>& a,
const concurrent_hash_map<Key,T,HashCompare,A2>& b);
template<typename Key, typename T, typename HashCompare, typename A1, typename A2>
bool operator!=( const concurrent_hash_map<Key,T,HashCompare,A1>& a,
const concurrent_hash_map<Key,T,HashCompare,A2>& b );
template<typename Key, typename T, typename HashCompare, typename A>
void swap( concurrent_hash_map<Key,T,HashCompare,A>& a,
concurrent_hash_map<Key,T,HashCompare,A>& b );
}
次の関数は、例外をスローしてはなりません。
次のことが当てはまります。