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_nMultiLevelSet_HeadBits = 10;
27 size_t c_nMultiLevelSet_ArrayBits = 4;
29 size_t c_nLoadFactor = 2;
32 typedef CppUnitMini::TestCase Base;
33 typedef std::string key_type;
34 typedef size_t value_type;
36 const std::vector<std::string> * m_parrString;
39 class Inserter: public CppUnitMini::TestThread
42 typedef typename Set::value_type keyval_type;
44 virtual Inserter * clone()
46 return new Inserter( *this );
49 size_t m_nInsertSuccess;
50 size_t m_nInsertFailed;
53 Inserter( CppUnitMini::ThreadPool& pool, Set& rSet )
54 : CppUnitMini::TestThread( pool )
57 Inserter( Inserter& src )
58 : CppUnitMini::TestThread( src )
62 Set_InsDel_string& getTest()
64 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
67 virtual void init() { cds::threading::Manager::attachThread() ; }
68 virtual void fini() { cds::threading::Manager::detachThread() ; }
77 const std::vector<std::string>& arrString = *getTest().m_parrString;
78 size_t nArrSize = arrString.size();
79 size_t const nSetSize = getTest().c_nSetSize;
80 size_t const nPassCount = getTest().c_nThreadPassCount;
82 if ( m_nThreadNo & 1 ) {
83 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
84 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
85 if ( rSet.insert( keyval_type(arrString[nItem % nArrSize], nItem * 8) ) )
93 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
94 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
95 if ( rSet.insert( keyval_type( arrString[nItem % nArrSize], nItem * 8) ) )
106 class Deleter: public CppUnitMini::TestThread
110 virtual Deleter * clone()
112 return new Deleter( *this );
115 size_t m_nDeleteSuccess;
116 size_t m_nDeleteFailed;
119 Deleter( CppUnitMini::ThreadPool& pool, Set& rSet )
120 : CppUnitMini::TestThread( pool )
123 Deleter( Deleter& src )
124 : CppUnitMini::TestThread( src )
128 Set_InsDel_string& getTest()
130 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
133 virtual void init() { cds::threading::Manager::attachThread() ; }
134 virtual void fini() { cds::threading::Manager::detachThread() ; }
143 const std::vector<std::string>& arrString = *getTest().m_parrString;
144 size_t nArrSize = arrString.size();
145 size_t const nSetSize = getTest().c_nSetSize;
146 size_t const nPassCount = getTest().c_nThreadPassCount;
148 if ( m_nThreadNo & 1 ) {
149 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
150 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
151 if ( rSet.erase( arrString[nItem % nArrSize] ) )
159 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
160 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
161 if ( rSet.erase( arrString[nItem % nArrSize] ) )
171 template <typename GC, class Set>
172 class Extractor: public CppUnitMini::TestThread
176 virtual Extractor * clone()
178 return new Extractor( *this );
181 size_t m_nDeleteSuccess;
182 size_t m_nDeleteFailed;
185 Extractor( CppUnitMini::ThreadPool& pool, Set& rSet )
186 : CppUnitMini::TestThread( pool )
189 Extractor( Extractor& src )
190 : CppUnitMini::TestThread( src )
194 Set_InsDel_string& getTest()
196 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
199 virtual void init() { cds::threading::Manager::attachThread() ; }
200 virtual void fini() { cds::threading::Manager::detachThread() ; }
209 typename Set::guarded_ptr gp;
211 const std::vector<std::string>& arrString = *getTest().m_parrString;
212 size_t nArrSize = arrString.size();
213 size_t const nSetSize = getTest().c_nSetSize;
214 size_t const nPassCount = getTest().c_nThreadPassCount;
216 if ( m_nThreadNo & 1 ) {
217 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
218 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
219 gp = rSet.extract( arrString[nItem % nArrSize]);
229 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
230 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
231 gp = rSet.extract( arrString[nItem % nArrSize]);
243 template <typename RCU, class Set>
244 class Extractor<cds::urcu::gc<RCU>, Set >: public CppUnitMini::TestThread
248 virtual Extractor * clone()
250 return new Extractor( *this );
253 size_t m_nDeleteSuccess;
254 size_t m_nDeleteFailed;
257 Extractor( CppUnitMini::ThreadPool& pool, Set& rSet )
258 : CppUnitMini::TestThread( pool )
261 Extractor( Extractor& src )
262 : CppUnitMini::TestThread( src )
266 Set_InsDel_string& getTest()
268 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
271 virtual void init() { cds::threading::Manager::attachThread() ; }
272 virtual void fini() { cds::threading::Manager::detachThread() ; }
281 typename Set::exempt_ptr xp;
283 const std::vector<std::string>& arrString = *getTest().m_parrString;
284 size_t nArrSize = arrString.size();
285 size_t const nSetSize = getTest().c_nSetSize;
286 size_t const nPassCount = getTest().c_nThreadPassCount;
288 if ( m_nThreadNo & 1 ) {
289 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
290 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
291 if ( Set::c_bExtractLockExternal ) {
293 typename Set::rcu_lock l;
294 xp = rSet.extract( arrString[nItem % nArrSize] );
302 xp = rSet.extract( arrString[nItem % nArrSize] );
313 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
314 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
315 if ( Set::c_bExtractLockExternal ) {
317 typename Set::rcu_lock l;
318 xp = rSet.extract( arrString[nItem % nArrSize] );
326 xp = rSet.extract( arrString[nItem % nArrSize] );
341 void do_test( Set& testSet )
343 typedef Inserter<Set> InserterThread;
344 typedef Deleter<Set> DeleterThread;
345 cds::OS::Timer timer;
347 CppUnitMini::ThreadPool pool( *this );
348 pool.add( new InserterThread( pool, testSet ), c_nInsertThreadCount );
349 pool.add( new DeleterThread( pool, testSet ), c_nDeleteThreadCount );
351 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
353 size_t nInsertSuccess = 0;
354 size_t nInsertFailed = 0;
355 size_t nDeleteSuccess = 0;
356 size_t nDeleteFailed = 0;
357 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
358 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
360 nInsertSuccess += pThread->m_nInsertSuccess;
361 nInsertFailed += pThread->m_nInsertFailed;
364 DeleterThread * p = static_cast<DeleterThread *>( *it );
365 nDeleteSuccess += p->m_nDeleteSuccess;
366 nDeleteFailed += p->m_nDeleteFailed;
370 CPPUNIT_MSG( " Totals: Ins succ=" << nInsertSuccess
371 << " Del succ=" << nDeleteSuccess << "\n"
372 << " : Ins fail=" << nInsertFailed
373 << " Del fail=" << nDeleteFailed
374 << " Set size=" << testSet.size()
378 CPPUNIT_MSG( " Clear set (single-threaded)..." );
380 for ( size_t i = 0; i < m_parrString->size(); ++i )
381 testSet.erase( (*m_parrString)[i] );
382 CPPUNIT_MSG( " Duration=" << timer.duration() );
383 CPPUNIT_ASSERT( testSet.empty() );
385 additional_check( testSet );
386 print_stat( testSet );
387 additional_cleanup( testSet );
391 void do_test_extract( Set& testSet )
393 typedef Inserter<Set> InserterThread;
394 typedef Deleter<Set> DeleterThread;
395 typedef Extractor<typename Set::gc, Set> ExtractThread;
397 size_t nDelThreadCount = c_nDeleteThreadCount / 2;
399 CppUnitMini::ThreadPool pool( *this );
400 pool.add( new InserterThread( pool, testSet ), c_nInsertThreadCount );
401 pool.add( new DeleterThread( pool, testSet ), nDelThreadCount );
402 pool.add( new ExtractThread( pool, testSet ), c_nDeleteThreadCount - nDelThreadCount );
404 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
406 size_t nInsertSuccess = 0;
407 size_t nInsertFailed = 0;
408 size_t nDeleteSuccess = 0;
409 size_t nDeleteFailed = 0;
410 size_t nExtractSuccess = 0;
411 size_t nExtractFailed = 0;
412 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
413 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
415 nInsertSuccess += pThread->m_nInsertSuccess;
416 nInsertFailed += pThread->m_nInsertFailed;
419 DeleterThread * p = dynamic_cast<DeleterThread *>( *it );
421 nDeleteSuccess += p->m_nDeleteSuccess;
422 nDeleteFailed += p->m_nDeleteFailed;
425 ExtractThread * pExtract = dynamic_cast<ExtractThread *>( *it );
427 nExtractSuccess += pExtract->m_nDeleteSuccess;
428 nExtractFailed += pExtract->m_nDeleteFailed;
433 CPPUNIT_MSG( " Totals: Ins succ=" << nInsertSuccess
434 << " Del succ=" << nDeleteSuccess
435 << " Extract succ= " << nExtractSuccess << "\n"
436 << " : Ins fail=" << nInsertFailed
437 << " Del fail=" << nDeleteFailed
438 << " Extract fail=" << nExtractFailed
439 << " Set size=" << testSet.size()
443 CPPUNIT_MSG( " Clear set (single-threaded)..." );
444 cds::OS::Timer timer;
445 for ( size_t i = 0; i < m_parrString->size(); ++i )
446 testSet.erase( (*m_parrString)[i] );
447 CPPUNIT_MSG( " Duration=" << timer.duration() );
448 CPPUNIT_ASSERT( testSet.empty() );
450 additional_check( testSet );
451 print_stat( testSet );
452 additional_cleanup( testSet );
458 m_parrString = &CppUnitMini::TestCase::getTestStrings();
460 CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
461 << " delete=" << c_nDeleteThreadCount
462 << " pass count=" << c_nThreadPassCount
463 << " set size=" << c_nSetSize
466 if ( Set::c_bLoadFactorDepended ) {
467 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
468 CPPUNIT_MSG(" LoadFactor = " << c_nLoadFactor );
471 if ( c_bPrintGCState )
478 if ( c_bPrintGCState )
484 void run_test_extract()
486 m_parrString = &CppUnitMini::TestCase::getTestStrings();
488 CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
489 << " delete=" << c_nDeleteThreadCount
490 << " pass count=" << c_nThreadPassCount
491 << " set size=" << c_nSetSize
494 if ( Set::c_bLoadFactorDepended ) {
495 for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
496 CPPUNIT_MSG(" LoadFactor = " << c_nLoadFactor );
498 do_test_extract( s );
499 if ( c_bPrintGCState )
505 do_test_extract( s );
506 if ( c_bPrintGCState )
511 void setUpParams( const CppUnitMini::TestCfg& cfg );
513 # include "set2/set_defs.h"
514 CDSUNIT_DECLARE_MichaelSet
515 CDSUNIT_DECLARE_SplitList
516 CDSUNIT_DECLARE_StripedSet
517 CDSUNIT_DECLARE_RefinableSet
518 CDSUNIT_DECLARE_CuckooSet
519 CDSUNIT_DECLARE_SkipListSet
520 CDSUNIT_DECLARE_EllenBinTreeSet
521 CDSUNIT_DECLARE_MultiLevelHashSet
522 CDSUNIT_DECLARE_StdSet
524 CPPUNIT_TEST_SUITE_(Set_InsDel_string, "Map_InsDel_func")
525 CDSUNIT_TEST_MichaelSet
526 CDSUNIT_TEST_SplitList
527 CDSUNIT_TEST_SkipListSet
528 CDSUNIT_TEST_MultiLevelHashSet
529 CDSUNIT_TEST_EllenBinTreeSet
530 CDSUNIT_TEST_StripedSet
531 CDSUNIT_TEST_RefinableSet
532 CDSUNIT_TEST_CuckooSet
534 CPPUNIT_TEST_SUITE_END();