並列操作

count 操作、find 操作、insert 操作、erase 操作のみ、同じ concurrent_hash_map で同時に呼び出すことができます。これらの操作は指定されたキーと一致するキー/値ペアについてテーブルを検索します。find メソッドと insert メソッドはそれぞれ、2 つの可変要素があります。1 つは、const_accessor 引数を使用して目的のキー/値ペアの読み取りアクセスを提供します。もう 1 つは、accessor 引数を使用して書き込みアクセスを提供します。さらに、insert には accessor 引数のないバージョンもあります。

注意

並列操作 (countfindinsert、および erase) は、影響を受けるインスタンスを指している反復を、const 修飾子を含むものであっても無効にします。これらの操作をほかの操作と同時に使用することは安全ではありません。この規則の例外として、rehash メソッドへの最後の呼び出しの後に変更と消去が発生しなかった場合、countfind はイテレーターを無効にしません。

ヒント

シリアルコードでは、equal_range のほうが速く、イテレーターを無効にしないため、find メソッドの代わりに equal_range メソッドを使用してルックアップを行います。

ヒント

キーの検索で非 const 可変要素が成功すると、その結果生じる書き込みアクセスは、アクセサー・オブジェクトが破棄されるまで、ほかのスレッドがキーをアクセスしないようにブロックします。可能であれば、並列性を向上するために const 可変要素を使用してください。

操作に成功した場合、このセクションの各マップ操作は true を返し、その他の場合は false を返します。

注意

指定されたキーはマップに多くても 1 つしかありませんが、同じキーには異なるキー/値ペアが複数ある可能性があります。これは、insert メソッドと erase メソッドのセマンティクスによります。insert メソッドは、マップに追加されない一時的なキー/値ペアを作成し破棄できます。erase メソッドは、キー/値ペアを破棄する前にマップから削除し、古いキーが破棄される前に別のスレッドが同じようなキーを作成できるようにします。

ヒント

指定されたキーに対して、同時に存在するリソースのインスタンスが 1 つだけであることを保証するため、次の手法を使用します。

  • リソースの構築: リソースを構築する前に、マップのキーへの accessor を取得します。

  • リソースの破棄: キーへの accessor を取得し、リソースを破棄してから、accessor を使用してキーを消去します。

次のコードは、この方法を示したものです。

extern tbb::concurrent_hash_map<Key,Resource,HashCompare> Map;

void ConstructResource( Key key ) {
    accessor acc;
    if( Map.insert(acc,key) ) {
        // 現在のスレッドはキーを挿入して排他アクセス
        ... ここでリソースを構築 ...
    }
    // acc リリースロックの暗黙的な破棄
}

void DestroyResource( Key key ) {
    accessor acc;
    if( Map.find(acc,key) ) {
        // 現在のスレッドはキーを検索して排他アクセス
        ... ここでリソースを破棄 ...
        // accessor を使用してキーを消去
        Map.erase(acc);
    }
}
次の表は、このテンプレート・クラスのメンバーの詳細な情報を提供します。
メンバー 説明
size_type count( const Key& key ) const

注意

このメソッドは、以前に取得されたイテレーターを無効にすることがあります。シリアルコードでは、その問題がない equal_range を使用できます。

戻り値: マップにキーがある場合は 1、その他の場合は 0。

bool find( const_accessor& result, const Key& key ) const

指定されたキーを含むペアがあるかテーブルを検索します。キーが見つかった場合、一致するペアの読み取り専用アクセスを提供するように result を設定します。

注意

このメソッドは、以前に取得されたイテレーターを無効にすることがあります。シリアルコードでは、その問題がない equal_range を使用できます。

戻り値: キーが見つかった場合は ture。キーが見つからなかった場合は false。

bool find( accessor& result, const Key& key )

指定されたキーを含むペアがあるかテーブルを検索します。キーが見つかった場合、一致するペアへの書き込みアクセスを提供するように result を設定します。

注意

このメソッドは、以前に取得されたイテレーターを無効にすることがあります。シリアルコードでは、その問題がない equal_range を使用できます。

