3 #include "set2/set_type.h"
4 #include "cppunit/thread.h"
10 #define TEST_CASE(TAG, X) void X();
12 class Set_InsDel_string: public CppUnitMini::TestCase
15 size_t c_nSetSize = 1000000; // set size
16 size_t c_nInsertThreadCount = 4; // count of insertion thread
17 size_t c_nDeleteThreadCount = 4; // count of deletion thread
18 size_t c_nThreadPassCount = 4; // pass count for each thread
19 size_t c_nMaxLoadFactor = 8; // maximum load factor
20 bool c_bPrintGCState = true;
22 size_t c_nCuckooInitialSize = 1024;// initial size for CuckooSet
23 size_t c_nCuckooProbesetSize = 16; // CuckooSet probeset size (only for list-based probeset)
24 size_t c_nCuckooProbesetThreshold = 0; // CUckooSet probeset threshold (0 - use default)
26 size_t c_nLoadFactor = 2;
29 typedef CppUnitMini::TestCase Base;
30 typedef std::string key_type;
31 typedef size_t value_type;
33 const std::vector<std::string> * m_parrString;
36 class Inserter: public CppUnitMini::TestThread
39 typedef typename Set::value_type keyval_type;
41 virtual Inserter * clone()
43 return new Inserter( *this );
46 size_t m_nInsertSuccess;
47 size_t m_nInsertFailed;
50 Inserter( CppUnitMini::ThreadPool& pool, Set& rSet )
51 : CppUnitMini::TestThread( pool )
54 Inserter( Inserter& src )
55 : CppUnitMini::TestThread( src )
59 Set_InsDel_string& getTest()
61 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
64 virtual void init() { cds::threading::Manager::attachThread() ; }
65 virtual void fini() { cds::threading::Manager::detachThread() ; }
74 const std::vector<std::string>& arrString = *getTest().m_parrString;
75 size_t nArrSize = arrString.size();
76 size_t const nSetSize = getTest().c_nSetSize;
77 size_t const nPassCount = getTest().c_nThreadPassCount;
79 if ( m_nThreadNo & 1 ) {
80 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
81 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
82 if ( rSet.insert( keyval_type(arrString[nItem % nArrSize], nItem * 8) ) )
90 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
91 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
92 if ( rSet.insert( keyval_type( arrString[nItem % nArrSize], nItem * 8) ) )
103 class Deleter: public CppUnitMini::TestThread
107 virtual Deleter * clone()
109 return new Deleter( *this );
112 size_t m_nDeleteSuccess;
113 size_t m_nDeleteFailed;
116 Deleter( CppUnitMini::ThreadPool& pool, Set& rSet )
117 : CppUnitMini::TestThread( pool )
120 Deleter( Deleter& src )
121 : CppUnitMini::TestThread( src )
125 Set_InsDel_string& getTest()
127 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
130 virtual void init() { cds::threading::Manager::attachThread() ; }
131 virtual void fini() { cds::threading::Manager::detachThread() ; }
140 const std::vector<std::string>& arrString = *getTest().m_parrString;
141 size_t nArrSize = arrString.size();
142 size_t const nSetSize = getTest().c_nSetSize;
143 size_t const nPassCount = getTest().c_nThreadPassCount;
145 if ( m_nThreadNo & 1 ) {
146 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
147 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
148 if ( rSet.erase( arrString[nItem % nArrSize] ) )
156 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
157 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
158 if ( rSet.erase( arrString[nItem % nArrSize] ) )
168 template <typename GC, class Set>
169 class Extractor: public CppUnitMini::TestThread
173 virtual Extractor * clone()
175 return new Extractor( *this );
178 size_t m_nDeleteSuccess;
179 size_t m_nDeleteFailed;
182 Extractor( CppUnitMini::ThreadPool& pool, Set& rSet )
183 : CppUnitMini::TestThread( pool )
186 Extractor( Extractor& src )
187 : CppUnitMini::TestThread( src )
191 Set_InsDel_string& getTest()
193 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
196 virtual void init() { cds::threading::Manager::attachThread() ; }
197 virtual void fini() { cds::threading::Manager::detachThread() ; }
206 typename Set::guarded_ptr gp;
208 const std::vector<std::string>& arrString = *getTest().m_parrString;
209 size_t nArrSize = arrString.size();
210 size_t const nSetSize = getTest().c_nSetSize;
211 size_t const nPassCount = getTest().c_nThreadPassCount;
213 if ( m_nThreadNo & 1 ) {
214 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
215 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
216 gp = rSet.extract( arrString[nItem % nArrSize]);
226 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
227 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
228 gp = rSet.extract( arrString[nItem % nArrSize]);
240 template <typename RCU, class Set>
241 class Extractor<cds::urcu::gc<RCU>, Set >: public CppUnitMini::TestThread
245 virtual Extractor * clone()
247 return new Extractor( *this );
250 size_t m_nDeleteSuccess;
251 size_t m_nDeleteFailed;
254 Extractor( CppUnitMini::ThreadPool& pool, Set& rSet )
255 : CppUnitMini::TestThread( pool )
258 Extractor( Extractor& src )
259 : CppUnitMini::TestThread( src )
263 Set_InsDel_string& getTest()
265 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
268 virtual void init() { cds::threading::Manager::attachThread() ; }
269 virtual void fini() { cds::threading::Manager::detachThread() ; }
278 typename Set::exempt_ptr xp;
280 const std::vector<std::string>& arrString = *getTest().m_parrString;
281 size_t nArrSize = arrString.size();
282 size_t const nSetSize = getTest().c_nSetSize;
283 size_t const nPassCount = getTest().c_nThreadPassCount;
285 if ( m_nThreadNo & 1 ) {
286 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
287 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
288 if ( Set::c_bExtractLockExternal ) {
290 typename Set::rcu_lock l;
291 xp = rSet.extract( arrString[nItem % nArrSize] );
299 xp = rSet.extract( arrString[nItem % nArrSize] );
310 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
311 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
312 if ( Set::c_bExtractLockExternal ) {
314 typename Set::rcu_lock l;
315 xp = rSet.extract( arrString[nItem % nArrSize] );
323 xp = rSet.extract( arrString[nItem % nArrSize] );
338 void do_test( Set& testSet )
340 typedef Inserter<Set> InserterThread;
341 typedef Deleter<Set> DeleterThread;
342 cds::OS::Timer timer;
344 CppUnitMini::ThreadPool pool( *this );
345 pool.add( new InserterThread( pool, testSet ), c_nInsertThreadCount );
346 pool.add( new DeleterThread( pool, testSet ), c_nDeleteThreadCount );
348 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
350 size_t nInsertSuccess = 0;
351 size_t nInsertFailed = 0;
352 size_t nDeleteSuccess = 0;
353 size_t nDeleteFailed = 0;
354 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
355 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
357 nInsertSuccess += pThread->m_nInsertSuccess;
358 nInsertFailed += pThread->m_nInsertFailed;
361 DeleterThread * p = static_cast<DeleterThread *>( *it );
362 nDeleteSuccess += p->m_nDeleteSuccess;
363 nDeleteFailed += p->m_nDeleteFailed;
367 CPPUNIT_MSG( " Totals: Ins succ=" << nInsertSuccess
368 << " Del succ=" << nDeleteSuccess << "\n"
369 << " : Ins fail=" << nInsertFailed
370 << " Del fail=" << nDeleteFailed
371 << " Set size=" << testSet.size()
375 CPPUNIT_MSG( " Clear set (single-threaded)..." );
377 for ( size_t i = 0; i < m_parrString->size(); ++i )
378 testSet.erase( (*m_parrString)[i] );
379 CPPUNIT_MSG( " Duration=" << timer.duration() );
380 CPPUNIT_ASSERT( testSet.empty() );
382 additional_check( testSet );
383 print_stat( testSet );
384 additional_cleanup( testSet );
388 void do_test_extract( Set& testSet )
390 typedef Inserter<Set> InserterThread;
391 typedef Deleter<Set> DeleterThread;
392 typedef Extractor<typename Set::gc, Set> ExtractThread;
394 size_t nDelThreadCount = c_nDeleteThreadCount / 2;
396 CppUnitMini::ThreadPool pool( *this );
397 pool.add( new InserterThread( pool, testSet ), c_nInsertThreadCount );
398 pool.add( new DeleterThread( pool, testSet ), nDelThreadCount );
399 pool.add( new ExtractThread( pool, testSet ), c_nDeleteThreadCount - nDelThreadCount );
401 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
403 size_t nInsertSuccess = 0;
404 size_t nInsertFailed = 0;
405 size_t nDeleteSuccess = 0;
406 size_t nDeleteFailed = 0;
407 size_t nExtractSuccess = 0;
408 size_t nExtractFailed = 0;
409 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
410 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
412 nInsertSuccess += pThread->m_nInsertSuccess;
413 nInsertFailed += pThread->m_nInsertFailed;
416 DeleterThread * p = dynamic_cast<DeleterThread *>( *it );
418 nDeleteSuccess += p->m_nDeleteSuccess;
419 nDeleteFailed += p->m_nDeleteFailed;
422 ExtractThread * pExtract = dynamic_cast<ExtractThread *>( *it );
424 nExtractSuccess += pExtract->m_nDeleteSuccess;
425 nExtractFailed += pExtract->m_nDeleteFailed;
430 CPPUNIT_MSG( " Totals: Ins succ=" << nInsertSuccess
431 << " Del succ=" << nDeleteSuccess
432 << " Extract succ= " << nExtractSuccess << "\n"
433 << " : Ins fail=" << nInsertFailed
434 << " Del fail=" << nDeleteFailed
435 << " Extract fail=" << nExtractFailed
436 << " Set size=" << testSet.size()
440 CPPUNIT_MSG( " Clear set (single-threaded)..." );
441 cds::OS::Timer timer;
442 for ( size_t i = 0; i < m_parrString->size(); ++i )
443 testSet.erase( (*m_parrString)[i] );
444 CPPUNIT_MSG( " Duration=" << timer.duration() );
445 CPPUNIT_ASSERT( testSet.empty() );
447 additional_check( testSet );
448 print_stat( testSet );
449 additional_cleanup( testSet );
455 m_parrString = &CppUnitMini::TestCase::getTestStrings();
457 CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
458 << " delete=" << c_nDeleteThreadCount
459 << " pass count=" << c_nThreadPassCount
460 << " set size=" << c_nSetSize
463 if ( Set::c_bLoadFactorDepended ) {
464 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
465 CPPUNIT_MSG(" LoadFactor = " << c_nLoadFactor );
468 if ( c_bPrintGCState )
475 if ( c_bPrintGCState )
481 void run_test_extract()
483 m_parrString = &CppUnitMini::TestCase::getTestStrings();
485 CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
486 << " delete=" << c_nDeleteThreadCount
487 << " pass count=" << c_nThreadPassCount
488 << " set size=" << c_nSetSize
491 if ( Set::c_bLoadFactorDepended ) {
492 for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
493 CPPUNIT_MSG(" LoadFactor = " << c_nLoadFactor );
495 do_test_extract( s );
496 if ( c_bPrintGCState )
502 do_test_extract( s );
503 if ( c_bPrintGCState )
508 void setUpParams( const CppUnitMini::TestCfg& cfg );
510 # include "set2/set_defs.h"
511 CDSUNIT_DECLARE_MichaelSet
512 CDSUNIT_DECLARE_SplitList
513 CDSUNIT_DECLARE_StripedSet
514 CDSUNIT_DECLARE_RefinableSet
515 CDSUNIT_DECLARE_CuckooSet
516 CDSUNIT_DECLARE_SkipListSet
517 CDSUNIT_DECLARE_EllenBinTreeSet
518 CDSUNIT_DECLARE_MultiLevelHashSet
519 CDSUNIT_DECLARE_StdSet
521 CPPUNIT_TEST_SUITE_(Set_InsDel_string, "Map_InsDel_func")
522 CDSUNIT_TEST_MichaelSet
523 CDSUNIT_TEST_SplitList
524 CDSUNIT_TEST_SkipListSet
525 CDSUNIT_TEST_MultiLevelHashSet
526 CDSUNIT_TEST_EllenBinTreeSet
527 CDSUNIT_TEST_StripedSet
528 CDSUNIT_TEST_RefinableSet
529 CDSUNIT_TEST_CuckooSet
531 CPPUNIT_TEST_SUITE_END();