assert( m_guard.is_initialized() );
return m_guard;
}
+
+ void reset(guarded_type * p) CDS_NOEXCEPT
+ {
+ alloc_guard();
+ assert( m_guard.is_initialized() );
+ m_guard.set(p);
+ }
+
//@endcond
private:
};
\endcode
*/
- typedef opt::none hash_accessor;
+ typedef cds::opt::none hash_accessor;
/// Disposer for removing data nodes
- typedef opt::v::empty_disposer disposer;
+ typedef cds::intrusive::opt::v::empty_disposer disposer;
/// Hash comparing functor
/**
No default functor is provided.
If the option is not specified, the \p less option is used.
*/
- typedef opt::none compare;
+ typedef cds::opt::none compare;
/// Specifies binary predicate used for hash compare.
/**
If the option is not specified, \p memcmp() -like bit-wise hash comparator is used
because the hash value is treated as fixed-sized bit-string.
*/
- typedef opt::none less;
+ typedef cds::opt::none less;
/// Item counter
/**
Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
or \p opt::v::sequential_consistent (sequentially consisnent memory model).
*/
- typedef opt::v::relaxed_ordering memory_model;
+ typedef cds::opt::v::relaxed_ordering memory_model;
/// Back-off strategy
typedef cds::backoff::Default back_off;
/**
List of available policy see \p opt::rcu_check_deadlock
*/
- typedef opt::v::rcu_throw_deadlock rcu_check_deadlock;
+ typedef cds::opt::v::rcu_throw_deadlock rcu_check_deadlock;
};
/// Metafunction converting option list to \p multilevel_hashset::traits
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
+ - \p Traits - type traits, the structure based on \p multilevel_hashset::traits or result of \p multilevel_hashset::make_traits metafunction.\r
+ \p Traits is the mandatory argument because it has one mandatory type - an @ref multilevel_hashset::traits::hash_accessor "accessor" \r
+ to hash value of \p T. The set algorithm does not calculate that hash value.\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_rcu.h></tt> for \ref cds_intrusive_MultiLevelHashSet_rcu "RCU type"
+ - <tt><cds/intrusive/multilevel_hashset_rcu.h></tt> for \ref cds_intrusive_MultiLevelHashSet_rcu "RCU type". RCU specialization
+ has a slightly different interface.
*/
template <
class GC
return false;
}
+ /// Deletes the item pointed by iterator \p it
+ /**
+ Returns \p true if the operation is successful, \p false otherwise.
+
+ The function does not invalidate the iterator, it remains valid and can be used for further traversing.
+ */
+ bool erase_at( iterator const& it )
+ {
+ if ( it.m_set != this )
+ return false;
+ if ( it.m_pNode == m_Head && it.m_idx >= head_size())
+ return false;
+ if ( it.m_idx >= array_node_size() )
+ return false;
+
+ for (;;) {
+ node_ptr slot = it.m_pNode->nodes[it.m_idx].load( memory_model::memory_order_acquire );
+ if ( slot.bits() == 0 && slot.ptr() == it.pointer() ) {
+ if ( it.m_pNode->nodes[it.m_idx].compare_exchange_strong(slot, node_ptr(nullptr), memory_model::memory_order_acquire, atomics::memory_order_relaxed) ) {
+ // the item is guarded by iterator, so we may retire it safely
+ gc::template retire<disposer>( slot.ptr() );
+ --m_ItemCounter;
+ m_Stat.onEraseSuccess();
+ return true;
+ }
+ }
+ else
+ return false;
+ }
+ }
+
/// Extracts the item with specified \p hash
/**
The function searches \p hash in the set,
<ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_michael_set_rcu_shb_lazy.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_michael_set_rcu_sht.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_michael_set_rcu_sht_lazy.cpp" />\r
+ <ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_multilevel_hashset_dhp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_multilevel_hashset_hp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_skiplist_dhp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_skiplist_dhp_member.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_multilevel_hashset_hp.cpp">\r
<Filter>intrusive\multilevel_hashset</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\tests\test-hdr\set\hdr_intrusive_multilevel_hashset_dhp.cpp">\r
+ <Filter>intrusive\multilevel_hashset</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
<ClInclude Include="..\..\..\tests\test-hdr\set\hdr_intrusive_striped_set.h" />\r
<ClInclude Include="..\..\..\tests\test-hdr\set\hdr_striped_set.h" />\r
<ClInclude Include="..\..\..\tests\test-hdr\set\intrusive_cuckoo_set_common.h" />\r
+ <ClInclude Include="..\..\..\tests\test-hdr\size_check.h" />\r
</ItemGroup>\r
<PropertyGroup Label="Globals">\r
<ProjectGuid>{A38E5597-6916-4480-A343-C9846EF544E4}</ProjectGuid>\r
<ClInclude Include="..\..\..\tests\test-hdr\set\hdr_striped_set.h">\r
<Filter>container\striped</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\..\..\tests\test-hdr\size_check.h" />\r
</ItemGroup>\r
</Project>
\ No newline at end of file
CDS_TESTHDR_SET := \
tests/test-hdr/set/hdr_intrusive_multilevel_hashset_hp.cpp \
+ tests/test-hdr/set/hdr_intrusive_multilevel_hashset_dhp.cpp \
tests/test-hdr/set/hdr_intrusive_refinable_hashset_avlset.cpp \
tests/test-hdr/set/hdr_intrusive_refinable_hashset_list.cpp \
tests/test-hdr/set/hdr_intrusive_refinable_hashset_set.cpp \
details::liberate_set set( beans::ceil2( retiredList.second > nLiberateThreshold ? retiredList.second : nLiberateThreshold ) );
// Get list of retired pointers
+ size_t nRetiredCount = 0;
details::retired_ptr_node * pHead = retiredList.first;
while ( pHead ) {
details::retired_ptr_node * pNext = pHead->m_pNext.load( atomics::memory_order_relaxed );
pHead->m_pNextFree.store( nullptr, atomics::memory_order_relaxed );
set.insert( *pHead );
pHead = pNext;
+ ++nRetiredCount;
}
// Liberate cycle
assert( range.second != nullptr );
m_RetiredAllocator.free_range( range.first, range.second );
}
- else {
+ else if ( nRetiredCount >= nLiberateThreshold ) {
// scan() cycle did not free any retired pointer - double scan() threshold
m_nLiberateThreshold.compare_exchange_strong( nLiberateThreshold, nLiberateThreshold * 2, atomics::memory_order_release, atomics::memory_order_relaxed );
}
queue/hdr_vyukov_mpmc_cyclic.cpp)\r
\r
set(CDS_TESTHDR_SET\r
+ set/hdr_intrusive_multilevel_hashset_hp.cpp\r
+ set/hdr_intrusive_multilevel_hashset_dhp.cpp\r
set/hdr_intrusive_refinable_hashset_avlset.cpp\r
set/hdr_intrusive_refinable_hashset_list.cpp\r
set/hdr_intrusive_refinable_hashset_set.cpp\r
misc/michael_allocator.cpp\r
misc/hash_tuple.cpp\r
misc/bitop_st.cpp\r
+ misc/split_bitstring.cpp\r
misc/permutation_generator.cpp\r
misc/thread_init_fini.cpp)\r
\r
}
};
+ struct hash128
+ {
+ size_t lo;
+ size_t hi;
+
+ hash128() {}
+ hash128(size_t l, size_t h) : lo(l), hi(h) {}
+
+ struct make {
+ hash128 operator()( size_t n ) const
+ {
+ return hash128( std::hash<size_t>()( n ), std::hash<size_t>()( ~n ));
+ }
+ hash128 operator()( hash128 const& n ) const
+ {
+ return hash128( std::hash<size_t>()( n.lo ), std::hash<size_t>()( ~n.hi ));
+ }
+ };
+
+ struct less {
+ bool operator()( hash128 const& lhs, hash128 const& rhs ) const
+ {
+ if ( lhs.hi != rhs.hi )
+ return lhs.hi < rhs.hi;
+ return lhs.lo < rhs.lo;
+ }
+ };
+
+ struct cmp {
+ int operator()( hash128 const& lhs, hash128 const& rhs ) const
+ {
+ if ( lhs.hi != rhs.hi )
+ return lhs.hi < rhs.hi ? -1 : 1;
+ return lhs.lo < rhs.lo ? -1 : lhs.lo == rhs.lo ? 0 : 1;
+ }
+ };
+ };
+
+
template <typename Set, typename Hash>
void test_hp( size_t nHeadBits, size_t nArrayBits )
{
CPPUNIT_ASSERT(s.size() == 0 );
CPPUNIT_ASSERT(s.empty() );
+ // erase with iterator
+ for ( auto& el : arrValue ) {
+ el.nDisposeCount = 0;
+ el.nIteratorCall = 0;
+ CPPUNIT_ASSERT(s.insert( el ));
+ }
+ for ( typename Set::iterator it = s.begin(), itEnd = s.end(); it != itEnd; ++it ) {
+ s.erase_at( it );
+ it->nIteratorCall = 1;
+ }
+ CPPUNIT_ASSERT(s.size() == 0 );
+ Set::gc::force_dispose();
+ for ( auto& el : arrValue ) {
+ CPPUNIT_ASSERT( el.nDisposeCount == 1 );
+ CPPUNIT_ASSERT( el.nIteratorCall == 1 );
+ }
+ CPPUNIT_ASSERT(s.empty() );
+
CPPUNIT_MSG( s.statistics() );
}
void hp_stdhash_stat();
void hp_stdhash_5_3();
void hp_stdhash_5_3_stat();
+ void hp_hash128();
+ void hp_hash128_stat();
+ void hp_hash128_4_3();
+ void hp_hash128_4_3_stat();
+
+ void dhp_stdhash();
+ void dhp_stdhash_stat();
+ void dhp_stdhash_5_3();
+ void dhp_stdhash_5_3_stat();
+ void dhp_hash128();
+ void dhp_hash128_stat();
+ void dhp_hash128_4_3();
+ void dhp_hash128_4_3_stat();
CPPUNIT_TEST_SUITE(IntrusiveMultiLevelHashSetHdrTest)
CPPUNIT_TEST(hp_stdhash)
CPPUNIT_TEST(hp_stdhash_stat)
CPPUNIT_TEST(hp_stdhash_5_3)
CPPUNIT_TEST(hp_stdhash_5_3_stat)
+ CPPUNIT_TEST(hp_hash128)
+ CPPUNIT_TEST(hp_hash128_stat)
+ CPPUNIT_TEST(hp_hash128_4_3)
+ CPPUNIT_TEST(hp_hash128_4_3_stat)
+
+ CPPUNIT_TEST(dhp_stdhash)
+ CPPUNIT_TEST(dhp_stdhash_stat)
+ CPPUNIT_TEST(dhp_stdhash_5_3)
+ CPPUNIT_TEST(dhp_stdhash_5_3_stat)
+ CPPUNIT_TEST(dhp_hash128)
+ CPPUNIT_TEST(dhp_hash128_stat)
+ CPPUNIT_TEST(dhp_hash128_4_3)
+ CPPUNIT_TEST(dhp_hash128_4_3_stat)
CPPUNIT_TEST_SUITE_END()
};
} // namespace set
--- /dev/null
+//$$CDS-header$$
+
+#include "set/hdr_intrusive_multilevel_hashset.h"
+#include <cds/intrusive/multilevel_hashset_dhp.h>
+#include "unit/print_multilevel_hashset_stat.h"
+
+namespace set {
+ namespace {
+ typedef cds::gc::DHP gc_type;
+ } // namespace
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_stdhash()
+ {
+ typedef size_t hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, size_t>::value, "set::hash_type != size_t!!!" );
+ test_hp<set_type, std::hash<hash_type>>(4, 2);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ >::type
+ > set_type2;
+ test_hp<set_type2, std::hash<hash_type>>(4, 2);
+ }
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_hash128()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef hash128::less less;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash128!!!" );
+ test_hp<set_type, hash128::make>(4, 2);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ , ci::opt::less< hash_type::less >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash128::make>(4, 2);
+ }
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_stdhash_stat()
+ {
+ typedef size_t hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef ci::multilevel_hashset::stat<> stat;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, size_t>::value, "set::hash_type != size_t!!!" );
+ test_hp<set_type, std::hash<hash_type>>(4, 2);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ ,co::stat< ci::multilevel_hashset::stat<>>
+ >::type
+ > set_type2;
+ test_hp<set_type2, std::hash<hash_type>>(4, 2);
+ }
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_hash128_stat()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef hash128::cmp compare;
+ typedef ci::multilevel_hashset::stat<> stat;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash_type!!!" );
+ test_hp<set_type, hash_type::make>(4, 2);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ ,co::stat< ci::multilevel_hashset::stat<>>
+ ,co::compare< hash128::cmp >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash_type::make>(4, 2);
+ }
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_stdhash_5_3()
+ {
+ typedef size_t hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, size_t>::value, "set::hash_type != size_t!!!" );
+ test_hp<set_type, std::hash<hash_type>>(5, 3);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ >::type
+ > set_type2;
+ test_hp<set_type2, std::hash<hash_type>>(5, 3);
+ }
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_hash128_4_3()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef co::v::sequential_consistent memory_model;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash_type!!!" );
+ test_hp<set_type, hash128::make >(4, 3);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ ,co::memory_model< co::v::sequential_consistent >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash128::make >(4, 3);
+ }
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_stdhash_5_3_stat()
+ {
+ typedef size_t hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef ci::multilevel_hashset::stat<> stat;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, size_t>::value, "set::hash_type != size_t!!!" );
+ test_hp<set_type, std::hash<hash_type>>(5, 3);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ ,co::stat< ci::multilevel_hashset::stat<>>
+ >::type
+ > set_type2;
+ test_hp<set_type2, std::hash<hash_type>>(5, 3);
+ }
+
+ void IntrusiveMultiLevelHashSetHdrTest::dhp_hash128_4_3_stat()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef ci::multilevel_hashset::stat<> stat;
+ typedef hash128::less less;
+ typedef hash128::cmp compare;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash_type!!!" );
+ test_hp<set_type, hash_type::make>(4, 3);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ , co::stat< ci::multilevel_hashset::stat<>>
+ , co::less< hash_type::less >
+ , co::compare< hash128::cmp >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash_type::make>(4, 3);
+ }
+
+} // namespace set
+
+CPPUNIT_TEST_SUITE_REGISTRATION(set::IntrusiveMultiLevelHashSetHdrTest);
test_hp<set_type2, std::hash<hash_type>>(4, 2);
}
+ void IntrusiveMultiLevelHashSetHdrTest::hp_hash128()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef hash128::less less;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash128!!!" );
+ test_hp<set_type, hash128::make>(4, 2);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ , ci::opt::less< hash_type::less >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash128::make>(4, 2);
+ }
+
void IntrusiveMultiLevelHashSetHdrTest::hp_stdhash_stat()
{
typedef size_t hash_type;
test_hp<set_type2, std::hash<hash_type>>(4, 2);
}
+ void IntrusiveMultiLevelHashSetHdrTest::hp_hash128_stat()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef hash128::cmp compare;
+ typedef ci::multilevel_hashset::stat<> stat;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash_type!!!" );
+ test_hp<set_type, hash_type::make>(4, 2);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ ,co::stat< ci::multilevel_hashset::stat<>>
+ ,co::compare< hash128::cmp >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash_type::make>(4, 2);
+ }
+
void IntrusiveMultiLevelHashSetHdrTest::hp_stdhash_5_3()
{
typedef size_t hash_type;
test_hp<set_type2, std::hash<hash_type>>(5, 3);
}
+ void IntrusiveMultiLevelHashSetHdrTest::hp_hash128_4_3()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef co::v::sequential_consistent memory_model;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash_type!!!" );
+ test_hp<set_type, hash128::make >(4, 3);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ ,co::memory_model< co::v::sequential_consistent >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash128::make >(4, 3);
+ }
+
void IntrusiveMultiLevelHashSetHdrTest::hp_stdhash_5_3_stat()
{
typedef size_t hash_type;
test_hp<set_type2, std::hash<hash_type>>(5, 3);
}
+ void IntrusiveMultiLevelHashSetHdrTest::hp_hash128_4_3_stat()
+ {
+ typedef hash128 hash_type;
+
+ struct traits: public ci::multilevel_hashset::traits
+ {
+ typedef get_hash<hash_type> hash_accessor;
+ typedef item_disposer disposer;
+ typedef ci::multilevel_hashset::stat<> stat;
+ typedef hash128::less less;
+ typedef hash128::cmp compare;
+ };
+ typedef ci::MultiLevelHashSet< gc_type, Item<hash_type>, traits > set_type;
+ static_assert(std::is_same< typename set_type::hash_type, hash_type>::value, "set::hash_type != hash_type!!!" );
+ test_hp<set_type, hash_type::make>(4, 3);
+
+ typedef ci::MultiLevelHashSet<
+ gc_type,
+ Item<hash_type>,
+ typename ci::multilevel_hashset::make_traits<
+ ci::multilevel_hashset::hash_accessor< get_hash<hash_type>>
+ , ci::opt::disposer< item_disposer >
+ , co::stat< ci::multilevel_hashset::stat<>>
+ , co::less< hash_type::less >
+ , co::compare< hash128::cmp >
+ >::type
+ > set_type2;
+ test_hp<set_type2, hash_type::make>(4, 3);
+ }
+
} // namespace set
CPPUNIT_TEST_SUITE_REGISTRATION(set::IntrusiveMultiLevelHashSetHdrTest);