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_nFeldmanSet_HeadBits = 10;
27 size_t c_nFeldmanSet_ArrayBits = 4;
29 size_t c_nLoadFactor = 2;
32 typedef std::string key_type;
33 typedef size_t value_type;
35 const std::vector<std::string> * m_parrString;
38 class Inserter: public CppUnitMini::TestThread
41 typedef typename Set::value_type keyval_type;
43 virtual Inserter * clone()
45 return new Inserter( *this );
48 size_t m_nInsertSuccess;
49 size_t m_nInsertFailed;
52 Inserter( CppUnitMini::ThreadPool& pool, Set& rSet )
53 : CppUnitMini::TestThread( pool )
56 Inserter( Inserter& src )
57 : CppUnitMini::TestThread( src )
61 Set_InsDel_string& getTest()
63 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
66 virtual void init() { cds::threading::Manager::attachThread() ; }
67 virtual void fini() { cds::threading::Manager::detachThread() ; }
76 const std::vector<std::string>& arrString = *getTest().m_parrString;
77 size_t nArrSize = arrString.size();
78 size_t const nSetSize = getTest().c_nSetSize;
79 size_t const nPassCount = getTest().c_nThreadPassCount;
81 if ( m_nThreadNo & 1 ) {
82 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
83 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
84 if ( rSet.insert( keyval_type(arrString[nItem % nArrSize], nItem * 8) ) )
92 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
93 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
94 if ( rSet.insert( keyval_type( arrString[nItem % nArrSize], nItem * 8) ) )
105 class Deleter: public CppUnitMini::TestThread
109 virtual Deleter * clone()
111 return new Deleter( *this );
114 size_t m_nDeleteSuccess;
115 size_t m_nDeleteFailed;
118 Deleter( CppUnitMini::ThreadPool& pool, Set& rSet )
119 : CppUnitMini::TestThread( pool )
122 Deleter( Deleter& src )
123 : CppUnitMini::TestThread( src )
127 Set_InsDel_string& getTest()
129 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
132 virtual void init() { cds::threading::Manager::attachThread() ; }
133 virtual void fini() { cds::threading::Manager::detachThread() ; }
142 const std::vector<std::string>& arrString = *getTest().m_parrString;
143 size_t nArrSize = arrString.size();
144 size_t const nSetSize = getTest().c_nSetSize;
145 size_t const nPassCount = getTest().c_nThreadPassCount;
147 if ( m_nThreadNo & 1 ) {
148 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
149 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
150 if ( rSet.erase( arrString[nItem % nArrSize] ) )
158 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
159 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
160 if ( rSet.erase( arrString[nItem % nArrSize] ) )
170 template <typename GC, class Set>
171 class Extractor: public CppUnitMini::TestThread
175 virtual Extractor * clone()
177 return new Extractor( *this );
180 size_t m_nDeleteSuccess;
181 size_t m_nDeleteFailed;
184 Extractor( CppUnitMini::ThreadPool& pool, Set& rSet )
185 : CppUnitMini::TestThread( pool )
188 Extractor( Extractor& src )
189 : CppUnitMini::TestThread( src )
193 Set_InsDel_string& getTest()
195 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
198 virtual void init() { cds::threading::Manager::attachThread() ; }
199 virtual void fini() { cds::threading::Manager::detachThread() ; }
208 typename Set::guarded_ptr gp;
210 const std::vector<std::string>& arrString = *getTest().m_parrString;
211 size_t nArrSize = arrString.size();
212 size_t const nSetSize = getTest().c_nSetSize;
213 size_t const nPassCount = getTest().c_nThreadPassCount;
215 if ( m_nThreadNo & 1 ) {
216 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
217 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
218 gp = rSet.extract( arrString[nItem % nArrSize]);
228 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
229 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
230 gp = rSet.extract( arrString[nItem % nArrSize]);
242 template <typename RCU, class Set>
243 class Extractor<cds::urcu::gc<RCU>, Set >: public CppUnitMini::TestThread
247 virtual Extractor * clone()
249 return new Extractor( *this );
252 size_t m_nDeleteSuccess;
253 size_t m_nDeleteFailed;
256 Extractor( CppUnitMini::ThreadPool& pool, Set& rSet )
257 : CppUnitMini::TestThread( pool )
260 Extractor( Extractor& src )
261 : CppUnitMini::TestThread( src )
265 Set_InsDel_string& getTest()
267 return reinterpret_cast<Set_InsDel_string&>( m_Pool.m_Test );
270 virtual void init() { cds::threading::Manager::attachThread() ; }
271 virtual void fini() { cds::threading::Manager::detachThread() ; }
280 typename Set::exempt_ptr xp;
282 const std::vector<std::string>& arrString = *getTest().m_parrString;
283 size_t nArrSize = arrString.size();
284 size_t const nSetSize = getTest().c_nSetSize;
285 size_t const nPassCount = getTest().c_nThreadPassCount;
287 if ( m_nThreadNo & 1 ) {
288 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
289 for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
290 if ( Set::c_bExtractLockExternal ) {
292 typename Set::rcu_lock l;
293 xp = rSet.extract( arrString[nItem % nArrSize] );
301 xp = rSet.extract( arrString[nItem % nArrSize] );
312 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
313 for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
314 if ( Set::c_bExtractLockExternal ) {
316 typename Set::rcu_lock l;
317 xp = rSet.extract( arrString[nItem % nArrSize] );
325 xp = rSet.extract( arrString[nItem % nArrSize] );
340 void do_test( Set& testSet )
342 typedef Inserter<Set> InserterThread;
343 typedef Deleter<Set> DeleterThread;
344 cds::OS::Timer timer;
346 CppUnitMini::ThreadPool pool( *this );
347 pool.add( new InserterThread( pool, testSet ), c_nInsertThreadCount );
348 pool.add( new DeleterThread( pool, testSet ), c_nDeleteThreadCount );
350 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
352 size_t nInsertSuccess = 0;
353 size_t nInsertFailed = 0;
354 size_t nDeleteSuccess = 0;
355 size_t nDeleteFailed = 0;
356 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
357 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
359 nInsertSuccess += pThread->m_nInsertSuccess;
360 nInsertFailed += pThread->m_nInsertFailed;
363 DeleterThread * p = static_cast<DeleterThread *>( *it );
364 nDeleteSuccess += p->m_nDeleteSuccess;
365 nDeleteFailed += p->m_nDeleteFailed;
369 CPPUNIT_MSG( " Totals: Ins succ=" << nInsertSuccess
370 << " Del succ=" << nDeleteSuccess << "\n"
371 << " : Ins fail=" << nInsertFailed
372 << " Del fail=" << nDeleteFailed
373 << " Set size=" << testSet.size()
377 CPPUNIT_MSG( " Clear set (single-threaded)..." );
379 for ( size_t i = 0; i < m_parrString->size(); ++i )
380 testSet.erase( (*m_parrString)[i] );
381 CPPUNIT_MSG( " Duration=" << timer.duration() );
382 CPPUNIT_ASSERT( testSet.empty() );
384 additional_check( testSet );
385 print_stat( testSet );
386 additional_cleanup( testSet );
390 void do_test_extract( Set& testSet )
392 typedef Inserter<Set> InserterThread;
393 typedef Deleter<Set> DeleterThread;
394 typedef Extractor<typename Set::gc, Set> ExtractThread;
396 size_t nDelThreadCount = c_nDeleteThreadCount / 2;
398 CppUnitMini::ThreadPool pool( *this );
399 pool.add( new InserterThread( pool, testSet ), c_nInsertThreadCount );
400 pool.add( new DeleterThread( pool, testSet ), nDelThreadCount );
401 pool.add( new ExtractThread( pool, testSet ), c_nDeleteThreadCount - nDelThreadCount );
403 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
405 size_t nInsertSuccess = 0;
406 size_t nInsertFailed = 0;
407 size_t nDeleteSuccess = 0;
408 size_t nDeleteFailed = 0;
409 size_t nExtractSuccess = 0;
410 size_t nExtractFailed = 0;
411 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
412 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
414 nInsertSuccess += pThread->m_nInsertSuccess;
415 nInsertFailed += pThread->m_nInsertFailed;
418 DeleterThread * p = dynamic_cast<DeleterThread *>( *it );
420 nDeleteSuccess += p->m_nDeleteSuccess;
421 nDeleteFailed += p->m_nDeleteFailed;
424 ExtractThread * pExtract = dynamic_cast<ExtractThread *>( *it );
426 nExtractSuccess += pExtract->m_nDeleteSuccess;
427 nExtractFailed += pExtract->m_nDeleteFailed;
432 CPPUNIT_MSG( " Totals: Ins succ=" << nInsertSuccess
433 << " Del succ=" << nDeleteSuccess
434 << " Extract succ= " << nExtractSuccess << "\n"
435 << " : Ins fail=" << nInsertFailed
436 << " Del fail=" << nDeleteFailed
437 << " Extract fail=" << nExtractFailed
438 << " Set size=" << testSet.size()
442 CPPUNIT_MSG( " Clear set (single-threaded)..." );
443 cds::OS::Timer timer;
444 for ( size_t i = 0; i < m_parrString->size(); ++i )
445 testSet.erase( (*m_parrString)[i] );
446 CPPUNIT_MSG( " Duration=" << timer.duration() );
447 CPPUNIT_ASSERT( testSet.empty() );
449 additional_check( testSet );
450 print_stat( testSet );
451 additional_cleanup( testSet );
457 m_parrString = &CppUnitMini::TestCase::getTestStrings();
459 CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
460 << " delete=" << c_nDeleteThreadCount
461 << " pass count=" << c_nThreadPassCount
462 << " set size=" << c_nSetSize
465 if ( Set::c_bLoadFactorDepended ) {
466 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
467 CPPUNIT_MSG(" LoadFactor = " << c_nLoadFactor );
470 if ( c_bPrintGCState )
477 if ( c_bPrintGCState )
483 void run_test_extract()
485 m_parrString = &CppUnitMini::TestCase::getTestStrings();
487 CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
488 << " delete=" << c_nDeleteThreadCount
489 << " pass count=" << c_nThreadPassCount
490 << " set size=" << c_nSetSize
493 if ( Set::c_bLoadFactorDepended ) {
494 for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
495 CPPUNIT_MSG(" LoadFactor = " << c_nLoadFactor );
497 do_test_extract( s );
498 if ( c_bPrintGCState )
504 do_test_extract( s );
505 if ( c_bPrintGCState )
510 void setUpParams( const CppUnitMini::TestCfg& cfg );
512 # include "set2/set_defs.h"
513 CDSUNIT_DECLARE_MichaelSet
514 CDSUNIT_DECLARE_SplitList
515 CDSUNIT_DECLARE_StripedSet
516 CDSUNIT_DECLARE_RefinableSet
517 CDSUNIT_DECLARE_CuckooSet
518 CDSUNIT_DECLARE_SkipListSet
519 CDSUNIT_DECLARE_EllenBinTreeSet
520 CDSUNIT_DECLARE_FeldmanHashSet_stdhash
521 CDSUNIT_DECLARE_FeldmanHashSet_md5
522 CDSUNIT_DECLARE_FeldmanHashSet_sha256
523 CDSUNIT_DECLARE_FeldmanHashSet_city
524 CDSUNIT_DECLARE_StdSet
526 CPPUNIT_TEST_SUITE_(Set_InsDel_string, "Map_InsDel_func")
527 CDSUNIT_TEST_MichaelSet
528 CDSUNIT_TEST_SplitList
529 CDSUNIT_TEST_SkipListSet
530 CDSUNIT_TEST_FeldmanHashSet_stdhash
531 CDSUNIT_TEST_FeldmanHashSet_md5
532 CDSUNIT_TEST_FeldmanHashSet_sha256
533 CDSUNIT_TEST_FeldmanHashSet_city
534 CDSUNIT_TEST_EllenBinTreeSet
535 CDSUNIT_TEST_StripedSet
536 CDSUNIT_TEST_RefinableSet
537 CDSUNIT_TEST_CuckooSet
539 CPPUNIT_TEST_SUITE_END();