戻り値: キーが見つかった場合は ture。キーが見つからなかった場合は false。

bool insert( const_accessor& result, const Key& key )

指定されたキーを含むペアがあるかテーブルを検索します。ペアがない場合、テーブルに新しい pair(key,T()) を挿入します。一致するペアへの読み取り専用アクセスを提供するように result を設定します。

戻り値: 新しいペアが挿入された場合は true。キーがすでにマップにある場合は false。

bool insert( accessor& result, const Key& key )

指定されたキーを含むペアがあるかテーブルを検索します。ペアがない場合、テーブルに新しい pair(key,T()) を挿入します。一致するペアへの書き込みアクセスを提供するように result を設定します。

戻り値: 新しいペアが挿入された場合は true。キーがすでにマップにある場合は false。

bool insert( const_accessor& result, const value_type& value )

指定されたキーを含むペアがあるかテーブルを検索します。ペアがない場合、テーブルに value から作成された新しいペアのコピーを挿入します。一致するペアへの読み取り専用アクセスを提供するように result を設定します。

戻り値: 新しいペアが挿入された場合は true。キーがすでにマップにある場合は false。

bool insert( accessor& result, const value_type& value )

指定されたキーを含むペアがあるかテーブルを検索します。ペアがない場合、テーブルに value から作成された新しいペアのコピーを挿入します。一致するペアへの書き込みアクセスを提供するように result を設定します。

戻り値: 新しいペアが挿入された場合は true。キーがすでにマップにある場合は false。

bool insert( const value_type& value )

指定されたキーを含むペアがあるかテーブルを検索します。ペアがない場合、テーブルに value から作成された新しいペアのコピーを挿入します。

戻り値: 新しいペアが挿入された場合は true。キーがすでにマップにある場合は false。

ヒント

挿入後にデータにアクセスする必要がない場合は、accessor なしの insert を使用します。処理が速くなり、使用するロックの数も少なくて済みます。

template<typename InputIterator> void insert( InputIterator first, InputIterator last )

半開区間 [first,last) の各ペア p について、insert(p) を実行します。挿入順序または並列に実行するかどうかは指定できません。

注意

現在の実装は、挿入を順番に処理します。将来の実装では、挿入を並列に処理できるようになる可能性があります。[first,last) に重複キーがある場合は、挿入順序に依存しないように注意してください。

void insert( std::initializer_list<value_type> il )

C++11 仕様。初期化子リストから各要素を挿入して、マップにシーケンスを挿入します。挿入順序または並列に実行するかどうかは指定できません。

注意

現在の実装は、挿入を順番に処理します。将来の実装では、挿入を並列に処理できるようになる可能性があります。初期化子リストに重複キーがある場合は、挿入順序に依存しないように注意してください。

bool erase( const Key& key )

指定されたキーを含むペアがあるかテーブルを検索します。ペアがある場合、一致するペアを削除します。ペアを指しているアクセサーがある場合もペアはテーブルから削除されますが、すべてのアクセサーが参照を停止するまで削除が保留されます。

戻り値: 呼び出しによりペアが削除された場合は true。キーがマップにない場合は false。

bool erase( const_accessor& item_accessor )

要件: item_accessor.empty()==false

効果

item_accessor で参照されるペアを削除します。別の const_accessorペアを指している場合もペアはテーブルから削除されますが、すべてのアクセサーが参照を停止するまで削除が保留されます。同時に同じキーの挿入を行うと、テーブルに新しいペアが作成され、削除されるペアと一時的に共存できます。

戻り値: このスレッドでペアが削除された場合は true。別のスレッドでペアが削除された場合は false。

bool erase( accessor& item_accessor )

要件: item_accessor.empty()==false

効果: item_accessor で参照されるペアをテーブルから削除し、破棄します。同時に同じキーの挿入を行うと、テーブルに新しいペアが作成され、削除されるペアと一時的に共存できます。

戻り値: このスレッドでペアが削除された場合は true。別のスレッドでペアが削除された場合は false。