X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=blobdiff_plain;f=test%2Fstress%2Fset%2Fdelodd%2Fset_delodd.h;h=83809c628d2ad6ddfc22cf03893f8076ec2da09f;hp=a27fcad244f462aeb6fd3e3652ee0d3652bb92f0;hb=e67378edc5adde0bb14c3c6fde60d51c61a12b69;hpb=041af6c4d6ddd916ed28db2fd3ef2820ee96cd79 diff --git a/test/stress/set/delodd/set_delodd.h b/test/stress/set/delodd/set_delodd.h index a27fcad2..83809c62 100644 --- a/test/stress/set/delodd/set_delodd.h +++ b/test/stress/set/delodd/set_delodd.h @@ -1,7 +1,7 @@ /* This file is a part of libcds - Concurrent Data Structures library - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 Source code repo: http://github.com/khizmax/libcds/ Download: http://sourceforge.net/projects/libcds/files/ @@ -29,6 +29,7 @@ */ #include "set_type.h" +#include namespace set { @@ -122,6 +123,7 @@ namespace set { static size_t s_nExtractThreadCount; // extract thread count static size_t s_nMaxLoadFactor; // maximum load factor static size_t s_nInsertPassCount; + static size_t s_nFindThreadCount; // find thread count static size_t s_nCuckooInitialSize; // initial size for CuckooSet static size_t s_nCuckooProbesetSize; // CuckooSet probeset size (only for list-based probeset) @@ -159,6 +161,7 @@ namespace set { inserter_thread, deleter_thread, extractor_thread, + find_thread }; @@ -587,21 +590,85 @@ namespace set { } }; + // Finds keys + template + class Observer: public cds_test::thread + { + typedef cds_test::thread base_class; + Set& m_Set; + + public: + size_t m_nFindEvenSuccess = 0; + size_t m_nFindEvenFailed = 0; + size_t m_nFindOddSuccess = 0; + size_t m_nFindOddFailed = 0; + + public: + Observer( cds_test::thread_pool& pool, Set& set ) + : base_class( pool, find_thread ) + , m_Set( set ) + {} + + Observer( Observer& src ) + : base_class( src ) + , m_Set( src.m_Set ) + {} + + virtual thread * clone() + { + return new Observer( *this ); + } + + virtual void test() + { + Set& set = m_Set; + Set_DelOdd& fixture = pool().template fixture(); + std::vector const& arr = m_arrData; + size_t const nInsThreadCount = s_nInsThreadCount; + + do { + for ( size_t key : arr ) { + if ( key & 1 ) { + for ( size_t k = 0; k < nInsThreadCount; ++k ) { + if ( set.contains( key_thread( key, k ) ) ) + ++m_nFindOddSuccess; + else + ++m_nFindOddFailed; + } + } + else { + // even keys MUST be in the map + for ( size_t k = 0; k < nInsThreadCount; ++k ) { + if ( set.contains( key_thread( key, k ) ) ) + ++m_nFindEvenSuccess; + else + ++m_nFindEvenFailed; + } + } + } + } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 ); + } + }; + protected: template void do_test_with( Set& testSet ) { typedef Inserter insert_thread; typedef Deleter delete_thread; + typedef Observer observer_thread; m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release ); cds_test::thread_pool& pool = get_pool(); pool.add( new insert_thread( pool, testSet ), s_nInsThreadCount ); pool.add( new delete_thread( pool, testSet ), s_nDelThreadCount ? s_nDelThreadCount : cds::OS::topology::processor_count()); + if ( s_nFindThreadCount ) + pool.add( new observer_thread( pool, testSet ), s_nFindThreadCount ); propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount ) << std::make_pair( "delete_thread_count", s_nDelThreadCount ) + << std::make_pair( "find_thread_count", s_nFindThreadCount ) << std::make_pair( "set_size", s_nSetSize ) << std::make_pair( "pass_count", s_nInsertPassCount ); @@ -616,20 +683,41 @@ namespace set { size_t nDeleteSuccess = 0; size_t nDeleteFailed = 0; + size_t nFindEvenSuccess = 0; + size_t nFindEvenFailed = 0; + size_t nFindOddSuccess = 0; + size_t nFindOddFailed = 0; + for ( size_t i = 0; i < pool.size(); ++i ) { cds_test::thread& thr = pool.get( i ); - if ( thr.type() == inserter_thread ) { - insert_thread& inserter = static_cast(thr); - nInsertSuccess += inserter.m_nInsertSuccess; - nInsertFailed += inserter.m_nInsertFailed; - nInsertInitSuccess += inserter.m_nInsertInitSuccess; - nInsertInitFailed += inserter.m_nInsertInitFailed; - } - else { - assert( thr.type() == deleter_thread ); - delete_thread& deleter = static_cast(thr); - nDeleteSuccess += deleter.m_nDeleteSuccess; - nDeleteFailed += deleter.m_nDeleteFailed; + switch ( thr.type()) { + case inserter_thread: + { + insert_thread& inserter = static_cast(thr); + nInsertSuccess += inserter.m_nInsertSuccess; + nInsertFailed += inserter.m_nInsertFailed; + nInsertInitSuccess += inserter.m_nInsertInitSuccess; + nInsertInitFailed += inserter.m_nInsertInitFailed; + } + break; + case deleter_thread: + { + delete_thread& deleter = static_cast(thr); + nDeleteSuccess += deleter.m_nDeleteSuccess; + nDeleteFailed += deleter.m_nDeleteFailed; + } + break; + case find_thread: + { + observer_thread& observer = static_cast( thr ); + nFindEvenSuccess = observer.m_nFindEvenSuccess; + nFindEvenFailed = observer.m_nFindEvenFailed; + nFindOddSuccess = observer.m_nFindOddSuccess; + nFindOddFailed = observer.m_nFindOddFailed; + } + break; + default: + assert( false ); } } @@ -637,6 +725,7 @@ namespace set { EXPECT_EQ( nInsertInitFailed, 0u ); EXPECT_EQ( nInsertInitSuccess, s_nSetSize * s_nInsThreadCount ); + EXPECT_EQ( nFindEvenFailed, 0u ); EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess ); EXPECT_LE( nInsertSuccess, nDeleteSuccess ); @@ -646,7 +735,11 @@ namespace set { << std::make_pair( "insert_success", nInsertSuccess ) << std::make_pair( "insert_failed", nInsertFailed ) << std::make_pair( "delete_success", nDeleteSuccess ) - << std::make_pair( "delete_failed", nDeleteFailed ); + << std::make_pair( "delete_failed", nDeleteFailed ) + << std::make_pair( "find_even_success", nFindEvenSuccess ) + << std::make_pair( "find_even_failed", nFindEvenFailed ) + << std::make_pair( "find_odd_success", nFindOddSuccess ) + << std::make_pair( "find_odd_failed", nFindOddFailed ); } template @@ -655,6 +748,7 @@ namespace set { typedef Inserter insert_thread; typedef Deleter delete_thread; typedef Extractor< typename Set::gc, Set > extract_thread; + typedef Observer observer_thread; m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release ); @@ -664,10 +758,13 @@ namespace set { pool.add( new delete_thread( pool, testSet ), s_nDelThreadCount ); if ( s_nExtractThreadCount ) pool.add( new extract_thread( pool, testSet ), s_nExtractThreadCount ); + if ( s_nFindThreadCount ) + pool.add( new observer_thread( pool, testSet ), s_nFindThreadCount ); propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount ) << std::make_pair( "delete_thread_count", s_nDelThreadCount ) << std::make_pair( "extract_thread_count", s_nExtractThreadCount ) + << std::make_pair( "find_thread_count", s_nFindThreadCount ) << std::make_pair( "set_size", s_nSetSize ) << std::make_pair( "pass_count", s_nInsertPassCount ); @@ -683,6 +780,12 @@ namespace set { size_t nDeleteFailed = 0; size_t nExtractSuccess = 0; size_t nExtractFailed = 0; + + size_t nFindEvenSuccess = 0; + size_t nFindEvenFailed = 0; + size_t nFindOddSuccess = 0; + size_t nFindOddFailed = 0; + for ( size_t i = 0; i < pool.size(); ++i ) { cds_test::thread& thr = pool.get( i ); switch ( thr.type()) { @@ -709,6 +812,15 @@ namespace set { nExtractFailed += extractor.m_nExtractFailed; } break; + case find_thread: + { + observer_thread& observer = static_cast( thr ); + nFindEvenSuccess = observer.m_nFindEvenSuccess; + nFindEvenFailed = observer.m_nFindEvenFailed; + nFindOddSuccess = observer.m_nFindOddSuccess; + nFindOddFailed = observer.m_nFindOddFailed; + } + break; default: assert( false ); } @@ -718,6 +830,7 @@ namespace set { EXPECT_EQ( nInsertInitFailed, 0u ); EXPECT_EQ( nInsertInitSuccess, s_nSetSize * s_nInsThreadCount ); + EXPECT_EQ( nFindEvenFailed, 0u ); EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess + nExtractSuccess ); EXPECT_LE( nInsertSuccess, nDeleteSuccess + nExtractSuccess ); @@ -729,7 +842,11 @@ namespace set { << std::make_pair( "delete_success", nDeleteSuccess ) << std::make_pair( "delete_failed", nDeleteFailed ) << std::make_pair( "extract_success", nExtractSuccess ) - << std::make_pair( "extract_failed", nExtractFailed ); + << std::make_pair( "extract_failed", nExtractFailed ) + << std::make_pair( "find_even_success", nFindEvenSuccess ) + << std::make_pair( "find_even_failed", nFindEvenFailed ) + << std::make_pair( "find_odd_success", nFindOddSuccess ) + << std::make_pair( "find_odd_failed", nFindOddFailed ); } template