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);
}
};