add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_func)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_string)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/iteration)
-add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/iter_erase)
+#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/iter_erase)
add_custom_target( stress-sequential-set
DEPENDS
stress-sequential-set-insdel-func
stress-sequential-set-insdel-string
stress-sequential-set-iteration
- stress-sequential-set-iter-erase
+ #stress-sequential-set-iter-erase
)
size_t Set_InsDel_string::s_nInsertThreadCount = 4; // count of insertion thread
size_t Set_InsDel_string::s_nDeleteThreadCount = 4; // count of deletion thread
size_t Set_InsDel_string::s_nThreadPassCount = 4; // pass count for each thread
+ size_t Set_InsDel_string::s_nFeldmanThreadPassCount = 4; // pass count for Feldman
+ size_t Set_InsDel_string::s_nSkiplistThreadPassCount = 4; // pass count for Skiplist
size_t Set_InsDel_string::s_nMaxLoadFactor = 8; // maximum load factor
size_t Set_InsDel_string::s_nCuckooInitialSize = 1024;// initial size for CuckooSet
void Set_InsDel_string::SetUpTestCase()
{
- cds_test::config const& cfg = get_config( "map_insdel_string" );
+ cds_test::config const& cfg = get_config( "sequential_map_insdel_string" );
s_nSetSize = cfg.get_size_t( "MapSize", s_nSetSize );
if ( s_nSetSize < 1000 )
if ( s_nThreadPassCount == 0 )
s_nThreadPassCount = 4;
- s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+ s_nFeldmanThreadPassCount =
+ cfg.get_size_t("FeldmanThreadPassCount", s_nFeldmanThreadPassCount);
+ if (s_nFeldmanThreadPassCount == 0)
+ s_nFeldmanThreadPassCount = 4;
+
+ s_nSkiplistThreadPassCount = cfg.get_size_t("SkiplistThreadPassCount",
+ s_nSkiplistThreadPassCount);
+ if (s_nSkiplistThreadPassCount == 0)
+ s_nSkiplistThreadPassCount = 4;
+
+ s_nMaxLoadFactor = cfg.get_size_t("MaxLoadFactor", s_nMaxLoadFactor);
if ( s_nMaxLoadFactor == 0 )
s_nMaxLoadFactor = 1;
static size_t s_nInsertThreadCount; // count of insertion thread
static size_t s_nDeleteThreadCount; // count of deletion thread
static size_t s_nThreadPassCount; // pass count for each thread
+ static size_t s_nFeldmanThreadPassCount; // pass count for Feldman
+ static size_t s_nSkiplistThreadPassCount; // pass count for Skiplist
static size_t s_nMaxLoadFactor; // maximum load factor
static size_t s_nCuckooInitialSize; // initial size for CuckooSet
size_t const nSetSize = fixture.s_nSetSize;
size_t const nPassCount = fixture.s_nThreadPassCount;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
- if ( rSet.insert( keyval_type( m_arrString[nItem % nArrSize], nItem * 8 )))
- ++m_nInsertSuccess;
- else
- ++m_nInsertFailed;
- }
- }
- }
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
- if ( rSet.insert( keyval_type( m_arrString[nItem % nArrSize], nItem * 8 )))
- ++m_nInsertSuccess;
- else
- ++m_nInsertFailed;
- }
- }
+ for (size_t nPass = 0; nPass < nPassCount; ++nPass) {
+ for (size_t nItem = 0; nItem < nSetSize; ++nItem) {
+ if (rSet.insert(keyval_type(m_arrString[nItem % nArrSize],
+ nItem * 8)))
+ ++m_nInsertSuccess;
+ else
+ ++m_nInsertFailed;
+ }
}
}
};
size_t const nSetSize = fixture.s_nSetSize;
size_t const nPassCount = fixture.s_nThreadPassCount;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
- if ( rSet.erase( m_arrString[nItem % nArrSize] ))
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- }
- }
- }
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
- if ( rSet.erase( m_arrString[nItem % nArrSize] ))
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- }
- }
+ for (size_t nPass = 0; nPass < nPassCount; ++nPass) {
+ for (size_t nItem = 0; nItem < nSetSize; ++nItem) {
+ if (rSet.erase(m_arrString[nItem % nArrSize]))
+ ++m_nDeleteSuccess;
+ else
+ ++m_nDeleteFailed;
+ }
}
}
};
size_t const nSetSize = fixture.s_nSetSize;
size_t const nPassCount = fixture.s_nThreadPassCount;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
- gp = rSet.extract( m_arrString[nItem % nArrSize] );
- if ( gp )
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- gp.release();
- }
- }
- }
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
- gp = rSet.extract( m_arrString[nItem % nArrSize] );
- if ( gp )
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- gp.release();
- }
- }
+ for (size_t nPass = 0; nPass < nPassCount; ++nPass) {
+ for (size_t nItem = 0; nItem < nSetSize; ++nItem) {
+ gp = rSet.extract(m_arrString[nItem % nArrSize]);
+ if (gp)
+ ++m_nDeleteSuccess;
+ else
+ ++m_nDeleteFailed;
+ gp.release();
+ }
}
}
};
typedef Deleter<Set> DeleterThread;
typedef Extractor<typename Set::gc, Set> ExtractThread;
- size_t const nDelThreadCount = s_nDeleteThreadCount / 2;
- size_t const nExtractThreadCount = s_nDeleteThreadCount - nDelThreadCount;
-
cds_test::thread_pool& pool = get_pool();
- pool.add( new InserterThread( pool, testSet ), s_nInsertThreadCount );
- pool.add( new DeleterThread( pool, testSet ), nDelThreadCount );
- pool.add( new ExtractThread( pool, testSet ), nExtractThreadCount );
-
- propout() << std::make_pair( "insert_thread_count", s_nInsertThreadCount )
- << std::make_pair( "delete_thread_count", nDelThreadCount )
- << std::make_pair( "extract_thread_count", nExtractThreadCount )
- << 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 nExtractSuccess = 0;
- size_t nExtractFailed = 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;
- }
- break;
- case delete_thread:
- {
- DeleterThread& deleter = static_cast<DeleterThread&>(thr);
- nDeleteSuccess += deleter.m_nDeleteSuccess;
- nDeleteFailed += deleter.m_nDeleteFailed;
- }
- break;
- case extract_thread:
- {
- ExtractThread& extractor = static_cast<ExtractThread&>(thr);
- nExtractSuccess += extractor.m_nDeleteSuccess;
- nExtractFailed += extractor.m_nDeleteFailed;
- }
- break;
- default:
- assert( false ); // Forgot anything?..
- }
- }
-
- propout()
- << std::make_pair( "insert_success", nInsertSuccess )
- << std::make_pair( "delete_success", nDeleteSuccess )
- << std::make_pair( "extract_success", nExtractSuccess )
- << std::make_pair( "insert_failed", nInsertFailed )
- << std::make_pair( "delete_failed", nDeleteFailed )
- << std::make_pair( "extract_failed", nExtractFailed )
- << std::make_pair( "final_set_size", testSet.size());
-
- //testSet.clear();
- for ( auto const& str : m_arrString )
- testSet.erase( str );
- EXPECT_TRUE( testSet.empty());
- EXPECT_EQ( testSet.size(), 0u );
- additional_check( testSet );
- print_stat( propout(), testSet );
- additional_cleanup( testSet );
+ std::unique_ptr<InserterThread> inserter(
+ new InserterThread(pool, testSet));
+ std::unique_ptr<DeleterThread> deleter(
+ new DeleterThread(pool, testSet));
+ std::unique_ptr<ExtractThread> extractor(
+ new ExtractThread(pool, testSet));
+
+ inserter->test();
+ deleter->test();
+ inserter->test();
+ extractor->test();
+
+ for (auto const &str : m_arrString)
+ testSet.erase(str);
+ additional_cleanup(testSet);
}
template <class Set>
Set s( *this );
do_test_extract( s );
}
+
+ template <class Set>
+ void run_feldman()
+ {
+ Set_InsDel_string::s_nThreadPassCount =
+ Set_InsDel_string::s_nFeldmanThreadPassCount;
+ run_test_extract<Set>();
+ }
+
+ template <class Set>
+ void run_skiplist()
+ {
+ Set_InsDel_string::s_nThreadPassCount =
+ Set_InsDel_string::s_nSkiplistThreadPassCount;
+ run_test_extract<Set>();
+ }
};
class Set_InsDel_string_LF: public Set_InsDel_string
namespace set {
- CDSSTRESS_FeldmanHashSet_stdhash( Set_InsDel_string, run_test_extract, std::string, size_t )
- CDSSTRESS_FeldmanHashSet_city( Set_InsDel_string, run_test_extract, std::string, size_t )
+ CDSSTRESS_FeldmanHashSet_stdhash( Set_InsDel_string, run_feldman, std::string, size_t )
+ CDSSTRESS_FeldmanHashSet_city( Set_InsDel_string, run_feldman, std::string, size_t )
} // namespace set
namespace set {
- CDSSTRESS_SkipListSet( Set_InsDel_string, run_test_extract, std::string, size_t )
+ CDSSTRESS_SkipListSet( Set_InsDel_string, run_skiplist, std::string, size_t )
} // namespace set
void Set_Iteration::SetUpTestCase()
{
- cds_test::config const& cfg = get_config( "map_insdel_string" );
+ cds_test::config const& cfg = get_config( "sequential_map_iteration" );
s_nSetSize = cfg.get_size_t( "MapSize", s_nSetSize );
if ( s_nSetSize < 1000 )
std::vector<size_t> Set_Iteration_LF::get_load_factors()
{
- cds_test::config const& cfg = get_config( "map_insdel_string" );
+ cds_test::config const& cfg = get_config( "sequential_map_insdel_string" );
s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
if ( s_nMaxLoadFactor == 0 )
size_t const nSetSize = fixture.s_nSetSize;
size_t const nPassCount = fixture.s_nThreadPassCount;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
- if ( rSet.insert( keyval_type( m_arrString[nItem % nArrSize], nItem * 8 )))
- ++m_nInsertSuccess;
- else
- ++m_nInsertFailed;
- }
- }
+ for (size_t nPass = 0; nPass < nPassCount; ++nPass) {
+ for (size_t nItem = 0; nItem < nSetSize; ++nItem) {
+ if (rSet.insert(keyval_type(m_arrString[nItem % nArrSize],
+ nItem * 8)))
+ ++m_nInsertSuccess;
+ else
+ ++m_nInsertFailed;
+ }
}
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
- if ( rSet.insert( keyval_type( m_arrString[nItem % nArrSize], nItem * 8 )))
- ++m_nInsertSuccess;
- else
- ++m_nInsertFailed;
- }
- }
- }
-
- fixture.on_modifier_done();
}
};
size_t const nSetSize = fixture.s_nSetSize;
size_t const nPassCount = fixture.s_nThreadPassCount;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
- if ( rSet.erase( m_arrString[nItem % nArrSize] ))
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- }
- }
+ for (size_t nPass = 0; nPass < nPassCount; ++nPass) {
+ for (size_t nItem = 0; nItem < nSetSize; ++nItem) {
+ if (rSet.erase(m_arrString[nItem % nArrSize]))
+ ++m_nDeleteSuccess;
+ else
+ ++m_nDeleteFailed;
+ }
}
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
- if ( rSet.erase( m_arrString[nItem % nArrSize] ))
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- }
- }
- }
-
- fixture.on_modifier_done();
}
};
size_t const nSetSize = fixture.s_nSetSize;
size_t const nPassCount = fixture.s_nThreadPassCount;
- if ( id() & 1 ) {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = 0; nItem < nSetSize; ++nItem ) {
- gp = rSet.extract( m_arrString[nItem % nArrSize] );
- if ( gp )
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- gp.release();
- }
- }
+ for (size_t nPass = 0; nPass < nPassCount; ++nPass) {
+ for (size_t nItem = 0; nItem < nSetSize; ++nItem) {
+ gp = rSet.extract(m_arrString[nItem % nArrSize]);
+ if (gp)
+ ++m_nDeleteSuccess;
+ else
+ ++m_nDeleteFailed;
+ gp.release();
+ }
}
- else {
- for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
- for ( size_t nItem = nSetSize; nItem > 0; --nItem ) {
- gp = rSet.extract( m_arrString[nItem % nArrSize] );
- if ( gp )
- ++m_nDeleteSuccess;
- else
- ++m_nDeleteFailed;
- gp.release();
- }
- }
- }
-
- fixture.on_modifier_done();
}
};
Set& rSet = m_Set;
Set_Iteration& fixture = pool().template fixture<Set_Iteration>();
- while ( !fixture.all_modifiers_done()) {
- ++m_nPassCount;
- typename Set::iterator it;
- typename Set::iterator itEnd;
- itEnd = rSet.end();
- for ( it = rSet.begin(); it != itEnd; ++it ) {
+ typename Set::iterator it;
+ typename Set::iterator itEnd;
+ itEnd = rSet.end();
+ for (it = rSet.begin(); it != itEnd; ++it) {
#if CDS_BUILD_BITS == 64
- it->val.hash = CityHash64( it->key.c_str(), it->key.length());
+ it->val.hash = CityHash64(it->key.c_str(), it->key.length());
#else
- it->val.hash = std::hash<std::string>()( it->key );
+ it->val.hash = std::hash<std::string>()(it->key);
#endif
- ++m_nVisitCount;
- }
+ ++m_nVisitCount;
}
}
};
Set& rSet = m_Set;
Set_Iteration& fixture = pool().template fixture<Set_Iteration>();
- while ( !fixture.all_modifiers_done()) {
- ++m_nPassCount;
- typename Set::rcu_lock l;
- for ( auto it = rSet.begin(); it != rSet.end(); ++it ) {
+ typename Set::rcu_lock l;
+ for (auto it = rSet.begin(); it != rSet.end(); ++it) {
#if CDS_BUILD_BITS == 64
- it->val.hash = CityHash64( it->key.c_str(), it->key.length());
+ it->val.hash = CityHash64(it->key.c_str(), it->key.length());
#else
- it->val.hash = std::hash<std::string>()(it->key);
+ it->val.hash = std::hash<std::string>()(it->key);
#endif
- ++m_nVisitCount;
- }
+ ++m_nVisitCount;
}
- }
+ }
};
protected:
typedef Extractor<typename Set::gc, Set> ExtractThread;
typedef Iterator<typename Set::gc, Set> IteratorThread;
- size_t const nDelThreadCount = s_nDeleteThreadCount / 2;
- size_t const nExtractThreadCount = s_nDeleteThreadCount - nDelThreadCount;
-
cds_test::thread_pool& pool = get_pool();
- pool.add( new InserterThread( pool, testSet ), s_nInsertThreadCount );
- pool.add( new DeleterThread( pool, testSet ), nDelThreadCount );
- pool.add( new ExtractThread( pool, testSet ), nExtractThreadCount );
- m_nModifierCount.store( pool.size(), atomics::memory_order_relaxed );
- pool.add( new IteratorThread( pool, testSet ), 1 );
-
- propout() << std::make_pair( "insert_thread_count", s_nInsertThreadCount )
- << std::make_pair( "delete_thread_count", nDelThreadCount )
- << std::make_pair( "extract_thread_count", nExtractThreadCount )
- << 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 nExtractSuccess = 0;
- size_t nExtractFailed = 0;
- size_t nIteratorPassCount = 0;
- size_t nIteratorVisitCount = 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;
- }
- break;
- case delete_thread:
- {
- DeleterThread& deleter = static_cast<DeleterThread&>(thr);
- nDeleteSuccess += deleter.m_nDeleteSuccess;
- nDeleteFailed += deleter.m_nDeleteFailed;
- }
- break;
- case extract_thread:
- {
- ExtractThread& extractor = static_cast<ExtractThread&>(thr);
- nExtractSuccess += extractor.m_nDeleteSuccess;
- nExtractFailed += extractor.m_nDeleteFailed;
- }
- break;
- case iterator_thread:
- {
- IteratorThread& iter = static_cast<IteratorThread&>(thr);
- nIteratorPassCount += iter.m_nPassCount;
- nIteratorVisitCount += iter.m_nVisitCount;
- }
- break;
- default:
- assert( false ); // Forgot anything?..
- }
- }
-
- propout()
- << std::make_pair( "insert_success", nInsertSuccess )
- << std::make_pair( "delete_success", nDeleteSuccess )
- << std::make_pair( "extract_success", nExtractSuccess )
- << std::make_pair( "insert_failed", nInsertFailed )
- << std::make_pair( "delete_failed", nDeleteFailed )
- << std::make_pair( "extract_failed", nExtractFailed )
- << std::make_pair( "iterator_pass_count", nIteratorPassCount )
- << std::make_pair( "iterator_visit_count", nIteratorVisitCount )
- << std::make_pair( "final_set_size", testSet.size());
+ std::unique_ptr<InserterThread> inserter(
+ new InserterThread(pool, testSet));
+ std::unique_ptr<DeleterThread> deleter(
+ new DeleterThread(pool, testSet));
+ std::unique_ptr<ExtractThread> extractor(
+ new ExtractThread(pool, testSet));
+ std::unique_ptr<IteratorThread> iterator(
+ new IteratorThread(pool, testSet));
+
+ inserter->test();
+ iterator->test();
+ deleter->test();
+ iterator->test();
+ extractor->test();
+ iterator->test();
testSet.clear();
- EXPECT_TRUE( testSet.empty());
-
- additional_check( testSet );
- print_stat( propout(), testSet );
additional_cleanup( testSet );
}
#define CDSSTRESS_FeldmanHashSet_stdhash_RCU( fixture, test_case, key_type, value_type ) \
CDSSTRESS_FeldmanHashSet_case( fixture, test_case, FeldmanHashSet_rcu_gpb_stdhash, key_type, value_type ) \
- CDSSTRESS_FeldmanHashSet_case( fixture, test_case, FeldmanHashSet_rcu_gpt_stdhash, key_type, value_type ) \
//CDSSTRESS_FeldmanHashSet_stdhash_SHRCU( fixture, test_case, key_type, value_type )
# define CDSSTRESS_FeldmanHashSet_city_RCU( fixture, test_case, key_type, value_type ) \
CDSSTRESS_FeldmanHashSet_case( fixture, test_case, FeldmanHashSet_rcu_gpb_city64, key_type, value_type ) \
- CDSSTRESS_FeldmanHashSet_case( fixture, test_case, FeldmanHashSet_rcu_gpt_city64, key_type, value_type ) \
CDSSTRESS_FeldmanHashSet_case( fixture, test_case, FeldmanHashSet_rcu_gpb_city128, key_type, value_type ) \
- CDSSTRESS_FeldmanHashSet_case( fixture, test_case, FeldmanHashSet_rcu_gpt_city128, key_type, value_type ) \
//CDSSTRESS_FeldmanHashSet_city_SHRCU( fixture, test_case, key_type, value_type )