From 24097b648bf247c4feb9ab5e042f0b5355abb0ce Mon Sep 17 00:00:00 2001 From: khizmax Date: Mon, 23 Mar 2015 17:01:11 +0300 Subject: [PATCH] Issue #21: splitted map_delodd test --- projects/Win/vc12/unit-map-delodd.vcxproj | 9 + projects/Win/vc12/unit-map-insdel.vcxproj | 15 +- projects/source.unit.map.mk | 23 +- tests/unit/map2/map_delodd.cpp | 775 +----------------- tests/unit/map2/map_delodd.h | 723 ++++++++++++++++ tests/unit/map2/map_delodd_bronsonavltree.cpp | 9 + tests/unit/map2/map_delodd_cuckoo.cpp | 9 + tests/unit/map2/map_delodd_ellentree.cpp | 9 + tests/unit/map2/map_delodd_michael.cpp | 9 + tests/unit/map2/map_delodd_skip.cpp | 9 + tests/unit/map2/map_delodd_split.cpp | 9 + tests/unit/map2/map_insdel_func.cpp | 4 - ...cpp => map_insdel_func_bronsonavltree.cpp} | 0 ...l_func8.cpp => map_insdel_func_cuckoo.cpp} | 0 ...unc4.cpp => map_insdel_func_ellentree.cpp} | 0 tests/unit/map2/map_insdel_func_michael.cpp | 9 + ...unc7.cpp => map_insdel_func_refinable.cpp} | 0 ...del_func3.cpp => map_insdel_func_skip.cpp} | 0 ...el_func2.cpp => map_insdel_func_split.cpp} | 0 ..._func6.cpp => map_insdel_func_striped.cpp} | 0 20 files changed, 860 insertions(+), 752 deletions(-) create mode 100644 tests/unit/map2/map_delodd.h create mode 100644 tests/unit/map2/map_delodd_bronsonavltree.cpp create mode 100644 tests/unit/map2/map_delodd_cuckoo.cpp create mode 100644 tests/unit/map2/map_delodd_ellentree.cpp create mode 100644 tests/unit/map2/map_delodd_michael.cpp create mode 100644 tests/unit/map2/map_delodd_skip.cpp create mode 100644 tests/unit/map2/map_delodd_split.cpp rename tests/unit/map2/{map_insdel_func5.cpp => map_insdel_func_bronsonavltree.cpp} (100%) rename tests/unit/map2/{map_insdel_func8.cpp => map_insdel_func_cuckoo.cpp} (100%) rename tests/unit/map2/{map_insdel_func4.cpp => map_insdel_func_ellentree.cpp} (100%) create mode 100644 tests/unit/map2/map_insdel_func_michael.cpp rename tests/unit/map2/{map_insdel_func7.cpp => map_insdel_func_refinable.cpp} (100%) rename tests/unit/map2/{map_insdel_func3.cpp => map_insdel_func_skip.cpp} (100%) rename tests/unit/map2/{map_insdel_func2.cpp => map_insdel_func_split.cpp} (100%) rename tests/unit/map2/{map_insdel_func6.cpp => map_insdel_func_striped.cpp} (100%) diff --git a/projects/Win/vc12/unit-map-delodd.vcxproj b/projects/Win/vc12/unit-map-delodd.vcxproj index 8474f43a..ec9b34a1 100644 --- a/projects/Win/vc12/unit-map-delodd.vcxproj +++ b/projects/Win/vc12/unit-map-delodd.vcxproj @@ -44,6 +44,15 @@ + + + + + + + + + {3C598F96-FB84-4d42-9B43-F697F53B0221} diff --git a/projects/Win/vc12/unit-map-insdel.vcxproj b/projects/Win/vc12/unit-map-insdel.vcxproj index 9a504f1d..cc319af4 100644 --- a/projects/Win/vc12/unit-map-insdel.vcxproj +++ b/projects/Win/vc12/unit-map-insdel.vcxproj @@ -45,13 +45,14 @@ - - - - - - - + + + + + + + + diff --git a/projects/source.unit.map.mk b/projects/source.unit.map.mk index f66e4a40..078ec837 100644 --- a/projects/source.unit.map.mk +++ b/projects/source.unit.map.mk @@ -3,17 +3,24 @@ CDSUNIT_MAP_SOURCES := \ tests/unit/map2/map_find_int.cpp \ tests/unit/map2/map_find_string.cpp \ tests/unit/map2/map_insdel_func.cpp \ - tests/unit/map2/map_insdel_func2.cpp \ - tests/unit/map2/map_insdel_func3.cpp \ - tests/unit/map2/map_insdel_func4.cpp \ - tests/unit/map2/map_insdel_func5.cpp \ - tests/unit/map2/map_insdel_func6.cpp \ - tests/unit/map2/map_insdel_func7.cpp \ - tests/unit/map2/map_insdel_func8.cpp \ + tests/unit/map2/map_insdel_func_michael.cpp \ + tests/unit/map2/map_insdel_func_split.cpp \ + tests/unit/map2/map_insdel_func_skip.cpp \ + tests/unit/map2/map_insdel_func_ellentree.cpp \ + tests/unit/map2/map_insdel_func_bronsonavltree.cpp \ + tests/unit/map2/map_insdel_func_striped.cpp \ + tests/unit/map2/map_insdel_func_refinable.cpp \ + tests/unit/map2/map_insdel_func_cuckoo.cpp \ tests/unit/map2/map_insdel_int.cpp \ tests/unit/map2/map_insdel_item_int.cpp \ tests/unit/map2/map_insdel_string.cpp \ tests/unit/map2/map_insdel_item_string.cpp \ tests/unit/map2/map_insfind_int.cpp \ tests/unit/map2/map_insdelfind.cpp \ - tests/unit/map2/map_delodd.cpp + tests/unit/map2/map_delodd.cpp \ + tests/unit/map2/map_delodd_michael.cpp \ + tests/unit/map2/map_delodd_bronsonavltree.cpp \ + tests/unit/map2/map_delodd_ellentree.cpp \ + tests/unit/map2/map_delodd_split.cpp \ + tests/unit/map2/map_delodd_skip.cpp \ + tests/unit/map2/map_delodd_cuckoo.cpp \ diff --git a/tests/unit/map2/map_delodd.cpp b/tests/unit/map2/map_delodd.cpp index a57c5d58..b2e974f4 100644 --- a/tests/unit/map2/map_delodd.cpp +++ b/tests/unit/map2/map_delodd.cpp @@ -1,744 +1,53 @@ //$$CDS-header$$ -#include "cppunit/thread.h" -#include "map2/map_types.h" -#include // random_shuffle +#include "map2/map_delodd.h" namespace map2 { + CPPUNIT_TEST_SUITE_REGISTRATION( Map_DelOdd ); -# define TEST_MAP(X) void X() { test::X >(); } -# define TEST_MAP_EXTRACT(X) void X() { test_extract::X >(); } -# define TEST_MAP_NOLF(X) void X() { test_nolf::X >(); } -# define TEST_MAP_NOLF_EXTRACT(X) void X() { test_nolf_extract::X >(); } - - namespace { - static size_t c_nMapSize = 1000000 ; // max map size - static size_t c_nInsThreadCount = 4 ; // insert thread count - static size_t c_nDelThreadCount = 4 ; // delete thread count - static size_t c_nExtractThreadCount = 4 ; // extract thread count - static size_t c_nMaxLoadFactor = 8 ; // maximum load factor - static bool c_bPrintGCState = true; - } - - namespace { - struct key_thread - { - size_t nKey; - size_t nThread; - - key_thread( size_t key, size_t threadNo ) - : nKey( key ) - , nThread( threadNo ) - {} - - key_thread() - {} - }; - - //typedef MapTypes::key_val key_value_pair; + size_t Map_DelOdd::c_nMapSize = 1000000 ; // max map size + size_t Map_DelOdd::c_nInsThreadCount = 4 ; // insert thread count + size_t Map_DelOdd::c_nDelThreadCount = 4 ; // delete thread count + size_t Map_DelOdd::c_nExtractThreadCount = 4 ; // extract thread count + size_t Map_DelOdd::c_nMaxLoadFactor = 8 ; // maximum load factor + bool Map_DelOdd::c_bPrintGCState = true; + + void Map_DelOdd::setUpParams( const CppUnitMini::TestCfg& cfg ) { + c_nMapSize = cfg.getULong("MapSize", static_cast(c_nMapSize) ); + c_nInsThreadCount = cfg.getULong("InsThreadCount", static_cast(c_nInsThreadCount) ); + c_nDelThreadCount = cfg.getULong("DelThreadCount", static_cast(c_nDelThreadCount) ); + c_nExtractThreadCount = cfg.getULong("ExtractThreadCount", static_cast(c_nExtractThreadCount) ); + c_nMaxLoadFactor = cfg.getULong("MaxLoadFactor", static_cast(c_nMaxLoadFactor) ); + c_bPrintGCState = cfg.getBool("PrintGCStateFlag", true ); + + if ( c_nInsThreadCount == 0 ) + c_nInsThreadCount = cds::OS::topology::processor_count(); + if ( c_nDelThreadCount == 0 && c_nExtractThreadCount == 0 ) { + c_nExtractThreadCount = cds::OS::topology::processor_count() / 2; + c_nDelThreadCount = cds::OS::topology::processor_count() - c_nExtractThreadCount; + } + + m_arrData.resize( c_nMapSize ); + for ( size_t i = 0; i < c_nMapSize; ++i ) + m_arrData[i] = i; + std::random_shuffle( m_arrData.begin(), m_arrData.end() ); } - template <> - struct cmp { - int operator ()(key_thread const& k1, key_thread const& k2) const - { - if ( k1.nKey < k2.nKey ) - return -1; - if ( k1.nKey > k2.nKey ) - return 1; - if ( k1.nThread < k2.nThread ) - return -1; - if ( k1.nThread > k2.nThread ) - return 1; - return 0; - } - int operator ()(key_thread const& k1, size_t k2) const - { - if ( k1.nKey < k2 ) - return -1; - if ( k1.nKey > k2 ) - return 1; - return 0; - } - int operator ()(size_t k1, key_thread const& k2) const - { - if ( k1 < k2.nKey ) - return -1; - if ( k1 > k2.nKey ) - return 1; - return 0; - } - }; - -} // namespace map2 - -namespace std { - template <> - struct less - { - bool operator()(map2::key_thread const& k1, map2::key_thread const& k2) const - { - if ( k1.nKey <= k2.nKey ) - return k1.nKey < k2.nKey || k1.nThread < k2.nThread; - return false; - } - }; - - template <> - struct hash - { - typedef size_t result_type; - typedef map2::key_thread argument_type; - - size_t operator()( map2::key_thread const& k ) const - { - return std::hash()(k.nKey); - } - size_t operator()( size_t k ) const - { - return std::hash()(k); - } - }; -} // namespace std - -namespace boost { - inline size_t hash_value( map2::key_thread const& k ) + void Map_DelOdd::myRun(const char *in_name, bool invert /*= false*/) { - return std::hash()( k.nKey ); + setUpParams( m_Cfg.get( "Map_InsDel_func" )); + + run_MichaelMap(in_name, invert); + run_SplitList(in_name, invert); + run_SkipListMap(in_name, invert); + run_EllenBinTreeMap(in_name, invert); + run_BronsonAVLTreeMap(in_name, invert); + //run_StripedMap(in_name, invert); + //run_RefinableMap(in_name, invert); + run_CuckooMap(in_name, invert); + //run_StdMap(in_name, invert); + + endTestCase(); } - template <> - struct hash - { - typedef size_t result_type; - typedef map2::key_thread argument_type; - - size_t operator()(map2::key_thread const& k) const - { - return boost::hash()( k.nKey ); - } - size_t operator()(size_t k) const - { - return boost::hash()( k ); - } - }; -} // namespace boost - -namespace map2 { - - class Map_DelOdd: public CppUnitMini::TestCase - { - std::vector m_arrData; - - protected: - typedef key_thread key_type; - typedef size_t value_type; - typedef std::pair pair_type; - - atomics::atomic m_nInsThreadCount; - - // Inserts keys from [0..N) - template - class InsertThread: public CppUnitMini::TestThread - { - Map& m_Map; - - virtual InsertThread * clone() - { - return new InsertThread( *this ); - } - - struct ensure_func - { - template - void operator()( bool /*bNew*/, Q const& ) - {} - template - void operator()( bool /*bNew*/, Q const&, V& ) - {} - }; - public: - size_t m_nInsertSuccess; - size_t m_nInsertFailed; - - public: - InsertThread( CppUnitMini::ThreadPool& pool, Map& rMap ) - : CppUnitMini::TestThread( pool ) - , m_Map( rMap ) - {} - InsertThread( InsertThread& src ) - : CppUnitMini::TestThread( src ) - , m_Map( src.m_Map ) - {} - - Map_DelOdd& getTest() - { - return reinterpret_cast( m_Pool.m_Test ); - } - - virtual void init() { cds::threading::Manager::attachThread() ; } - virtual void fini() { cds::threading::Manager::detachThread() ; } - - virtual void test() - { - Map& rMap = m_Map; - - m_nInsertSuccess = - m_nInsertFailed = 0; - - std::vector& arrData = getTest().m_arrData; - for ( size_t i = 0; i < arrData.size(); ++i ) { - if ( rMap.insert( key_type( arrData[i], m_nThreadNo ))) - ++m_nInsertSuccess; - else - ++m_nInsertFailed; - } - - ensure_func f; - for ( size_t i = arrData.size() - 1; i > 0; --i ) { - if ( arrData[i] & 1 ) { - rMap.ensure( key_type( arrData[i], m_nThreadNo ), f ); - } - } - - getTest().m_nInsThreadCount.fetch_sub( 1, atomics::memory_order_acquire ); - } - }; - - struct key_equal { - bool operator()( key_type const& k1, key_type const& k2 ) const - { - return k1.nKey == k2.nKey; - } - bool operator()( size_t k1, key_type const& k2 ) const - { - return k1 == k2.nKey; - } - bool operator()( key_type const& k1, size_t k2 ) const - { - return k1.nKey == k2; - } - }; - - struct key_less { - bool operator()( key_type const& k1, key_type const& k2 ) const - { - return k1.nKey < k2.nKey; - } - bool operator()( size_t k1, key_type const& k2 ) const - { - return k1 < k2.nKey; - } - bool operator()( key_type const& k1, size_t k2 ) const - { - return k1.nKey < k2; - } - - typedef key_equal equal_to; - }; - - // Deletes odd keys from [0..N) - template - class DeleteThread: public CppUnitMini::TestThread - { - Map& m_Map; - - virtual DeleteThread * clone() - { - return new DeleteThread( *this ); - } - public: - size_t m_nDeleteSuccess; - size_t m_nDeleteFailed; - - public: - DeleteThread( CppUnitMini::ThreadPool& pool, Map& rMap ) - : CppUnitMini::TestThread( pool ) - , m_Map( rMap ) - {} - DeleteThread( DeleteThread& src ) - : CppUnitMini::TestThread( src ) - , m_Map( src.m_Map ) - {} - - Map_DelOdd& getTest() - { - return reinterpret_cast( m_Pool.m_Test ); - } - - virtual void init() { cds::threading::Manager::attachThread() ; } - virtual void fini() { cds::threading::Manager::detachThread() ; } - - virtual void test() - { - Map& rMap = m_Map; - - m_nDeleteSuccess = - m_nDeleteFailed = 0; - - std::vector& arrData = getTest().m_arrData; - if ( m_nThreadNo & 1 ) { - for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { - for ( size_t i = 0; i < arrData.size(); ++i ) { - if ( arrData[i] & 1 ) { - if ( rMap.erase_with( arrData[i], key_less() )) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - } - } - if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) - break; - } - } - else { - for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { - for ( size_t i = arrData.size() - 1; i > 0; --i ) { - if ( arrData[i] & 1 ) { - if ( rMap.erase_with( arrData[i], key_less() )) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - } - } - if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) - break; - } - } - } - }; - - // Deletes odd keys from [0..N) - template - class ExtractThread: public CppUnitMini::TestThread - { - Map& m_Map; - - virtual ExtractThread * clone() - { - return new ExtractThread( *this ); - } - public: - size_t m_nDeleteSuccess; - size_t m_nDeleteFailed; - - public: - ExtractThread( CppUnitMini::ThreadPool& pool, Map& rMap ) - : CppUnitMini::TestThread( pool ) - , m_Map( rMap ) - {} - ExtractThread( ExtractThread& src ) - : CppUnitMini::TestThread( src ) - , m_Map( src.m_Map ) - {} - - Map_DelOdd& getTest() - { - return reinterpret_cast( m_Pool.m_Test ); - } - - virtual void init() { cds::threading::Manager::attachThread() ; } - virtual void fini() { cds::threading::Manager::detachThread() ; } - - virtual void test() - { - Map& rMap = m_Map; - - m_nDeleteSuccess = - m_nDeleteFailed = 0; - - typename Map::guarded_ptr gp; - - std::vector& arrData = getTest().m_arrData; - if ( m_nThreadNo & 1 ) { - for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { - for ( size_t i = 0; i < arrData.size(); ++i ) { - if ( arrData[i] & 1 ) { - gp = rMap.extract_with( arrData[i], key_less()); - if ( gp ) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - gp.release(); - } - } - if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) - break; - } - } - else { - for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { - for ( size_t i = arrData.size() - 1; i > 0; --i ) { - if ( arrData[i] & 1 ) { - gp = rMap.extract_with( arrData[i], key_less()); - if ( gp ) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - gp.release(); - } - } - if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) - break; - } - } - } - }; - - template - class ExtractThread< cds::urcu::gc, Map > : public CppUnitMini::TestThread - { - Map& m_Map; - - virtual ExtractThread * clone() - { - return new ExtractThread( *this ); - } - public: - size_t m_nDeleteSuccess; - size_t m_nDeleteFailed; - - public: - ExtractThread( CppUnitMini::ThreadPool& pool, Map& rMap ) - : CppUnitMini::TestThread( pool ) - , m_Map( rMap ) - {} - ExtractThread( ExtractThread& src ) - : CppUnitMini::TestThread( src ) - , m_Map( src.m_Map ) - {} - - Map_DelOdd& getTest() - { - return reinterpret_cast( m_Pool.m_Test ); - } - - virtual void init() { cds::threading::Manager::attachThread() ; } - virtual void fini() { cds::threading::Manager::detachThread() ; } - - virtual void test() - { - Map& rMap = m_Map; - - m_nDeleteSuccess = - m_nDeleteFailed = 0; - - typename Map::exempt_ptr xp; - - std::vector& arrData = getTest().m_arrData; - if ( m_nThreadNo & 1 ) { - for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { - for ( size_t i = 0; i < arrData.size(); ++i ) { - if ( arrData[i] & 1 ) { - if ( Map::c_bExtractLockExternal ) { - { - typename Map::rcu_lock l; - xp = rMap.extract_with( arrData[i], key_less() ); - if ( xp ) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - } - } - else { - xp = rMap.extract_with( arrData[i], key_less() ); - if ( xp ) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - } - xp.release(); - } - } - if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) - break; - } - } - else { - for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { - for ( size_t i = arrData.size() - 1; i > 0; --i ) { - if ( arrData[i] & 1 ) { - if ( Map::c_bExtractLockExternal ) { - { - typename Map::rcu_lock l; - xp = rMap.extract_with( arrData[i], key_less() ); - if ( xp ) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - } - } - else { - xp = rMap.extract_with( arrData[i], key_less() ); - if ( xp ) - ++m_nDeleteSuccess; - else - ++m_nDeleteFailed; - } - xp.release(); - } - } - if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) - break; - } - } - } - }; - - protected: - template - void do_test( size_t nLoadFactor ) - { - Map testMap( c_nMapSize, nLoadFactor ); - do_test_with( testMap ); - } - - template - void do_test_extract( size_t nLoadFactor ) - { - Map testMap( c_nMapSize, nLoadFactor ); - do_test_extract_with( testMap ); - } - - template - void do_test_with( Map& testMap ) - { - typedef InsertThread insert_thread; - typedef DeleteThread delete_thread; - - m_nInsThreadCount.store( c_nInsThreadCount, atomics::memory_order_release ); - - CppUnitMini::ThreadPool pool( *this ); - pool.add( new insert_thread( pool, testMap ), c_nInsThreadCount ); - pool.add( new delete_thread( pool, testMap ), c_nDelThreadCount ? c_nDelThreadCount : cds::OS::topology::processor_count()); - pool.run(); - CPPUNIT_MSG( " Duration=" << pool.avgDuration() ); - - size_t nInsertSuccess = 0; - size_t nInsertFailed = 0; - size_t nDeleteSuccess = 0; - size_t nDeleteFailed = 0; - for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) { - insert_thread * pThread = dynamic_cast( *it ); - if ( pThread ) { - nInsertSuccess += pThread->m_nInsertSuccess; - nInsertFailed += pThread->m_nInsertFailed; - } - else { - delete_thread * p = static_cast( *it ); - nDeleteSuccess += p->m_nDeleteSuccess; - nDeleteFailed += p->m_nDeleteFailed; - } - } - - CPPUNIT_MSG( " Totals (success/failed): \n\t" - << " Insert=" << nInsertSuccess << '/' << nInsertFailed << "\n\t" - << " Delete=" << nDeleteSuccess << '/' << nDeleteFailed << "\n\t" - ); - CPPUNIT_CHECK( nInsertSuccess == c_nMapSize * c_nInsThreadCount ); - CPPUNIT_CHECK( nInsertFailed == 0 ); - - analyze( testMap ); - } - - template - void do_test_extract_with( Map& testMap ) - { - typedef InsertThread insert_thread; - typedef DeleteThread delete_thread; - typedef ExtractThread< typename Map::gc, Map > extract_thread; - - m_nInsThreadCount.store( c_nInsThreadCount, atomics::memory_order_release ); - - CppUnitMini::ThreadPool pool( *this ); - pool.add( new insert_thread( pool, testMap ), c_nInsThreadCount ); - if ( c_nDelThreadCount ) - pool.add( new delete_thread( pool, testMap ), c_nDelThreadCount ); - if ( c_nExtractThreadCount ) - pool.add( new extract_thread( pool, testMap ), c_nExtractThreadCount ); - pool.run(); - CPPUNIT_MSG( " Duration=" << pool.avgDuration() ); - - size_t nInsertSuccess = 0; - size_t nInsertFailed = 0; - size_t nDeleteSuccess = 0; - size_t nDeleteFailed = 0; - size_t nExtractSuccess = 0; - size_t nExtractFailed = 0; - for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) { - insert_thread * pThread = dynamic_cast( *it ); - if ( pThread ) { - nInsertSuccess += pThread->m_nInsertSuccess; - nInsertFailed += pThread->m_nInsertFailed; - } - else { - delete_thread * p = dynamic_cast( *it ); - if ( p ) { - nDeleteSuccess += p->m_nDeleteSuccess; - nDeleteFailed += p->m_nDeleteFailed; - } - else { - extract_thread * pExtract = dynamic_cast( *it ); - assert( pExtract ); - nExtractSuccess += pExtract->m_nDeleteSuccess; - nExtractFailed += pExtract->m_nDeleteFailed; - } - } - } - - CPPUNIT_MSG( " Totals (success/failed): \n\t" - << " Insert=" << nInsertSuccess << '/' << nInsertFailed << "\n\t" - << " Delete=" << nDeleteSuccess << '/' << nDeleteFailed << "\n\t" - << " Extract=" << nExtractSuccess << '/' << nExtractFailed << "\n\t" - ); - CPPUNIT_CHECK( nInsertSuccess == c_nMapSize * c_nInsThreadCount ); - CPPUNIT_CHECK( nInsertFailed == 0 ); - - analyze( testMap ); - } - - template - void analyze( Map& testMap ) - { - cds::OS::Timer timer; - - // All even keys must be in the map - { - size_t nErrorCount = 0; - CPPUNIT_MSG( " Check even keys..." ); - for ( size_t n = 0; n < c_nMapSize; n +=2 ) { - for ( size_t i = 0; i < c_nInsThreadCount; ++i ) { - if ( !testMap.find( key_type(n, i) ) ) { - if ( ++nErrorCount < 10 ) { - CPPUNIT_MSG( "key " << n << "-" << i << " is not found!"); - } - } - } - } - CPPUNIT_CHECK_EX( nErrorCount == 0, "Totals: " << nErrorCount << " keys is not found"); - } - - check_before_cleanup( testMap ); - - CPPUNIT_MSG( " Clear map (single-threaded)..." ); - timer.reset(); - testMap.clear(); - CPPUNIT_MSG( " Duration=" << timer.duration() ); - CPPUNIT_CHECK_EX( testMap.empty(), ((long long) testMap.size()) ); - - additional_check( testMap ); - print_stat( testMap ); - - additional_cleanup( testMap ); - } - - - template - void test() - { - CPPUNIT_MSG( "Insert thread count=" << c_nInsThreadCount - << " delete thread count=" << c_nDelThreadCount - << " set size=" << c_nMapSize - ); - - for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) { - CPPUNIT_MSG( "Load factor=" << nLoadFactor ); - do_test( nLoadFactor ); - if ( c_bPrintGCState ) - print_gc_state(); - } - } - - template - void test_extract() - { - CPPUNIT_MSG( "Thread count: insert=" << c_nInsThreadCount - << ", delete=" << c_nDelThreadCount - << ", extract=" << c_nExtractThreadCount - << "; set size=" << c_nMapSize - ); - - for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) { - CPPUNIT_MSG( "Load factor=" << nLoadFactor ); - do_test_extract( nLoadFactor ); - if ( c_bPrintGCState ) - print_gc_state(); - } - } - - template - void test_nolf() - { - CPPUNIT_MSG( "Insert thread count=" << c_nInsThreadCount - << " delete thread count=" << c_nDelThreadCount - << " set size=" << c_nMapSize - ); - - Map s; - do_test_with( s ); - if ( c_bPrintGCState ) - print_gc_state(); - } - - template - void test_nolf_extract() - { - CPPUNIT_MSG( "Thread count: insert=" << c_nInsThreadCount - << ", delete=" << c_nDelThreadCount - << ", extract=" << c_nExtractThreadCount - << "; set size=" << c_nMapSize - ); - - Map s; - do_test_extract_with( s ); - if ( c_bPrintGCState ) - print_gc_state(); - } - - void setUpParams( const CppUnitMini::TestCfg& cfg ) { - c_nMapSize = cfg.getULong("MapSize", static_cast(c_nMapSize) ); - c_nInsThreadCount = cfg.getULong("InsThreadCount", static_cast(c_nInsThreadCount) ); - c_nDelThreadCount = cfg.getULong("DelThreadCount", static_cast(c_nDelThreadCount) ); - c_nExtractThreadCount = cfg.getULong("ExtractThreadCount", static_cast(c_nExtractThreadCount) ); - c_nMaxLoadFactor = cfg.getULong("MaxLoadFactor", static_cast(c_nMaxLoadFactor) ); - c_bPrintGCState = cfg.getBool("PrintGCStateFlag", true ); - - if ( c_nInsThreadCount == 0 ) - c_nInsThreadCount = cds::OS::topology::processor_count(); - if ( c_nDelThreadCount == 0 && c_nExtractThreadCount == 0 ) { - c_nExtractThreadCount = cds::OS::topology::processor_count() / 2; - c_nDelThreadCount = cds::OS::topology::processor_count() - c_nExtractThreadCount; - } - - m_arrData.resize( c_nMapSize ); - for ( size_t i = 0; i < c_nMapSize; ++i ) - m_arrData[i] = i; - std::random_shuffle( m_arrData.begin(), m_arrData.end() ); - } - -# include "map2/map_defs.h" - CDSUNIT_DECLARE_MichaelMap - CDSUNIT_DECLARE_SplitList - //CDSUNIT_DECLARE_StripedMap - //CDSUNIT_DECLARE_RefinableMap - CDSUNIT_DECLARE_CuckooMap - CDSUNIT_DECLARE_SkipListMap - CDSUNIT_DECLARE_EllenBinTreeMap - CDSUNIT_DECLARE_BronsonAVLTreeMap - //CDSUNIT_DECLARE_StdMap - - CPPUNIT_TEST_SUITE( Map_DelOdd ) - CDSUNIT_TEST_MichaelMap - CDSUNIT_TEST_SplitList - CDSUNIT_TEST_SkipListMap - CDSUNIT_TEST_EllenBinTreeMap - CDSUNIT_TEST_BronsonAVLTreeMap - //CDSUNIT_TEST_StripedMap - //CDSUNIT_TEST_RefinableMap - CDSUNIT_TEST_CuckooMap - //CDSUNIT_TEST_StdMap - CPPUNIT_TEST_SUITE_END() - }; - - CPPUNIT_TEST_SUITE_REGISTRATION( Map_DelOdd ); } // namespace map2 diff --git a/tests/unit/map2/map_delodd.h b/tests/unit/map2/map_delodd.h new file mode 100644 index 00000000..226098bd --- /dev/null +++ b/tests/unit/map2/map_delodd.h @@ -0,0 +1,723 @@ +//$$CDS-header$$ + +#include "cppunit/thread.h" +#include "map2/map_types.h" +#include // random_shuffle + +namespace map2 { + +# define TEST_MAP(X) void X() { test::X >(); } +# define TEST_MAP_EXTRACT(X) void X() { test_extract::X >(); } +# define TEST_MAP_NOLF(X) void X() { test_nolf::X >(); } +# define TEST_MAP_NOLF_EXTRACT(X) void X() { test_nolf_extract::X >(); } + + namespace { + struct key_thread + { + size_t nKey; + size_t nThread; + + key_thread( size_t key, size_t threadNo ) + : nKey( key ) + , nThread( threadNo ) + {} + + key_thread() + {} + }; + + //typedef MapTypes::key_val key_value_pair; + } + + template <> + struct cmp { + int operator ()(key_thread const& k1, key_thread const& k2) const + { + if ( k1.nKey < k2.nKey ) + return -1; + if ( k1.nKey > k2.nKey ) + return 1; + if ( k1.nThread < k2.nThread ) + return -1; + if ( k1.nThread > k2.nThread ) + return 1; + return 0; + } + int operator ()(key_thread const& k1, size_t k2) const + { + if ( k1.nKey < k2 ) + return -1; + if ( k1.nKey > k2 ) + return 1; + return 0; + } + int operator ()(size_t k1, key_thread const& k2) const + { + if ( k1 < k2.nKey ) + return -1; + if ( k1 > k2.nKey ) + return 1; + return 0; + } + }; + +} // namespace map2 + +namespace std { + template <> + struct less + { + bool operator()(map2::key_thread const& k1, map2::key_thread const& k2) const + { + if ( k1.nKey <= k2.nKey ) + return k1.nKey < k2.nKey || k1.nThread < k2.nThread; + return false; + } + }; + + template <> + struct hash + { + typedef size_t result_type; + typedef map2::key_thread argument_type; + + size_t operator()( map2::key_thread const& k ) const + { + return std::hash()(k.nKey); + } + size_t operator()( size_t k ) const + { + return std::hash()(k); + } + }; +} // namespace std + +namespace boost { + inline size_t hash_value( map2::key_thread const& k ) + { + return std::hash()( k.nKey ); + } + + template <> + struct hash + { + typedef size_t result_type; + typedef map2::key_thread argument_type; + + size_t operator()(map2::key_thread const& k) const + { + return boost::hash()( k.nKey ); + } + size_t operator()(size_t k) const + { + return boost::hash()( k ); + } + }; +} // namespace boost + +namespace map2 { + + class Map_DelOdd: public CppUnitMini::TestCase + { + static size_t c_nMapSize; // max map size + static size_t c_nInsThreadCount; // insert thread count + static size_t c_nDelThreadCount; // delete thread count + static size_t c_nExtractThreadCount; // extract thread count + static size_t c_nMaxLoadFactor; // maximum load factor + static bool c_bPrintGCState; + + std::vector m_arrData; + + protected: + typedef CppUnitMini::TestCase Base; + + typedef key_thread key_type; + typedef size_t value_type; + typedef std::pair pair_type; + + atomics::atomic m_nInsThreadCount; + + // Inserts keys from [0..N) + template + class InsertThread: public CppUnitMini::TestThread + { + Map& m_Map; + + virtual InsertThread * clone() + { + return new InsertThread( *this ); + } + + struct ensure_func + { + template + void operator()( bool /*bNew*/, Q const& ) + {} + template + void operator()( bool /*bNew*/, Q const&, V& ) + {} + }; + public: + size_t m_nInsertSuccess; + size_t m_nInsertFailed; + + public: + InsertThread( CppUnitMini::ThreadPool& pool, Map& rMap ) + : CppUnitMini::TestThread( pool ) + , m_Map( rMap ) + {} + InsertThread( InsertThread& src ) + : CppUnitMini::TestThread( src ) + , m_Map( src.m_Map ) + {} + + Map_DelOdd& getTest() + { + return reinterpret_cast( m_Pool.m_Test ); + } + + virtual void init() { cds::threading::Manager::attachThread() ; } + virtual void fini() { cds::threading::Manager::detachThread() ; } + + virtual void test() + { + Map& rMap = m_Map; + + m_nInsertSuccess = + m_nInsertFailed = 0; + + std::vector& arrData = getTest().m_arrData; + for ( size_t i = 0; i < arrData.size(); ++i ) { + if ( rMap.insert( key_type( arrData[i], m_nThreadNo ))) + ++m_nInsertSuccess; + else + ++m_nInsertFailed; + } + + ensure_func f; + for ( size_t i = arrData.size() - 1; i > 0; --i ) { + if ( arrData[i] & 1 ) { + rMap.ensure( key_type( arrData[i], m_nThreadNo ), f ); + } + } + + getTest().m_nInsThreadCount.fetch_sub( 1, atomics::memory_order_acquire ); + } + }; + + struct key_equal { + bool operator()( key_type const& k1, key_type const& k2 ) const + { + return k1.nKey == k2.nKey; + } + bool operator()( size_t k1, key_type const& k2 ) const + { + return k1 == k2.nKey; + } + bool operator()( key_type const& k1, size_t k2 ) const + { + return k1.nKey == k2; + } + }; + + struct key_less { + bool operator()( key_type const& k1, key_type const& k2 ) const + { + return k1.nKey < k2.nKey; + } + bool operator()( size_t k1, key_type const& k2 ) const + { + return k1 < k2.nKey; + } + bool operator()( key_type const& k1, size_t k2 ) const + { + return k1.nKey < k2; + } + + typedef key_equal equal_to; + }; + + // Deletes odd keys from [0..N) + template + class DeleteThread: public CppUnitMini::TestThread + { + Map& m_Map; + + virtual DeleteThread * clone() + { + return new DeleteThread( *this ); + } + public: + size_t m_nDeleteSuccess; + size_t m_nDeleteFailed; + + public: + DeleteThread( CppUnitMini::ThreadPool& pool, Map& rMap ) + : CppUnitMini::TestThread( pool ) + , m_Map( rMap ) + {} + DeleteThread( DeleteThread& src ) + : CppUnitMini::TestThread( src ) + , m_Map( src.m_Map ) + {} + + Map_DelOdd& getTest() + { + return reinterpret_cast( m_Pool.m_Test ); + } + + virtual void init() { cds::threading::Manager::attachThread() ; } + virtual void fini() { cds::threading::Manager::detachThread() ; } + + virtual void test() + { + Map& rMap = m_Map; + + m_nDeleteSuccess = + m_nDeleteFailed = 0; + + std::vector& arrData = getTest().m_arrData; + if ( m_nThreadNo & 1 ) { + for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { + for ( size_t i = 0; i < arrData.size(); ++i ) { + if ( arrData[i] & 1 ) { + if ( rMap.erase_with( arrData[i], key_less() )) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + } + } + if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) + break; + } + } + else { + for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { + for ( size_t i = arrData.size() - 1; i > 0; --i ) { + if ( arrData[i] & 1 ) { + if ( rMap.erase_with( arrData[i], key_less() )) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + } + } + if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) + break; + } + } + } + }; + + // Deletes odd keys from [0..N) + template + class ExtractThread: public CppUnitMini::TestThread + { + Map& m_Map; + + virtual ExtractThread * clone() + { + return new ExtractThread( *this ); + } + public: + size_t m_nDeleteSuccess; + size_t m_nDeleteFailed; + + public: + ExtractThread( CppUnitMini::ThreadPool& pool, Map& rMap ) + : CppUnitMini::TestThread( pool ) + , m_Map( rMap ) + {} + ExtractThread( ExtractThread& src ) + : CppUnitMini::TestThread( src ) + , m_Map( src.m_Map ) + {} + + Map_DelOdd& getTest() + { + return reinterpret_cast( m_Pool.m_Test ); + } + + virtual void init() { cds::threading::Manager::attachThread() ; } + virtual void fini() { cds::threading::Manager::detachThread() ; } + + virtual void test() + { + Map& rMap = m_Map; + + m_nDeleteSuccess = + m_nDeleteFailed = 0; + + typename Map::guarded_ptr gp; + + std::vector& arrData = getTest().m_arrData; + if ( m_nThreadNo & 1 ) { + for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { + for ( size_t i = 0; i < arrData.size(); ++i ) { + if ( arrData[i] & 1 ) { + gp = rMap.extract_with( arrData[i], key_less()); + if ( gp ) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + gp.release(); + } + } + if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) + break; + } + } + else { + for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { + for ( size_t i = arrData.size() - 1; i > 0; --i ) { + if ( arrData[i] & 1 ) { + gp = rMap.extract_with( arrData[i], key_less()); + if ( gp ) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + gp.release(); + } + } + if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) + break; + } + } + } + }; + + template + class ExtractThread< cds::urcu::gc, Map > : public CppUnitMini::TestThread + { + Map& m_Map; + + virtual ExtractThread * clone() + { + return new ExtractThread( *this ); + } + public: + size_t m_nDeleteSuccess; + size_t m_nDeleteFailed; + + public: + ExtractThread( CppUnitMini::ThreadPool& pool, Map& rMap ) + : CppUnitMini::TestThread( pool ) + , m_Map( rMap ) + {} + ExtractThread( ExtractThread& src ) + : CppUnitMini::TestThread( src ) + , m_Map( src.m_Map ) + {} + + Map_DelOdd& getTest() + { + return reinterpret_cast( m_Pool.m_Test ); + } + + virtual void init() { cds::threading::Manager::attachThread() ; } + virtual void fini() { cds::threading::Manager::detachThread() ; } + + virtual void test() + { + Map& rMap = m_Map; + + m_nDeleteSuccess = + m_nDeleteFailed = 0; + + typename Map::exempt_ptr xp; + + std::vector& arrData = getTest().m_arrData; + if ( m_nThreadNo & 1 ) { + for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { + for ( size_t i = 0; i < arrData.size(); ++i ) { + if ( arrData[i] & 1 ) { + if ( Map::c_bExtractLockExternal ) { + { + typename Map::rcu_lock l; + xp = rMap.extract_with( arrData[i], key_less() ); + if ( xp ) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + } + } + else { + xp = rMap.extract_with( arrData[i], key_less() ); + if ( xp ) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + } + xp.release(); + } + } + if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) + break; + } + } + else { + for ( size_t k = 0; k < c_nInsThreadCount; ++k ) { + for ( size_t i = arrData.size() - 1; i > 0; --i ) { + if ( arrData[i] & 1 ) { + if ( Map::c_bExtractLockExternal ) { + { + typename Map::rcu_lock l; + xp = rMap.extract_with( arrData[i], key_less() ); + if ( xp ) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + } + } + else { + xp = rMap.extract_with( arrData[i], key_less() ); + if ( xp ) + ++m_nDeleteSuccess; + else + ++m_nDeleteFailed; + } + xp.release(); + } + } + if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 ) + break; + } + } + } + }; + + protected: + template + void do_test( size_t nLoadFactor ) + { + Map testMap( c_nMapSize, nLoadFactor ); + do_test_with( testMap ); + } + + template + void do_test_extract( size_t nLoadFactor ) + { + Map testMap( c_nMapSize, nLoadFactor ); + do_test_extract_with( testMap ); + } + + template + void do_test_with( Map& testMap ) + { + typedef InsertThread insert_thread; + typedef DeleteThread delete_thread; + + m_nInsThreadCount.store( c_nInsThreadCount, atomics::memory_order_release ); + + CppUnitMini::ThreadPool pool( *this ); + pool.add( new insert_thread( pool, testMap ), c_nInsThreadCount ); + pool.add( new delete_thread( pool, testMap ), c_nDelThreadCount ? c_nDelThreadCount : cds::OS::topology::processor_count()); + pool.run(); + CPPUNIT_MSG( " Duration=" << pool.avgDuration() ); + + size_t nInsertSuccess = 0; + size_t nInsertFailed = 0; + size_t nDeleteSuccess = 0; + size_t nDeleteFailed = 0; + for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) { + insert_thread * pThread = dynamic_cast( *it ); + if ( pThread ) { + nInsertSuccess += pThread->m_nInsertSuccess; + nInsertFailed += pThread->m_nInsertFailed; + } + else { + delete_thread * p = static_cast( *it ); + nDeleteSuccess += p->m_nDeleteSuccess; + nDeleteFailed += p->m_nDeleteFailed; + } + } + + CPPUNIT_MSG( " Totals (success/failed): \n\t" + << " Insert=" << nInsertSuccess << '/' << nInsertFailed << "\n\t" + << " Delete=" << nDeleteSuccess << '/' << nDeleteFailed << "\n\t" + ); + CPPUNIT_CHECK( nInsertSuccess == c_nMapSize * c_nInsThreadCount ); + CPPUNIT_CHECK( nInsertFailed == 0 ); + + analyze( testMap ); + } + + template + void do_test_extract_with( Map& testMap ) + { + typedef InsertThread insert_thread; + typedef DeleteThread delete_thread; + typedef ExtractThread< typename Map::gc, Map > extract_thread; + + m_nInsThreadCount.store( c_nInsThreadCount, atomics::memory_order_release ); + + CppUnitMini::ThreadPool pool( *this ); + pool.add( new insert_thread( pool, testMap ), c_nInsThreadCount ); + if ( c_nDelThreadCount ) + pool.add( new delete_thread( pool, testMap ), c_nDelThreadCount ); + if ( c_nExtractThreadCount ) + pool.add( new extract_thread( pool, testMap ), c_nExtractThreadCount ); + pool.run(); + CPPUNIT_MSG( " Duration=" << pool.avgDuration() ); + + size_t nInsertSuccess = 0; + size_t nInsertFailed = 0; + size_t nDeleteSuccess = 0; + size_t nDeleteFailed = 0; + size_t nExtractSuccess = 0; + size_t nExtractFailed = 0; + for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) { + insert_thread * pThread = dynamic_cast( *it ); + if ( pThread ) { + nInsertSuccess += pThread->m_nInsertSuccess; + nInsertFailed += pThread->m_nInsertFailed; + } + else { + delete_thread * p = dynamic_cast( *it ); + if ( p ) { + nDeleteSuccess += p->m_nDeleteSuccess; + nDeleteFailed += p->m_nDeleteFailed; + } + else { + extract_thread * pExtract = dynamic_cast( *it ); + assert( pExtract ); + nExtractSuccess += pExtract->m_nDeleteSuccess; + nExtractFailed += pExtract->m_nDeleteFailed; + } + } + } + + CPPUNIT_MSG( " Totals (success/failed): \n\t" + << " Insert=" << nInsertSuccess << '/' << nInsertFailed << "\n\t" + << " Delete=" << nDeleteSuccess << '/' << nDeleteFailed << "\n\t" + << " Extract=" << nExtractSuccess << '/' << nExtractFailed << "\n\t" + ); + CPPUNIT_CHECK( nInsertSuccess == c_nMapSize * c_nInsThreadCount ); + CPPUNIT_CHECK( nInsertFailed == 0 ); + + analyze( testMap ); + } + + template + void analyze( Map& testMap ) + { + cds::OS::Timer timer; + + // All even keys must be in the map + { + size_t nErrorCount = 0; + CPPUNIT_MSG( " Check even keys..." ); + for ( size_t n = 0; n < c_nMapSize; n +=2 ) { + for ( size_t i = 0; i < c_nInsThreadCount; ++i ) { + if ( !testMap.find( key_type(n, i) ) ) { + if ( ++nErrorCount < 10 ) { + CPPUNIT_MSG( "key " << n << "-" << i << " is not found!"); + } + } + } + } + CPPUNIT_CHECK_EX( nErrorCount == 0, "Totals: " << nErrorCount << " keys is not found"); + } + + check_before_cleanup( testMap ); + + CPPUNIT_MSG( " Clear map (single-threaded)..." ); + timer.reset(); + testMap.clear(); + CPPUNIT_MSG( " Duration=" << timer.duration() ); + CPPUNIT_CHECK_EX( testMap.empty(), ((long long) testMap.size()) ); + + additional_check( testMap ); + print_stat( testMap ); + + additional_cleanup( testMap ); + } + + + template + void test() + { + CPPUNIT_MSG( "Insert thread count=" << c_nInsThreadCount + << " delete thread count=" << c_nDelThreadCount + << " set size=" << c_nMapSize + ); + + for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) { + CPPUNIT_MSG( "Load factor=" << nLoadFactor ); + do_test( nLoadFactor ); + if ( c_bPrintGCState ) + print_gc_state(); + } + } + + template + void test_extract() + { + CPPUNIT_MSG( "Thread count: insert=" << c_nInsThreadCount + << ", delete=" << c_nDelThreadCount + << ", extract=" << c_nExtractThreadCount + << "; set size=" << c_nMapSize + ); + + for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) { + CPPUNIT_MSG( "Load factor=" << nLoadFactor ); + do_test_extract( nLoadFactor ); + if ( c_bPrintGCState ) + print_gc_state(); + } + } + + template + void test_nolf() + { + CPPUNIT_MSG( "Insert thread count=" << c_nInsThreadCount + << " delete thread count=" << c_nDelThreadCount + << " set size=" << c_nMapSize + ); + + Map s; + do_test_with( s ); + if ( c_bPrintGCState ) + print_gc_state(); + } + + template + void test_nolf_extract() + { + CPPUNIT_MSG( "Thread count: insert=" << c_nInsThreadCount + << ", delete=" << c_nDelThreadCount + << ", extract=" << c_nExtractThreadCount + << "; set size=" << c_nMapSize + ); + + Map s; + do_test_extract_with( s ); + if ( c_bPrintGCState ) + print_gc_state(); + } + + void setUpParams( const CppUnitMini::TestCfg& cfg ); + + void run_MichaelMap(const char *in_name, bool invert = false); + void run_SplitList(const char *in_name, bool invert = false); + //void run_StripedMap(const char *in_name, bool invert = false); + //void run_RefinableMap(const char *in_name, bool invert = false); + void run_CuckooMap(const char *in_name, bool invert = false); + void run_SkipListMap(const char *in_name, bool invert = false); + void run_EllenBinTreeMap(const char *in_name, bool invert = false); + void run_BronsonAVLTreeMap(const char *in_name, bool invert = false); + //void run_StdMap(const char *in_name, bool invert = false); + + virtual void myRun(const char *in_name, bool invert = false); + +# include "map2/map_defs.h" + CDSUNIT_DECLARE_MichaelMap + CDSUNIT_DECLARE_SplitList + //CDSUNIT_DECLARE_StripedMap + //CDSUNIT_DECLARE_RefinableMap + CDSUNIT_DECLARE_CuckooMap + CDSUNIT_DECLARE_SkipListMap + CDSUNIT_DECLARE_EllenBinTreeMap + CDSUNIT_DECLARE_BronsonAVLTreeMap + //CDSUNIT_DECLARE_StdMap + }; +} // namespace map2 diff --git a/tests/unit/map2/map_delodd_bronsonavltree.cpp b/tests/unit/map2/map_delodd_bronsonavltree.cpp new file mode 100644 index 00000000..0448891b --- /dev/null +++ b/tests/unit/map2/map_delodd_bronsonavltree.cpp @@ -0,0 +1,9 @@ +//$$CDS-header$$ + +#include "map2/map_delodd.h" + +namespace map2 { + CPPUNIT_TEST_SUITE_PART( Map_DelOdd, run_BronsonAVLTreeMap ) + CDSUNIT_TEST_BronsonAVLTreeMap + CPPUNIT_TEST_SUITE_END_PART() +} // namespace map2 diff --git a/tests/unit/map2/map_delodd_cuckoo.cpp b/tests/unit/map2/map_delodd_cuckoo.cpp new file mode 100644 index 00000000..191d35a9 --- /dev/null +++ b/tests/unit/map2/map_delodd_cuckoo.cpp @@ -0,0 +1,9 @@ +//$$CDS-header$$ + +#include "map2/map_delodd.h" + +namespace map2 { + CPPUNIT_TEST_SUITE_PART( Map_DelOdd, run_CuckooMap ) + CDSUNIT_TEST_CuckooMap + CPPUNIT_TEST_SUITE_END_PART() +} // namespace map2 diff --git a/tests/unit/map2/map_delodd_ellentree.cpp b/tests/unit/map2/map_delodd_ellentree.cpp new file mode 100644 index 00000000..e6883aa4 --- /dev/null +++ b/tests/unit/map2/map_delodd_ellentree.cpp @@ -0,0 +1,9 @@ +//$$CDS-header$$ + +#include "map2/map_delodd.h" + +namespace map2 { + CPPUNIT_TEST_SUITE_PART( Map_DelOdd, run_EllenBinTreeMap ) + CDSUNIT_TEST_EllenBinTreeMap + CPPUNIT_TEST_SUITE_END_PART() +} // namespace map2 diff --git a/tests/unit/map2/map_delodd_michael.cpp b/tests/unit/map2/map_delodd_michael.cpp new file mode 100644 index 00000000..c114aed0 --- /dev/null +++ b/tests/unit/map2/map_delodd_michael.cpp @@ -0,0 +1,9 @@ +//$$CDS-header$$ + +#include "map2/map_delodd.h" + +namespace map2 { + CPPUNIT_TEST_SUITE_PART( Map_DelOdd, run_MichaelMap ) + CDSUNIT_TEST_MichaelMap + CPPUNIT_TEST_SUITE_END_PART() +} // namespace map2 diff --git a/tests/unit/map2/map_delodd_skip.cpp b/tests/unit/map2/map_delodd_skip.cpp new file mode 100644 index 00000000..bb92b6d7 --- /dev/null +++ b/tests/unit/map2/map_delodd_skip.cpp @@ -0,0 +1,9 @@ +//$$CDS-header$$ + +#include "map2/map_delodd.h" + +namespace map2 { + CPPUNIT_TEST_SUITE_PART( Map_DelOdd, run_SkipListMap ) + CDSUNIT_TEST_SkipListMap + CPPUNIT_TEST_SUITE_END_PART() +} // namespace map2 diff --git a/tests/unit/map2/map_delodd_split.cpp b/tests/unit/map2/map_delodd_split.cpp new file mode 100644 index 00000000..b8895cb7 --- /dev/null +++ b/tests/unit/map2/map_delodd_split.cpp @@ -0,0 +1,9 @@ +//$$CDS-header$$ + +#include "map2/map_delodd.h" + +namespace map2 { + CPPUNIT_TEST_SUITE_PART( Map_DelOdd, run_SplitList ) + CDSUNIT_TEST_SplitList + CPPUNIT_TEST_SUITE_END_PART() +} // namespace map2 diff --git a/tests/unit/map2/map_insdel_func.cpp b/tests/unit/map2/map_insdel_func.cpp index 6232125a..6898d390 100644 --- a/tests/unit/map2/map_insdel_func.cpp +++ b/tests/unit/map2/map_insdel_func.cpp @@ -46,8 +46,4 @@ namespace map2 { endTestCase(); } - - CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_MichaelMap ) - CDSUNIT_TEST_MichaelMap - CPPUNIT_TEST_SUITE_END_PART() } // namespace map2 diff --git a/tests/unit/map2/map_insdel_func5.cpp b/tests/unit/map2/map_insdel_func_bronsonavltree.cpp similarity index 100% rename from tests/unit/map2/map_insdel_func5.cpp rename to tests/unit/map2/map_insdel_func_bronsonavltree.cpp diff --git a/tests/unit/map2/map_insdel_func8.cpp b/tests/unit/map2/map_insdel_func_cuckoo.cpp similarity index 100% rename from tests/unit/map2/map_insdel_func8.cpp rename to tests/unit/map2/map_insdel_func_cuckoo.cpp diff --git a/tests/unit/map2/map_insdel_func4.cpp b/tests/unit/map2/map_insdel_func_ellentree.cpp similarity index 100% rename from tests/unit/map2/map_insdel_func4.cpp rename to tests/unit/map2/map_insdel_func_ellentree.cpp diff --git a/tests/unit/map2/map_insdel_func_michael.cpp b/tests/unit/map2/map_insdel_func_michael.cpp new file mode 100644 index 00000000..41e1a7cf --- /dev/null +++ b/tests/unit/map2/map_insdel_func_michael.cpp @@ -0,0 +1,9 @@ +//$$CDS-header$$ + +#include "map2/map_insdel_func.h" + +namespace map2 { + CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_MichaelMap ) + CDSUNIT_TEST_MichaelMap + CPPUNIT_TEST_SUITE_END_PART() +} // namespace map2 diff --git a/tests/unit/map2/map_insdel_func7.cpp b/tests/unit/map2/map_insdel_func_refinable.cpp similarity index 100% rename from tests/unit/map2/map_insdel_func7.cpp rename to tests/unit/map2/map_insdel_func_refinable.cpp diff --git a/tests/unit/map2/map_insdel_func3.cpp b/tests/unit/map2/map_insdel_func_skip.cpp similarity index 100% rename from tests/unit/map2/map_insdel_func3.cpp rename to tests/unit/map2/map_insdel_func_skip.cpp diff --git a/tests/unit/map2/map_insdel_func2.cpp b/tests/unit/map2/map_insdel_func_split.cpp similarity index 100% rename from tests/unit/map2/map_insdel_func2.cpp rename to tests/unit/map2/map_insdel_func_split.cpp diff --git a/tests/unit/map2/map_insdel_func6.cpp b/tests/unit/map2/map_insdel_func_striped.cpp similarity index 100% rename from tests/unit/map2/map_insdel_func6.cpp rename to tests/unit/map2/map_insdel_func_striped.cpp -- 2.34.1