Fix Map_InsDel_func test for FeldmanHashMap
[libcds.git] / tests / unit / map2 / map_insdel_func.h
index 14ca7f282e9b65197ca5132997a8a1e6279ac8a7..76f59246407b829d5ca0de4158a251f091fecd7d 100644 (file)
@@ -27,8 +27,8 @@ namespace map2 {
         size_t c_nCuckooProbesetSize = 16; // CuckooMap probeset size (only for list-based probeset)
         size_t c_nCuckooProbesetThreshold = 0; // CUckooMap probeset threshold (o - use default)
 
-        size_t c_nMultiLevelMap_HeadBits = 10;
-        size_t c_nMultiLevelMap_ArrayBits = 4;
+        size_t c_nFeldmanMap_HeadBits = 10;
+        size_t c_nFeldmanMap_ArrayBits = 4;
 
         size_t  c_nLoadFactor;  // current load factor
 
@@ -39,7 +39,7 @@ namespace map2 {
             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;
@@ -49,15 +49,15 @@ namespace map2 {
                 , 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 =
@@ -101,7 +101,7 @@ namespace map2 {
                 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;
@@ -151,7 +151,7 @@ namespace map2 {
                 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;
@@ -161,7 +161,7 @@ namespace map2 {
                 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;
@@ -195,7 +195,7 @@ namespace map2 {
                 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;
@@ -203,6 +203,7 @@ namespace map2 {
                         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;
                     }
@@ -214,11 +215,13 @@ namespace map2 {
                     operator()( bNew, val.first, val.second );
                 }
 
-                // For MultiLevelHashMap
+                // For FeldmanHashMap
                 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:
@@ -266,8 +269,7 @@ namespace map2 {
                 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;
@@ -282,7 +284,7 @@ namespace map2 {
                 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;
@@ -394,7 +396,7 @@ namespace map2 {
                     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;
@@ -405,7 +407,7 @@ namespace map2 {
                     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;
@@ -432,14 +434,14 @@ namespace map2 {
             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;
@@ -507,8 +509,8 @@ namespace map2 {
             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 );
@@ -550,7 +552,8 @@ namespace map2 {
         CDSUNIT_DECLARE_SkipListMap
         CDSUNIT_DECLARE_EllenBinTreeMap
         CDSUNIT_DECLARE_BronsonAVLTreeMap
-        CDSUNIT_DECLARE_MultiLevelHashMap
+        CDSUNIT_DECLARE_FeldmanHashMap_fixed
+        CDSUNIT_DECLARE_FeldmanHashMap_city
         CDSUNIT_DECLARE_StripedMap
         CDSUNIT_DECLARE_RefinableMap
         CDSUNIT_DECLARE_CuckooMap
@@ -561,7 +564,8 @@ namespace map2 {
             CDSUNIT_TEST_SkipListMap
             CDSUNIT_TEST_EllenBinTreeMap
             CDSUNIT_TEST_BronsonAVLTreeMap
-            CDSUNIT_TEST_MultiLevelHashMap
+            CDSUNIT_TEST_FeldmanHashMap_fixed
+            CDSUNIT_TEST_FeldmanHashMap_city
             CDSUNIT_TEST_CuckooMap
             CDSUNIT_TEST_StripedMap
             CDSUNIT_TEST_RefinableMap