size_t nData;
atomics::atomic<size_t> nUpdateCall;
atomics::atomic<bool> bInitialized;
- cds::OS::ThreadId threadId ; // insert thread id
+ cds::OS::ThreadId threadId; // inserter thread id
typedef cds::sync::spin_lock< cds::backoff::pause > lock_type;
mutable lock_type m_access;
, nData(0)
, nUpdateCall(0)
, bInitialized( false )
- , threadId( cds::OS::get_current_thread_id() )
+ , threadId( cds::OS::get_current_thread_id())
{}
value_type( value_type const& s )
: nKey(s.nKey)
, nData(s.nData)
, nUpdateCall(s.nUpdateCall.load(atomics::memory_order_relaxed))
- , bInitialized( s.bInitialized.load(atomics::memory_order_relaxed) )
- , threadId( cds::OS::get_current_thread_id() )
+ , bInitialized( s.bInitialized.load(atomics::memory_order_relaxed))
+ , threadId( cds::OS::get_current_thread_id())
{}
// boost::container::flat_map requires operator =
template <typename Key, typename Val >
void operator()( Key const& key, Val& v )
{
- std::unique_lock< typename value_type::lock_type> ac( v.m_access );
+ std::unique_lock< typename value_type::lock_type> ac( v.m_access );
v.nKey = key;
v.nData = key * 8;
if ( m_nThreadNo & 1 ) {
for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
- if ( rMap.insert_with( *it, std::ref(func) ) )
+ if ( rMap.insert_with( *it, std::ref(func)))
++m_nInsertSuccess;
else
++m_nInsertFailed;
else {
for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
- if ( rMap.insert_with( *it, std::ref(func) ) )
+ if ( rMap.insert_with( *it, std::ref(func)))
++m_nInsertSuccess;
else
++m_nInsertFailed;
template <typename Key, typename Val>
void operator()( bool bNew, Key const& key, Val& v )
{
- std::unique_lock<typename value_type::lock_type> ac( v.m_access );
+ std::unique_lock<typename value_type::lock_type> ac( v.m_access );
if ( bNew ) {
++nCreated;
v.nKey = key;
v.bInitialized.store( true, atomics::memory_order_relaxed);
}
else {
+ assert( v.bInitialized.load( atomics::memory_order_relaxed ));
v.nUpdateCall.fetch_add( 1, atomics::memory_order_relaxed );
++nModified;
}
template <typename Val>
void operator()( Val& cur, Val * old )
{
- operator()( old != nullptr, cur.first, cur.second );
+ if ( old )
+ cur.second.bInitialized.store( true, atomics::memory_order_release );
+ operator()( old == nullptr, cur.first, cur.second );
}
private:
if ( m_nThreadNo & 1 ) {
for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
- //for ( size_t nItem = 0; nItem < c_nMapSize; ++nItem ) {
- std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ) );
+ std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ));
if ( ret.first ) {
if ( ret.second )
++m_nUpdateCreated;
else {
for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
- std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ) );
+ std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ));
if ( ret.first ) {
if ( ret.second )
++m_nUpdateCreated;
for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
func.m_cnt.nKeyExpected = *it;
- if ( rMap.erase( *it, std::ref(func) ))
+ if ( rMap.erase( *it, std::ref(func)))
++m_nDeleteSuccess;
else
++m_nDeleteFailed;
for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
func.m_cnt.nKeyExpected = *it;
- if ( rMap.erase( *it, std::ref(func) ))
+ if ( rMap.erase( *it, std::ref(func)))
++m_nDeleteSuccess;
else
++m_nDeleteFailed;
m_arrValues.reserve( c_nMapSize );
for ( size_t i = 0; i < c_nMapSize; ++i )
m_arrValues.push_back( i );
- shuffle( m_arrValues.begin(), m_arrValues.end() );
+ shuffle( m_arrValues.begin(), m_arrValues.end());
CppUnitMini::ThreadPool pool( *this );
pool.add( new InserterThread( pool, testMap ), c_nInsertThreadCount );
pool.add( new DeleterThread( pool, testMap ), c_nDeleteThreadCount );
pool.add( new UpdaterThread( pool, testMap ), c_nUpdateThreadCount );
pool.run();
- CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
+ CPPUNIT_MSG( " Duration=" << pool.avgDuration());
size_t nInsertSuccess = 0;
size_t nInsertFailed = 0;
size_t nUpdateModified = 0;
size_t nEnsFuncCreated = 0;
size_t nEnsFuncModified = 0;
- size_t nTestFunctorRef = 0;
+ size_t nInsFuncCalled = 0;
for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
if ( pThread ) {
nInsertSuccess += pThread->m_nInsertSuccess;
nInsertFailed += pThread->m_nInsertFailed;
- nTestFunctorRef += pThread->m_nTestFunctorRef;
+ nInsFuncCalled += pThread->m_nTestFunctorRef;
}
else {
DeleterThread * p = dynamic_cast<DeleterThread *>( *it );
CPPUNIT_CHECK_EX( nUpdateCreated == nEnsFuncCreated, "Update created=" << nUpdateCreated << " functor=" << nEnsFuncCreated );
CPPUNIT_CHECK_EX( nUpdateModified == nEnsFuncModified, "Update modified=" << nUpdateModified << " functor=" << nEnsFuncModified );
- // nTestFunctorRef is call count of insert functor
- CPPUNIT_CHECK_EX( nTestFunctorRef == nInsertSuccess, "nInsertSuccess=" << nInsertSuccess << " functor nTestFunctorRef=" << nTestFunctorRef );
+ // nInsFuncCalled is call count of insert functor
+ CPPUNIT_CHECK_EX( nInsFuncCalled == nInsertSuccess, "nInsertSuccess=" << nInsertSuccess << " functor nInsFuncCalled=" << nInsFuncCalled );
check_before_cleanup( testMap );
for ( size_t nItem = 0; nItem < c_nMapSize; ++nItem ) {
testMap.erase( nItem );
}
- CPPUNIT_MSG( " Duration=" << timer.duration() );
- CPPUNIT_CHECK( testMap.empty() );
+ CPPUNIT_MSG( " Duration=" << timer.duration());
+ CPPUNIT_CHECK( testMap.empty());
additional_check( testMap );
print_stat( testMap );