MultiLevelHashSet test, bugfixing
[libcds.git] / tests / unit / map2 / map_delodd.h
index 3bafa791bedea6e28e3af5c993fc2f112b6faf99..7c90e6b796b2881537a9a40a4b4bfa1082c80ca3 100644 (file)
@@ -120,10 +120,14 @@ namespace map2 {
         size_t  c_nExtractThreadCount = 4;  // extract thread count
         size_t  c_nMapSize = 1000000;       // max map size
         size_t  c_nMaxLoadFactor = 8;       // maximum load factor
+
         size_t  c_nCuckooInitialSize = 1024;// initial size for CuckooMap
         size_t  c_nCuckooProbesetSize = 16; // CuckooMap probeset size (only for list-based probeset)
         size_t  c_nCuckooProbesetThreshold = 0; // CUckooMap probeset threshold (0 - use default)
 
+        size_t c_nMultiLevelMap_HeadBits = 10;
+        size_t c_nMultiLevelMap_ArrayBits = 4;
+
         bool    c_bPrintGCState = true;
 
         size_t  c_nLoadFactor;  // current load factor
@@ -133,8 +137,6 @@ namespace map2 {
         std::vector<size_t>     m_arrRemove;
 
     protected:
-        typedef CppUnitMini::TestCase Base;
-
         typedef key_thread  key_type;
         typedef size_t      value_type;
         typedef std::pair<key_type const, value_type> pair_type;
@@ -278,6 +280,23 @@ namespace map2 {
             virtual void init() { cds::threading::Manager::attachThread()   ; }
             virtual void fini() { cds::threading::Manager::detachThread()   ; }
 
+            template <typename MapType, bool>
+            struct eraser {
+                static bool erase(MapType& map, size_t key, size_t /*insThread*/)
+                {
+                    return map.erase_with(key, key_less());
+                }
+            };
+
+            template <typename MapType>
+            struct eraser<MapType, true>
+            {
+                static bool erase(MapType& map, size_t key, size_t insThread)
+                {
+                    return map.erase(key_type(key, insThread));
+                }
+            };
+
             virtual void test()
             {
                 Map& rMap = m_Map;
@@ -293,10 +312,20 @@ namespace map2 {
                         for ( size_t k = 0; k < nInsThreadCount; ++k ) {
                             for ( size_t i = 0; i < arrData.size(); ++i ) {
                                 if ( arrData[i] & 1 ) {
-                                    if ( rMap.erase_with( arrData[i], key_less() ))
-                                        ++m_nDeleteSuccess;
-                                    else
-                                        ++m_nDeleteFailed;
+                                    if ( Map::c_bEraseExactKey ) {
+                                        for (size_t key = 0; key < nInsThreadCount; ++key) {
+                                            if ( eraser<Map, Map::c_bEraseExactKey>::erase( rMap, arrData[i], key ))
+                                                ++m_nDeleteSuccess;
+                                            else
+                                                ++m_nDeleteFailed;
+                                        }
+                                    }
+                                    else {
+                                        if ( eraser<Map, Map::c_bEraseExactKey>::erase(rMap, arrData[i], 0) )
+                                            ++m_nDeleteSuccess;
+                                        else
+                                            ++m_nDeleteFailed;
+                                    }
                                 }
                             }
                             if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
@@ -307,10 +336,20 @@ namespace map2 {
                         for ( size_t k = 0; k < nInsThreadCount; ++k ) {
                             for ( size_t i = arrData.size() - 1; i > 0; --i ) {
                                 if ( arrData[i] & 1 ) {
-                                    if ( rMap.erase_with( arrData[i], key_less() ))
-                                        ++m_nDeleteSuccess;
-                                    else
-                                        ++m_nDeleteFailed;
+                                    if ( Map::c_bEraseExactKey ) {
+                                        for (size_t key = 0; key < nInsThreadCount; ++key) {
+                                            if (eraser<Map, Map::c_bEraseExactKey>::erase(rMap, arrData[i], key))
+                                                ++m_nDeleteSuccess;
+                                            else
+                                                ++m_nDeleteFailed;
+                                        }
+                                    }
+                                    else {
+                                        if (eraser<Map, Map::c_bEraseExactKey>::erase(rMap, arrData[i], 0))
+                                            ++m_nDeleteSuccess;
+                                        else
+                                            ++m_nDeleteFailed;
+                                    }
                                 }
                             }
                             if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
@@ -353,6 +392,23 @@ namespace map2 {
             virtual void init() { cds::threading::Manager::attachThread()   ; }
             virtual void fini() { cds::threading::Manager::detachThread()   ; }
 
+            template <typename MapType, bool>
+            struct extractor {
+                static typename Map::guarded_ptr extract(MapType& map, size_t key, size_t /*insThread*/)
+                {
+                    return map.extract_with(key, key_less());
+                }
+            };
+
+            template <typename MapType>
+            struct extractor<MapType, true>
+            {
+                static typename Map::guarded_ptr extract(MapType& map, size_t key, size_t insThread)
+                {
+                    return map.extract(key_type(key, insThread));
+                }
+            };
+
             virtual void test()
             {
                 Map& rMap = m_Map;
@@ -369,7 +425,7 @@ namespace map2 {
                         for ( size_t k = 0; k < nInsThreadCount; ++k ) {
                             for ( size_t i = 0; i < arrData.size(); ++i ) {
                                 if ( arrData[i] & 1 ) {
-                                    gp = rMap.extract_with( arrData[i], key_less());
+                                    gp = extractor< Map, Map::c_bEraseExactKey >::extract( rMap, arrData[i], k );
                                     if ( gp )
                                         ++m_nDeleteSuccess;
                                     else
@@ -385,7 +441,7 @@ namespace map2 {
                         for ( size_t k = 0; k < nInsThreadCount; ++k ) {
                             for ( size_t i = arrData.size() - 1; i > 0; --i ) {
                                 if ( arrData[i] & 1 ) {
-                                    gp = rMap.extract_with( arrData[i], key_less());
+                                    gp = extractor< Map, Map::c_bEraseExactKey >::extract( rMap, arrData[i], k);
                                     if ( gp )
                                         ++m_nDeleteSuccess;
                                     else
@@ -432,6 +488,23 @@ namespace map2 {
             virtual void init() { cds::threading::Manager::attachThread()   ; }
             virtual void fini() { cds::threading::Manager::detachThread()   ; }
 
+            template <typename MapType, bool>
+            struct extractor {
+                static typename Map::exempt_ptr extract( MapType& map, size_t key, size_t /*insThread*/ )
+                {
+                    return map.extract_with( key, key_less());
+                }
+            };
+
+            template <typename MapType>
+            struct extractor<MapType, true>
+            {
+                static typename Map::exempt_ptr extract(MapType& map, size_t key, size_t insThread)
+                {
+                    return map.extract( key_type(key, insThread));
+                }
+            };
+
             virtual void test()
             {
                 Map& rMap = m_Map;
@@ -450,7 +523,7 @@ namespace map2 {
                                 if ( Map::c_bExtractLockExternal ) {
                                     {
                                         typename Map::rcu_lock l;
-                                        xp = rMap.extract_with( arrData[i], key_less() );
+                                        xp = extractor<Map, Map::c_bEraseExactKey>::extract( rMap, arrData[i], k );
                                         if ( xp )
                                             ++m_nDeleteSuccess;
                                         else
@@ -458,7 +531,7 @@ namespace map2 {
                                     }
                                 }
                                 else {
-                                    xp = rMap.extract_with( arrData[i], key_less() );
+                                    xp = extractor<Map, Map::c_bEraseExactKey>::extract( rMap, arrData[i], k);
                                     if ( xp )
                                         ++m_nDeleteSuccess;
                                     else
@@ -478,7 +551,7 @@ namespace map2 {
                                 if ( Map::c_bExtractLockExternal ) {
                                     {
                                         typename Map::rcu_lock l;
-                                        xp = rMap.extract_with( arrData[i], key_less() );
+                                        xp = extractor<Map, Map::c_bEraseExactKey>::extract(rMap, arrData[i], k);
                                         if ( xp )
                                             ++m_nDeleteSuccess;
                                         else
@@ -486,7 +559,7 @@ namespace map2 {
                                     }
                                 }
                                 else {
-                                    xp = rMap.extract_with( arrData[i], key_less() );
+                                    xp = extractor<Map, Map::c_bEraseExactKey>::extract(rMap, arrData[i], k);
                                     if ( xp )
                                         ++m_nDeleteSuccess;
                                     else
@@ -700,20 +773,19 @@ namespace map2 {
         CDSUNIT_DECLARE_SkipListMap
         CDSUNIT_DECLARE_EllenBinTreeMap
         CDSUNIT_DECLARE_BronsonAVLTreeMap
+        CDSUNIT_DECLARE_MultiLevelHashMap_fixed
+        CDSUNIT_DECLARE_MultiLevelHashMap_city
         CDSUNIT_DECLARE_CuckooMap
 
-        // This test is not suitable for MultiLevelHashMap
-        //CDSUNIT_DECLARE_MultiLevelHashMap
-
         CPPUNIT_TEST_SUITE(Map_DelOdd)
             CDSUNIT_TEST_MichaelMap
             CDSUNIT_TEST_SplitList
             CDSUNIT_TEST_SkipListMap
             CDSUNIT_TEST_EllenBinTreeMap
             CDSUNIT_TEST_BronsonAVLTreeMap
+            CDSUNIT_TEST_MultiLevelHashMap_fixed
+            CDSUNIT_TEST_MultiLevelHashMap_city
             CDSUNIT_TEST_CuckooMap
-
-            //CDSUNIT_TEST_MultiLevelHashMap // the test is not suitable
         CPPUNIT_TEST_SUITE_END();
 
         // Not implemented yet