*/
#include "map_type.h"
+#include "../../misc/common.h"
#include <cds/os/topology.h>
namespace map {
<< std::make_pair( "find_odd_success", nFindOddSuccess )
<< std::make_pair( "find_odd_failed", nFindOddFailed );
- analyze( testMap );
+ DEBUG(analyze( testMap ));
}
template <class Map>
<< std::make_pair( "find_odd_success", nFindOddSuccess )
<< std::make_pair( "find_odd_failed", nFindOddFailed );
- analyze( testMap );
+ DEBUG(analyze( testMap ));
}
template <class Map>
*/
#include "map_type.h"
+#include "../../misc/common.h"
#include <cds/os/topology.h>
namespace map {
<< std::make_pair( "find_odd_success", nFindOddSuccess )
<< std::make_pair( "find_odd_failed", nFindOddFailed );
- analyze( testMap );
+ DEBUG(analyze( testMap ));
}
template <class Map>
<< std::make_pair( "find_odd_success", nFindOddSuccess )
<< std::make_pair( "find_odd_failed", nFindOddFailed );
- analyze( testMap );
+ DEBUG(analyze( testMap ));
}
template <class Map>
*/
#include "map_type.h"
+#include "../../misc/common.h"
#include <cds/os/topology.h>
namespace map {
<< std::make_pair( "find_odd_success", nFindOddSuccess )
<< std::make_pair( "find_odd_failed", nFindOddFailed );
- analyze( testMap );
+ DEBUG(analyze( testMap ));
}
template <typename Iterator, class Map>
<< std::make_pair( "find_odd_success", nFindOddSuccess )
<< std::make_pair( "find_odd_failed", nFindOddFailed );
- analyze( testMap );
+ DEBUG(analyze( testMap ));
}
template <class Map>
*/
#include "map_type.h"
+#include "../../misc/common.h"
#include <cds/os/topology.h>
namespace map {
<< std::make_pair( "extract_max", nDeleteMax )
<< std::make_pair( "extract_max_failed", nDeleteMaxFailed );
- analyze( testMap );
+ DEBUG(analyze( testMap ));
}
template <class Map>
*/
#include "queue_type.h"
+#include "../misc/common.h"
// Multi-threaded queue test for pop operation
namespace {
propout() << std::make_pair( "duration", duration );
- analyze( q );
+ DEBUG(analyze( q ));
propout() << q.statistics();
}
*/
#include "queue_type.h"
+#include "../misc/common.h"
// Multi-threaded queue test for push operation
namespace {
propout() << std::make_pair( "duration", duration );
- analyze( q );
+ DEBUG(analyze( q ));
propout() << q.statistics();
}
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCDSUNIT_USE_URCU")
-add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/delodd)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/del3)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/delodd)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_find)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_func)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_string)
add_custom_target( stress-sequential-set
DEPENDS
- stress-sequential-set-delodd
stress-sequential-set-del3
+ stress-sequential-set-delodd
stress-sequential-set-insdelfind
stress-sequential-set-insdel-func
stress-sequential-set-insdel-string
size_t Set_Del3::s_nExtractThreadCount = 4;
size_t Set_Del3::s_nFindThreadCount = 2;
size_t Set_Del3::s_nMaxLoadFactor = 8;
+
size_t Set_Del3::s_nPassCount = 100;
size_t Set_Del3::s_nFeldmanPassCount = 100;
size_t Set_Del3::s_nInsertPassCount = 1;
static size_t s_nDelThreadCount; // delete thread count
static size_t s_nExtractThreadCount; // extract thread count
static size_t s_nMaxLoadFactor; // maximum load factor
+
static size_t s_nPassCount;
static size_t s_nFeldmanPassCount;
-
static size_t s_nInsertPassCount;
static size_t s_nDeletePassCount;
static size_t s_nFindPassCount;
+
static size_t s_nFindThreadCount; // find thread count
static size_t s_nCuckooInitialSize; // initial size for CuckooSet
size_t Set_DelOdd::s_nExtractThreadCount = 4;
size_t Set_DelOdd::s_nFindThreadCount = 2;
size_t Set_DelOdd::s_nMaxLoadFactor = 8;
- size_t Set_DelOdd::s_nInsertPassCount = 100;
+
+ size_t Set_DelOdd::s_nPassCount = 100;
+ size_t Set_DelOdd::s_nFeldmanPassCount = 100;
+ size_t Set_DelOdd::s_nInsertPassCount = 1;
+ size_t Set_DelOdd::s_nDeletePassCount = 1;
+ size_t Set_DelOdd::s_nFindPassCount = 10;
size_t Set_DelOdd::s_nCuckooInitialSize = 1024;
size_t Set_DelOdd::s_nCuckooProbesetSize = 16;
void Set_DelOdd::SetUpTestCase()
{
- cds_test::config const& cfg = get_config( "map_delodd" );
+ cds_test::config const& cfg = get_config( "sequential_map_delodd" );
s_nSetSize = cfg.get_size_t( "MapSize", s_nSetSize );
if ( s_nSetSize < 1000 )
if ( s_nMaxLoadFactor == 0 )
s_nMaxLoadFactor = 1;
- s_nInsertPassCount = cfg.get_size_t( "PassCount", s_nInsertPassCount );
+ s_nPassCount = cfg.get_size_t("PassCount", s_nPassCount);
+ if (s_nPassCount == 0)
+ s_nPassCount = 100;
+
+ s_nFeldmanPassCount =
+ cfg.get_size_t("FeldmanPassCount", s_nFeldmanPassCount);
+ if (s_nFeldmanPassCount == 0)
+ s_nFeldmanPassCount = 500;
+
+ s_nInsertPassCount = cfg.get_size_t( "InsertPassCount", s_nInsertPassCount );
if ( s_nInsertPassCount == 0 )
- s_nInsertPassCount = 100;
+ s_nInsertPassCount = 1;
+
+ s_nDeletePassCount = cfg.get_size_t( "DeletePassCount", s_nDeletePassCount );
+ if ( s_nDeletePassCount == 0 )
+ s_nDeletePassCount = 1;
+
+ s_nFindPassCount = cfg.get_size_t( "FindPassCount", s_nFindPassCount );
+ if ( s_nFindPassCount == 0 )
+ s_nFindPassCount = 10;
+
s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
if ( s_nCuckooInitialSize < 256 )
static size_t s_nDelThreadCount; // delete thread count
static size_t s_nExtractThreadCount; // extract thread count
static size_t s_nMaxLoadFactor; // maximum load factor
+
+ static size_t s_nPassCount;
+ static size_t s_nFeldmanPassCount;
static size_t s_nInsertPassCount;
+ static size_t s_nDeletePassCount;
+ static size_t s_nFindPassCount;
+
static size_t s_nFindThreadCount; // find thread count
static size_t s_nCuckooInitialSize; // initial size for CuckooSet
}
template <class Set>
- void do_test_extract_with( Set& testSet )
- {
- typedef Inserter<Set> insert_thread;
- typedef Deleter<Set> delete_thread;
- typedef Extractor< typename Set::gc, Set > extract_thread;
- typedef Observer<Set> 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 );
- if ( s_nDelThreadCount )
- 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 );
-
- std::chrono::milliseconds duration = pool.run();
-
- propout() << std::make_pair( "duration", duration );
-
- size_t nInsertInitFailed = 0;
- size_t nInsertInitSuccess = 0;
- size_t nInsertSuccess = 0;
- size_t nInsertFailed = 0;
- size_t nDeleteSuccess = 0;
- 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()) {
- case inserter_thread:
- {
- insert_thread& inserter = static_cast<insert_thread&>( 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<delete_thread&>(thr);
- nDeleteSuccess += deleter.m_nDeleteSuccess;
- nDeleteFailed += deleter.m_nDeleteFailed;
- }
- break;
- case extractor_thread:
- {
- extract_thread& extractor = static_cast<extract_thread&>(thr);
- nExtractSuccess += extractor.m_nExtractSuccess;
- nExtractFailed += extractor.m_nExtractFailed;
- }
- break;
- case find_thread:
- {
- observer_thread& observer = static_cast<observer_thread&>( thr );
- nFindEvenSuccess = observer.m_nFindEvenSuccess;
- nFindEvenFailed = observer.m_nFindEvenFailed;
- nFindOddSuccess = observer.m_nFindOddSuccess;
- nFindOddFailed = observer.m_nFindOddFailed;
- }
- break;
- default:
- assert( false );
- }
- }
-
- size_t const nInitialOddKeys = ( s_nSetSize * s_nInsThreadCount ) / 2;
-
- 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 );
-
- propout()
- << std::make_pair( "insert_init_success", nInsertInitSuccess )
- << std::make_pair( "insert_init_failed", nInsertInitFailed )
- << 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( "extract_success", nExtractSuccess )
- << 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 );
+ void do_test_extract_with(Set &testSet, size_t pass_count) {
+ typedef Inserter<Set> insert_thread;
+ typedef Deleter<Set> delete_thread;
+ typedef Extractor<typename Set::gc, Set> extract_thread;
+ typedef Observer<Set> observer_thread;
+
+ size_t nInsertSuccess = 0;
+ size_t nInsertFailed = 0;
+ size_t nDeleteSuccess = 0;
+ 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;
+
+ auto reset_stat = [&]() {
+ nInsertSuccess = 0;
+ nInsertFailed = 0;
+ nDeleteSuccess = 0;
+ nDeleteFailed = 0;
+ nExtractSuccess = 0;
+ nExtractFailed = 0;
+ nFindEvenSuccess = 0;
+ nFindEvenFailed = 0;
+ nFindOddSuccess = 0;
+ nFindOddFailed = 0;
+ };
+
+ auto insert_func = [&]() {
+ for (auto el : m_arrData) {
+ if (testSet.insert(key_type(el, 0)))
+ ++nInsertSuccess;
+ else
+ ++nInsertFailed;
+ }
+ };
+
+ auto delete_func = [&]() {
+ for (auto el : m_arrData) {
+ if (el & 1) {
+ if (testSet.erase(key_type(el, 0)))
+ ++nDeleteSuccess;
+ else
+ ++nDeleteFailed;
+ }
+ }
+ };
+
+ auto extract_func = [&]() {
+ for (auto el : m_arrData) {
+ if (el & 1) {
+ auto gp = testSet.extract(key_type(el, 0));
+ if (gp)
+ ++nExtractSuccess;
+ else
+ ++nExtractFailed;
+ gp.release();
+ }
+ }
+ };
+
+ auto find_func = [&]() {
+ for (size_t el : m_arrData) {
+ if (el & 1) {
+ if (testSet.contains(key_thread(el, 0)))
+ ++nFindOddSuccess;
+ else
+ ++nFindOddFailed;
+ } else {
+ // even keys MUST be in the map
+ if (testSet.contains(key_thread(el, 0)))
+ ++nFindEvenSuccess;
+ else
+ ++nFindEvenFailed;
+ }
+ }
+ };
+
+ auto test_func = [&](size_t count, std::function<void()> func) {
+ for (size_t i = 0; i < count; ++i) {
+ func();
+ }
+ };
+
+ size_t const nInitialOddKeys = s_nSetSize / 2;
+ size_t const nInitialEvenKeys = s_nSetSize / 2;
+ for (size_t nPass = 0; nPass < pass_count; ++nPass) {
+ // Start with an empty set.
+ testSet.clear();
+ reset_stat();
+
+ test_func(s_nInsertPassCount, insert_func);
+ EXPECT_EQ(nInsertSuccess, s_nSetSize);
+ reset_stat();
+
+ test_func(s_nFindPassCount, find_func);
+ EXPECT_EQ(nFindEvenFailed, 0u);
+ EXPECT_EQ(nFindOddFailed, 0u);
+ reset_stat();
+
+ test_func(s_nDeletePassCount, delete_func);
+ EXPECT_EQ(nDeleteSuccess, nInitialOddKeys);
+ reset_stat();
+
+ test_func(s_nInsertPassCount, insert_func);
+ EXPECT_EQ(nInsertSuccess, nInitialOddKeys);
+ reset_stat();
+
+ test_func(s_nDeletePassCount, extract_func);
+ EXPECT_EQ(nExtractSuccess, nInitialOddKeys);
+ reset_stat();
+
+ test_func(s_nFindPassCount, find_func);
+ EXPECT_EQ(nFindEvenFailed, 0u);
+ EXPECT_EQ(nFindOddSuccess, 0u);
+ }
+
+ // std::chrono::duration<double> time_elapsed;
+ // std::chrono::duration<double> time_diff;
+ // std::chrono::time_point<std::chrono::steady_clock>
+ // time_start;
+ // std::chrono::time_point<std::chrono::steady_clock>
+ // time_end;
+ // time_start = std::chrono::steady_clock::now();
+ // time_end = std::chrono::steady_clock::now();
+ // time_diff = time_end - time_start;
+ // time_elapsed = time_diff;
+ // std::cout << "Time elapsed: " << time_elapsed.count() <<
+ // "\n";
}
template <typename Set>
}
template <class Set>
- void run_test_extract()
+ void run_test_extract(size_t pass_count = s_nPassCount)
{
static_assert( Set::c_bExtractSupported, "Set class must support extract() method" );
Set testSet( *this );
- do_test_extract_with( testSet );
- analyze( testSet );
+ do_test_extract_with( testSet, pass_count);
}
template <class Map>
}
template <class Set>
- void run_test_extract()
+ void run_test_extract(size_t pass_count = s_nPassCount)
{
s_nLoadFactor = GetParam();
propout() << std::make_pair( "load_factor", s_nLoadFactor );
- Set_DelOdd::run_test_extract<Set>();
+ Set_DelOdd::run_test_extract<Set>(pass_count);
}
static std::vector<size_t> get_load_factors();
};
typedef typename Set::template rebind_traits< traits >::result set_type;
- run_test_extract<set_type>();
+ run_test_extract<set_type>(s_nFeldmanPassCount);
}
CDSSTRESS_FeldmanHashSet_fixed( Set_DelOdd, run_feldman, key_thread, size_t )
namespace set {
size_t Set_InsDelFind::s_nSetSize = 500000; // initial set size
+ size_t Set_InsDelFind::s_nPassCount = 500000; // initial pass count
+
size_t Set_InsDelFind::s_nThreadCount = 8; // thread count
size_t Set_InsDelFind::s_nMaxLoadFactor = 8; // maximum load factor
unsigned int Set_InsDelFind::s_nInsertPercentage = 5;
void Set_InsDelFind::SetUpTestCase()
{
- cds_test::config const& cfg = get_config( "map_insdelfind" );
+ cds_test::config const& cfg = get_config( "sequential_map_insdelfind" );
s_nSetSize = cfg.get_size_t( "InitialMapSize", s_nSetSize );
if ( s_nSetSize < 1000 )
s_nSetSize = 1000;
+ s_nPassCount = cfg.get_size_t( "PassCount", s_nPassCount);
+ if ( s_nPassCount < 1000 )
+ s_nPassCount = 1000;
+
s_nThreadCount = cfg.get_size_t( "ThreadCount", s_nThreadCount );
if ( s_nThreadCount == 0 )
s_nThreadCount = 2;
{
public:
static size_t s_nSetSize; // initial set size
+ static size_t s_nPassCount; // initial set size
static size_t s_nThreadCount; // thread count
static size_t s_nMaxLoadFactor; // maximum load factor
static unsigned int s_nInsertPercentage;
unsigned int i = 0;
size_t const nNormalize = size_t(-1) / ( fixture.s_nSetSize * 2);
+ size_t pass_count = fixture.s_nPassCount;
size_t nRand = 0;
- while ( !time_elapsed()) {
+ while ( pass_count-- ) {
nRand = cds::bitop::RandXorShift(nRand);
size_t n = nRand / nNormalize;
switch ( s_arrShuffle[i] ) {
delete [] pInitArr;
}
+ s_nThreadCount = 1;
cds_test::thread_pool& pool = get_pool();
- pool.add( new work_thread( pool, testSet ), s_nThreadCount );
+ std::unique_ptr<work_thread> worker(new work_thread(pool, testSet));
+ worker->test();
propout() << std::make_pair( "thread_count", s_nThreadCount )
<< std::make_pair( "set_size", s_nSetSize )
<< std::make_pair( "delete_percentage", s_nDeletePercentage )
<< std::make_pair( "total_duration", s_nDuration );
- std::chrono::milliseconds duration = pool.run( std::chrono::seconds( s_nDuration ));
-
- propout() << std::make_pair( "duration", duration );
-
size_t nInsertSuccess = 0;
size_t nInsertFailed = 0;
size_t nDeleteSuccess = 0;
size_t nDeleteFailed = 0;
size_t nFindSuccess = 0;
size_t nFindFailed = 0;
- for ( size_t i = 0; i < pool.size(); ++i ) {
- work_thread& thr = static_cast<work_thread&>( pool.get( i ));
- nInsertSuccess += thr.m_nInsertSuccess;
- nInsertFailed += thr.m_nInsertFailed;
- nDeleteSuccess += thr.m_nDeleteSuccess;
- nDeleteFailed += thr.m_nDeleteFailed;
- nFindSuccess += thr.m_nFindSuccess;
- nFindFailed += thr.m_nFindFailed;
- }
+ work_thread &thr = *worker;
+ nInsertSuccess += thr.m_nInsertSuccess;
+ nInsertFailed += thr.m_nInsertFailed;
+ nDeleteSuccess += thr.m_nDeleteSuccess;
+ nDeleteFailed += thr.m_nDeleteFailed;
+ nFindSuccess += thr.m_nFindSuccess;
+ nFindFailed += thr.m_nFindFailed;
propout()
<< std::make_pair( "insert_success", nInsertSuccess )
<< std::make_pair( "find_success", nFindSuccess )
<< std::make_pair( "find_failed", nFindFailed );
- {
- ASSERT_TRUE( std::chrono::duration_cast<std::chrono::seconds>(duration).count() > 0 );
- size_t nTotalOps = nInsertSuccess + nInsertFailed + nDeleteSuccess + nDeleteFailed + nFindSuccess + nFindFailed;
- propout() << std::make_pair( "avg_speed", nTotalOps / std::chrono::duration_cast<std::chrono::seconds>(duration).count());
- }
-
-
testSet.clear();
EXPECT_TRUE( testSet.empty()) << "set size=" << testSet.size();
size_t Set_InsDel_func::s_nDeleteThreadCount = 4; // count of deletion thread
size_t Set_InsDel_func::s_nUpdateThreadCount = 4; // count of ensure thread
size_t Set_InsDel_func::s_nThreadPassCount = 4; // pass count for each thread
+ size_t Set_InsDel_func::s_nFeldmanThreadPassCount = 4; // pass count for each thread
size_t Set_InsDel_func::s_nMaxLoadFactor = 8; // maximum load factor
size_t Set_InsDel_func::s_nCuckooInitialSize = 1024;// initial size for CuckooSet
void Set_InsDel_func::SetUpTestCase()
{
- cds_test::config const& cfg = get_config( "map_insdel_func" );
+ cds_test::config const& cfg = get_config( "sequential_map_insdel_func" );
s_nSetSize = cfg.get_size_t( "MapSize", s_nSetSize );
if ( s_nSetSize < 1000 )
if ( s_nThreadPassCount == 0 )
s_nThreadPassCount = 4;
+ s_nFeldmanThreadPassCount =
+ cfg.get_size_t("FeldmanThreadPassCount", s_nFeldmanThreadPassCount);
+ if (s_nFeldmanThreadPassCount == 0)
+ s_nFeldmanThreadPassCount = 4;
+
s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
if ( s_nMaxLoadFactor == 0 )
s_nMaxLoadFactor = 1;
static size_t s_nDeleteThreadCount; // count of deletion thread
static size_t s_nUpdateThreadCount; // count of updating thread
static size_t s_nThreadPassCount; // pass count for each thread
+ static size_t s_nFeldmanThreadPassCount; // pass count for Feldman
static size_t s_nMaxLoadFactor; // maximum load factor
static size_t s_nCuckooInitialSize; // initial size for CuckooSet
// func is passed by reference
insert_functor func;
-
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t * p = pKeyFirst; p < pKeyLast; ++p ) {
- if ( rSet.insert( *p, std::ref( func )))
- ++m_nInsertSuccess;
- else
- ++m_nInsertFailed;
- }
- }
+ for (size_t *p = pKeyFirst; p < pKeyLast; ++p) {
+ if (rSet.insert(*p, std::ref(func)))
+ ++m_nInsertSuccess;
+ else
+ ++m_nInsertFailed;
}
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t * p = pKeyLast - 1; p >= pKeyFirst; --p ) {
- if ( rSet.insert( *p, std::ref( func )))
- ++m_nInsertSuccess;
- else
- ++m_nInsertFailed;
- }
- }
- }
-
- m_nTestFunctorRef = func.nTestFunctorRef;
}
};
update_functor func;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t * p = pKeyFirst; p < pKeyLast; ++p ) {
- std::pair<bool, bool> ret = rSet.update( *p, std::ref( func ), true );
- if ( ret.first ) {
- if ( ret.second )
- ++m_nUpdateCreated;
- else
- ++m_nUpdateExisted;
- }
- else
- ++m_nUpdateFailed;
- }
- }
- }
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t * p = pKeyLast - 1 ; p >= pKeyFirst; --p ) {
- std::pair<bool, bool> ret = rSet.update( *p, std::ref( func ), true );
- if ( ret.first ) {
- if ( ret.second )
- ++m_nUpdateCreated;
- else
- ++m_nUpdateExisted;
- }
- else
- ++m_nUpdateFailed;
- }
- }
+ for (size_t *p = pKeyFirst; p < pKeyLast; ++p) {
+ std::pair<bool, bool> ret =
+ rSet.update(*p, std::ref(func), true);
+ if (ret.first) {
+ if (ret.second)
+ ++m_nUpdateCreated;
+ else
+ ++m_nUpdateExisted;
+ } else
+ ++m_nUpdateFailed;
}
-
- m_nFunctorCreated = func.nCreated;
- m_nFunctorModified = func.nModified;
}
};
erase_functor func;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t * p = pKeyFirst; p < pKeyLast; ++p ) {
- func.m_cnt.nKeyExpected = *p;
- if ( rSet.erase( *p, std::ref( func )))
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- }
- }
- }
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t * p = pKeyLast - 1; p >= pKeyFirst; --p ) {
- func.m_cnt.nKeyExpected = *p;
- if ( rSet.erase( *p, std::ref( func )))
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- }
- }
+ for (size_t *p = pKeyFirst; p < pKeyLast; ++p) {
+ func.m_cnt.nKeyExpected = *p;
+ if (rSet.erase(*p, std::ref(func)))
+ ++m_nDeleteSuccess;
+ else
+ ++m_nDeleteFailed;
}
-
- m_nValueSuccess = func.m_cnt.nSuccessItem;
- m_nValueFailed = func.m_cnt.nFailedItem;
}
};
protected:
template <class Set>
- void run_test( Set& testSet )
+ void run_test( Set& testSet, size_t pass_count)
{
typedef Inserter<Set> InserterThread;
typedef Deleter<Set> DeleterThread;
m_pKeyArr[i] = i;
shuffle( m_pKeyFirst, m_pKeyLast );
- cds_test::thread_pool& pool = get_pool();
- pool.add( new InserterThread( pool, testSet ), s_nInsertThreadCount );
- pool.add( new DeleterThread( pool, testSet ), s_nDeleteThreadCount );
- pool.add( new UpdaterThread( pool, testSet ), s_nUpdateThreadCount );
-
- propout() << std::make_pair( "insert_thread_count", s_nInsertThreadCount )
- << std::make_pair( "update_thread_count", s_nUpdateThreadCount )
- << std::make_pair( "delete_thread_count", s_nDeleteThreadCount )
- << std::make_pair( "thread_pass_count", s_nThreadPassCount )
- << std::make_pair( "set_size", s_nSetSize );
-
- std::chrono::milliseconds duration = pool.run();
-
- propout() << std::make_pair( "duration", duration );
-
- size_t nInsertSuccess = 0;
- size_t nInsertFailed = 0;
- size_t nDeleteSuccess = 0;
- size_t nDeleteFailed = 0;
- size_t nDelValueSuccess = 0;
- size_t nDelValueFailed = 0;
- size_t nUpdateFailed = 0;
- size_t nUpdateCreated = 0;
- size_t nUpdateModified = 0;
- size_t nEnsFuncCreated = 0;
- size_t nEnsFuncModified = 0;
- size_t nTestFunctorRef = 0;
-
- for ( size_t i = 0; i < pool.size(); ++i ) {
- cds_test::thread& thr = pool.get( i );
- switch ( thr.type()) {
- case insert_thread:
- {
- InserterThread& inserter = static_cast<InserterThread&>( thr );
- nInsertSuccess += inserter.m_nInsertSuccess;
- nInsertFailed += inserter.m_nInsertFailed;
- nTestFunctorRef += inserter.m_nTestFunctorRef;
- }
- break;
- case update_thread:
- {
- UpdaterThread& updater = static_cast<UpdaterThread&>(thr);
- nUpdateCreated += updater.m_nUpdateCreated;
- nUpdateModified += updater.m_nUpdateExisted;
- nUpdateFailed += updater.m_nUpdateFailed;
- nEnsFuncCreated += updater.m_nFunctorCreated;
- nEnsFuncModified += updater.m_nFunctorModified;
- }
- break;
- case delete_thread:
- {
- DeleterThread& deleter = static_cast<DeleterThread&>(thr);
- nDeleteSuccess += deleter.m_nDeleteSuccess;
- nDeleteFailed += deleter.m_nDeleteFailed;
- nDelValueSuccess += deleter.m_nValueSuccess;
- nDelValueFailed += deleter.m_nValueFailed;
- }
- break;
- }
+ cds_test::thread_pool &pool = get_pool();
+ std::unique_ptr<InserterThread> inserter(
+ new InserterThread(pool, testSet));
+ std::unique_ptr<DeleterThread> deleter(
+ new DeleterThread(pool, testSet));
+ std::unique_ptr<UpdaterThread> updater(
+ new UpdaterThread(pool, testSet));
+
+ for (size_t i = 0; i < pass_count; i++) {
+ inserter->test();
+ updater->test();
+ deleter->test();
+ updater->test();
}
- propout()
- << std::make_pair( "insert_success", nInsertSuccess )
- << std::make_pair( "delete_success", nDeleteSuccess )
- << std::make_pair( "insert_failed", nInsertFailed )
- << std::make_pair( "delete_failed", nDeleteFailed )
- << std::make_pair( "update_created", nUpdateCreated )
- << std::make_pair( "update_modified", nUpdateModified )
- << std::make_pair( "update_failed", nUpdateFailed )
- << std::make_pair( "final_set_size", testSet.size());
-
-
- EXPECT_EQ( nDelValueFailed, 0u );
- EXPECT_EQ( nDelValueSuccess, nDeleteSuccess );
-
- EXPECT_EQ( nUpdateFailed, 0u );
- EXPECT_EQ( nUpdateCreated, nEnsFuncCreated );
- EXPECT_EQ( nUpdateModified, nEnsFuncModified );
-
- // nTestFunctorRef is call count of insert functor
- EXPECT_EQ( nTestFunctorRef, nInsertSuccess );
-
- //testSet.clear();
- for ( size_t * p = m_pKeyFirst; p != m_pKeyLast; ++p )
- testSet.erase( *p );
-
+ for (size_t *p = m_pKeyFirst; p != m_pKeyLast; ++p)
+ testSet.erase(*p);
EXPECT_TRUE( testSet.empty());
EXPECT_EQ( testSet.size(), 0u );
-
- additional_check( testSet );
- print_stat( propout(), testSet );
-
- additional_cleanup( testSet );
}
template <class Set>
void run_test()
{
Set s( *this );
- run_test( s );
+ run_test(s, s_nThreadPassCount);
}
template <class Set>
- void run_test2()
+ void run_feldman()
{
Set s( *this );
- run_test( s );
+ run_test(s, s_nFeldmanThreadPassCount);
+ }
- for ( auto it = s.begin(); it != s.end(); ++it )
- std::cout << "key=" << it->key << std::endl;
+ template <class Set>
+ void run_test2()
+ {
+ Set s( *this );
+ run_test( s, s_nThreadPassCount);
}
};
namespace set {
- CDSSTRESS_FeldmanHashSet_fixed( Set_InsDel_func, run_test, size_t, value )
+ CDSSTRESS_FeldmanHashSet_fixed( Set_InsDel_func, run_feldman, size_t, value )
} // namespace set
#define CDSSTRESS_EllenBinTreeSet_RCU( fixture, test_case, key_type, value_type ) \
CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpb, key_type, value_type ) \
- CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpt, key_type, value_type ) \
CDSSTRESS_EllenBinTreeSet_RCU_1( fixture, test_case, key_type, value_type ) \
#define CDSSTRESS_EllenBinTreeSet( fixture, test_case, key_type, value_type ) \
*/
#include "set_type.h"
+#include "../../misc/common.h"
#include <cds/os/topology.h>
namespace set {
Set testSet( *this );
do_test_with( testSet );
- analyze( testSet );
+ DEBUG(analyze( testSet ));
}
template <class Set>
Set testSet( *this );
do_test_extract_with( testSet );
- analyze( testSet );
+ DEBUG(analyze( testSet ));
}
template <class Map>
*/
#include "set_type.h"
+#include "../../misc/common.h"
#include <cds/os/topology.h>
namespace set {
Set testSet( *this );
do_test_with( testSet );
- analyze( testSet );
+ DEBUG(analyze( testSet ));
}
template <class Set>
Set testSet( *this );
do_test_extract_with( testSet );
- analyze( testSet );
+ DEBUG(analyze( testSet ));
}
template <class Map>
*/
#include "set_type.h"
+#include "../../misc/common.h"
#include <cds/os/topology.h>
namespace set {
Set testSet( *this );
do_test_with<Iterator>( testSet );
- analyze( testSet );
+ DEBUG(analyze( testSet ));
}
template <class Set, typename Iterator=typename Set::iterator>
Set testSet( *this );
do_test_extract_with<Iterator>( testSet );
- analyze( testSet );
+ DEBUG(analyze( testSet ));
}
template <class Set>
*/
#include "intrusive_stack_push_pop.h"
+#include "../misc/common.h"
namespace cds_test {
/*static*/ size_t intrusive_stack_push_pop::s_nPushThreadCount = 4;
*/
#include "stack_type.h"
+#include "../misc/common.h"
namespace {
propout() << std::make_pair( "duration", duration );
- analyze( stack );
-
+ DEBUG(analyze( stack ));
propout() << stack.statistics();
}
*/
#include "stack_type.h"
+#include "../misc/common.h"
namespace {
propout() << std::make_pair( "duration", duration );
- analyze( stack );
+ DEBUG(analyze( stack ));
propout() << stack.statistics();
}