have identical hash then you cannot insert both that keys in the set. \p %MultiLevelHashSet does not maintain the key,\r
it maintains its fixed-size hash value.\r
\r
+ Template parameters:\r
+ - \p GC - safe memory reclamation schema. Can be \p gc::HP, \p gc::DHP or one of \ref cds_urcu_type "RCU type"\r
+ - \p T - a value type to be stored in the set\r
+ - \p Traits - type traits, the structure based on \p multilevel_hashset::traits or result of \p multilevel_hashset::make_traits metafunction\r
\r
There are several specializations of \p %MultiLevelHashSet for each \p GC. You should include:
- <tt><cds/intrusive/multilevel_hashset_hp.h></tt> for \p gc::HP garbage collector
- <tt><cds/intrusive/multilevel_hashset_dhp.h></tt> for \p gc::DHP garbage collector
- - <tt><cds/intrusive/multilevel_hashset_nogc.h></tt> for \ref cds_intrusive_MultiLevelHashSet_nogc for append-only set
- <tt><cds/intrusive/multilevel_hashset_rcu.h></tt> for \ref cds_intrusive_MultiLevelHashSet_rcu "RCU type"
*/
template <
decltype( hash_accessor()( std::declval<T>()) )
>::type
>::type hash_type;
- static_assert( !std::is_pointer<hash_type>, "hash_accessor should return a reference to hash value" );
+ static_assert( !std::is_pointer<hash_type>::value, "hash_accessor should return a reference to hash value" );
typedef typename traits::disposer disposer; ///< data node disposer
hash_type const& hash = hash_accessor()( val );
hash_splitter splitter( hash );
hash_comparator cmp;
- gc::Guard guard;
+ typename gc::Guard guard;
back_off bkoff;
atomic_node_ptr * pArr = m_Head;
else {
// the slot is empty, try to insert data node
node_ptr pNull;
- if ( pArr[nSlot].compare_exchange_strong( pNull, node_ptr( &val ), memory_model::memory_order_release, atomics::memory_order_relaxed )
+ if ( pArr[nSlot].compare_exchange_strong( pNull, node_ptr( &val ), memory_model::memory_order_release, atomics::memory_order_relaxed ))
{
// the new data node has been inserted
f( val );
hash_type const& hash = hash_accessor()( val );
hash_splitter splitter( hash );
hash_comparator cmp;
- gc::Guard guard;
+ typename gc::Guard guard;
back_off bkoff;
atomic_node_ptr * pArr = m_Head;
// the slot is empty, try to insert data node
if ( bInsert ) {
node_ptr pNull;
- if ( pArr[nSlot].compare_exchange_strong( pNull, node_ptr( &val ), memory_model::memory_order_release, atomics::memory_order_relaxed )
+ if ( pArr[nSlot].compare_exchange_strong( pNull, node_ptr( &val ), memory_model::memory_order_release, atomics::memory_order_relaxed ))
{
// the new data node has been inserted
f( val );
}
else {
m_Stat.onUpdateFailed();
- return std:make_pair( false, false );
+ return std::make_pair( false, false );
}
// insert failed - slot has been changed by another thread
{
typename gc::Guard guard;
auto pred = [&val](value_type const& item) -> bool { return &item == &val; };
- value_type * p = do_erase( hash, guard, std::ref( pred ));
+ value_type * p = do_erase( hash_accessor()( val ), guard, std::ref( pred ));
// p is guarded by HP
if ( p ) {
metrics m;
m.head_node_size_log = head_bits;
- m.head_node_size = 1 << head_bits;
+ m.head_node_size = size_t(1) << head_bits;
m.array_node_size_log = array_bits;
- m.array_node_size = 1 << array_bits;
+ m.array_node_size = size_t(1) << array_bits;
return m;
}
- template <typename T>
- static bool check_node_alignment( T * p )
+ template <typename Q>
+ static bool check_node_alignment( Q const* p )
{
return (reinterpret_cast<uintptr_t>(p) & node_ptr::bitmask) == 0;
}
atomic_node_ptr * alloc_array_node() const
{
- return cxx_array_node_allocator().NewArray( array_node_size(), nullptr )
+ return cxx_array_node_allocator().NewArray( array_node_size(), nullptr );
}
void free_array_node( atomic_node_ptr * parr ) const
}
else {
// data node
- if ( pArr->compare_exchange_strong( slot, node_ptr(), memory_model::memory_order_acquire, atomics::memory_order_relaxed ) ) {
- gc::template retire<disposer>( p );
+ if ( pArr->compare_exchange_strong( slot, node_ptr(), memory_model::memory_order_acquire, atomics::memory_order_relaxed )) {
+ gc::template retire<disposer>( slot.ptr() );
--m_ItemCounter;
m_Stat.onEraseSuccess();
break;
pArr[idx].store( current, memory_model::memory_order_release );
cur = cur | array_converting;
- CDS_VERIFY( slot.compare_exchange_strong( cur, node_ptr( to_node( pArr ), array_node ), memory_model::memory_order_release, atomics::memory_order_relaxed )));
+ CDS_VERIFY(
+ slot.compare_exchange_strong( cur, node_ptr( to_node( pArr ), array_node ), memory_model::memory_order_release, atomics::memory_order_relaxed )
+ );
return std::make_pair( pArr, idx );
}
}} // namespace cds::intrusive
#endif // #ifndef CDSLIB_INTRUSIVE_IMPL_MULTILEVEL_HASHSET_H
-1
\ No newline at end of file