From f1b4634363bd389efd72206d3f26fa4ff3daac36 Mon Sep 17 00:00:00 2001
From: khizmax <libcds.dev@gmail.com>
Date: Sat, 5 Sep 2015 18:57:42 +0300
Subject: [PATCH] Refactored Map_InsDel_string MT-test

---
 projects/Win/vc12/unit-map-insdel.vcxproj     |   2 +-
 .../Win/vc12/unit-map-insdel.vcxproj.filters  |   6 +-
 projects/source.unit.map.mk                   |  17 +--
 tests/data/test-debug.conf                    |   8 +
 tests/data/test-express.conf                  |   8 +
 tests/data/test.conf                          |   8 +
 tests/unit/map2/CMakeLists.txt                |   9 +-
 tests/unit/map2/map_insdel_int.h              |   1 -
 tests/unit/map2/map_insdel_string.cpp         |  30 ++--
 tests/unit/map2/map_insdel_string.h           | 140 ++++++++++--------
 .../map2/map_insdel_string_bronsonavltree.cpp |  10 +-
 tests/unit/map2/map_insdel_string_cuckoo.cpp  |  10 +-
 .../unit/map2/map_insdel_string_ellentree.cpp |  10 +-
 tests/unit/map2/map_insdel_string_michael.cpp |  10 +-
 .../map_insdel_string_multilevelhashmap.cpp   |  12 ++
 .../unit/map2/map_insdel_string_refinable.cpp |  12 --
 tests/unit/map2/map_insdel_string_skip.cpp    |  10 +-
 tests/unit/map2/map_insdel_string_split.cpp   |  10 +-
 tests/unit/map2/map_insdel_string_std.cpp     |  10 +-
 tests/unit/map2/map_insdel_string_striped.cpp |  11 +-
 20 files changed, 177 insertions(+), 157 deletions(-)
 create mode 100644 tests/unit/map2/map_insdel_string_multilevelhashmap.cpp
 delete mode 100644 tests/unit/map2/map_insdel_string_refinable.cpp

diff --git a/projects/Win/vc12/unit-map-insdel.vcxproj b/projects/Win/vc12/unit-map-insdel.vcxproj
index fd0ee80b..11d74752 100644
--- a/projects/Win/vc12/unit-map-insdel.vcxproj
+++ b/projects/Win/vc12/unit-map-insdel.vcxproj
@@ -67,7 +67,7 @@
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_cuckoo.cpp" />
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_ellentree.cpp" />
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_michael.cpp" />
-    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_refinable.cpp" />
+    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_multilevelhashmap.cpp" />
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_skip.cpp" />
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_split.cpp" />
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_std.cpp" />
diff --git a/projects/Win/vc12/unit-map-insdel.vcxproj.filters b/projects/Win/vc12/unit-map-insdel.vcxproj.filters
index c22d583e..0818ac7a 100644
--- a/projects/Win/vc12/unit-map-insdel.vcxproj.filters
+++ b/projects/Win/vc12/unit-map-insdel.vcxproj.filters
@@ -64,9 +64,6 @@
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_michael.cpp">
       <Filter>map_insdel_string</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_refinable.cpp">
-      <Filter>map_insdel_string</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_skip.cpp">
       <Filter>map_insdel_string</Filter>
     </ClCompile>
@@ -88,6 +85,9 @@
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_multilevelhashmap.cpp">
       <Filter>map_insdel_func</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_string_multilevelhashmap.cpp">
+      <Filter>map_insdel_string</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="map_insdel_func">
diff --git a/projects/source.unit.map.mk b/projects/source.unit.map.mk
index 2264a10a..93749f10 100644
--- a/projects/source.unit.map.mk
+++ b/projects/source.unit.map.mk
@@ -59,23 +59,22 @@ CDSUNIT_MAP_SOURCES := \
     tests/unit/map2/map_insdel_item_int_refinable.cpp \
     tests/unit/map2/map_insdel_item_int_cuckoo.cpp \
     tests/unit/map2/map_insdel_item_string.cpp \
+    tests/unit/map2/map_insdel_item_string_bronsonavltree.cpp \
+    tests/unit/map2/map_insdel_item_string_cuckoo.cpp \
+    tests/unit/map2/map_insdel_item_string_ellentree.cpp \
     tests/unit/map2/map_insdel_item_string_michael.cpp \
-    tests/unit/map2/map_insdel_item_string_split.cpp \
     tests/unit/map2/map_insdel_item_string_skip.cpp \
-    tests/unit/map2/map_insdel_item_string_ellentree.cpp \
-    tests/unit/map2/map_insdel_item_string_bronsonavltree.cpp \
+    tests/unit/map2/map_insdel_item_string_split.cpp \
     tests/unit/map2/map_insdel_item_string_striped.cpp \
     tests/unit/map2/map_insdel_item_string_refinable.cpp \
-    tests/unit/map2/map_insdel_item_string_cuckoo.cpp \
     tests/unit/map2/map_insdel_string.cpp \
+    tests/unit/map2/map_insdel_string_bronsonavltree.cpp \
+    tests/unit/map2/map_insdel_string_cuckoo.cpp \
+    tests/unit/map2/map_insdel_string_ellentree.cpp \
     tests/unit/map2/map_insdel_string_michael.cpp \
-    tests/unit/map2/map_insdel_string_split.cpp \
     tests/unit/map2/map_insdel_string_skip.cpp \
-    tests/unit/map2/map_insdel_string_ellentree.cpp \
-    tests/unit/map2/map_insdel_string_bronsonavltree.cpp \
+    tests/unit/map2/map_insdel_string_split.cpp \
     tests/unit/map2/map_insdel_string_striped.cpp \
-    tests/unit/map2/map_insdel_string_refinable.cpp \
-    tests/unit/map2/map_insdel_string_cuckoo.cpp \
     tests/unit/map2/map_insdel_string_std.cpp \
     tests/unit/map2/map_insdelfind.cpp \
     tests/unit/map2/map_insdelfind_michael.cpp \
diff --git a/tests/data/test-debug.conf b/tests/data/test-debug.conf
index 304feb9d..d9a924f9 100644
--- a/tests/data/test-debug.conf
+++ b/tests/data/test-debug.conf
@@ -179,6 +179,14 @@ ThreadPassCount=8
 MapSize=10000
 MaxLoadFactor=4
 PrintGCStateFlag=1
+# *** Cuckoo map properties
+CuckooInitialSize=256
+CuckooProbesetSize=8
+# 0 - use default
+CuckooProbesetThreshold=0 
+# *** MultiLevelHashMap properties
+MultiLevelMapHeadBits=8
+MultiLevelMapArrayBits=4
 
 [Map_InsDel_Item_string]
 ThreadCount=4
diff --git a/tests/data/test-express.conf b/tests/data/test-express.conf
index 929420ce..27e8f232 100644
--- a/tests/data/test-express.conf
+++ b/tests/data/test-express.conf
@@ -177,6 +177,14 @@ ThreadPassCount=2
 MapSize=100000
 MaxLoadFactor=4
 PrintGCStateFlag=1
+# *** Cuckoo map properties
+CuckooInitialSize=1024
+CuckooProbesetSize=16
+# 0 - use default
+CuckooProbesetThreshold=0 
+# *** MultiLevelHashMap properties
+MultiLevelMapHeadBits=8
+MultiLevelMapArrayBits=4
 
 [Map_InsDel_Item_string]
 ThreadCount=8
diff --git a/tests/data/test.conf b/tests/data/test.conf
index d5be15c3..e2703951 100644
--- a/tests/data/test.conf
+++ b/tests/data/test.conf
@@ -172,6 +172,14 @@ ThreadPassCount=2
 MapSize=500000
 MaxLoadFactor=4
 PrintGCStateFlag=1
+# *** Cuckoo map properties
+CuckooInitialSize=1024
+CuckooProbesetSize=16
+# 0 - use default
+CuckooProbesetThreshold=0 
+# *** MultiLevelHashMap properties
+MultiLevelMapHeadBits=10
+MultiLevelMapArrayBits=4
 
 [Map_InsDel_Item_string]
 ThreadCount=8
diff --git a/tests/unit/map2/CMakeLists.txt b/tests/unit/map2/CMakeLists.txt
index 95fc4fb5..98194774 100644
--- a/tests/unit/map2/CMakeLists.txt
+++ b/tests/unit/map2/CMakeLists.txt
@@ -69,14 +69,13 @@ set(CDSUNIT_MAP_SOURCES
     map_insdel_item_string_refinable.cpp
     map_insdel_item_string_cuckoo.cpp
     map_insdel_string.cpp
+    map_insdel_string_bronsonavltree.cpp
+    map_insdel_string_cuckoo.cpp
+    map_insdel_string_ellentree.cpp
     map_insdel_string_michael.cpp
-    map_insdel_string_split.cpp
     map_insdel_string_skip.cpp
-    map_insdel_string_ellentree.cpp
-    map_insdel_string_bronsonavltree.cpp
+    map_insdel_string_split.cpp
     map_insdel_string_striped.cpp
-    map_insdel_string_refinable.cpp
-    map_insdel_string_cuckoo.cpp
     map_insdel_string_std.cpp
     map_insdelfind.cpp
     map_insdelfind_michael.cpp
diff --git a/tests/unit/map2/map_insdel_int.h b/tests/unit/map2/map_insdel_int.h
index c6130a05..a47738fd 100644
--- a/tests/unit/map2/map_insdel_int.h
+++ b/tests/unit/map2/map_insdel_int.h
@@ -270,6 +270,5 @@ namespace map2 {
             CDSUNIT_TEST_RefinableMap
             CDSUNIT_TEST_StdMap
         CPPUNIT_TEST_SUITE_END();
-
     };
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string.cpp b/tests/unit/map2/map_insdel_string.cpp
index bcfd00c0..e52c8276 100644
--- a/tests/unit/map2/map_insdel_string.cpp
+++ b/tests/unit/map2/map_insdel_string.cpp
@@ -5,13 +5,6 @@
 namespace map2 {
     CPPUNIT_TEST_SUITE_REGISTRATION( Map_InsDel_string );
 
-    size_t Map_InsDel_string::c_nMapSize = 1000000;
-    size_t Map_InsDel_string::c_nInsertThreadCount = 4;
-    size_t Map_InsDel_string::c_nDeleteThreadCount = 4;
-    size_t Map_InsDel_string::c_nThreadPassCount = 4;
-    size_t Map_InsDel_string::c_nMaxLoadFactor = 8;
-    bool   Map_InsDel_string::c_bPrintGCState = true;
-
     void Map_InsDel_string::setUpParams( const CppUnitMini::TestCfg& cfg )
     {
         c_nInsertThreadCount = cfg.getSizeT("InsertThreadCount", c_nInsertThreadCount );
@@ -20,22 +13,17 @@ namespace map2 {
         c_nMapSize = cfg.getSizeT("MapSize", c_nMapSize );
         c_nMaxLoadFactor = cfg.getSizeT("MaxLoadFactor", c_nMaxLoadFactor );
         c_bPrintGCState = cfg.getBool("PrintGCStateFlag", c_bPrintGCState );
-    }
 
-    void Map_InsDel_string::myRun(const char *in_name, bool invert /*= false*/)
-    {
-        setUpParams( m_Cfg.get( "Map_InsDel_string" ));
+        c_nCuckooInitialSize = cfg.getSizeT("CuckooInitialSize", c_nCuckooInitialSize);
+        c_nCuckooProbesetSize = cfg.getSizeT("CuckooProbesetSize", c_nCuckooProbesetSize);
+        c_nCuckooProbesetThreshold = cfg.getSizeT("CuckooProbesetThreshold", c_nCuckooProbesetThreshold);
 
-        run_MichaelMap(in_name, invert);
-        run_SplitList(in_name, invert);
-        run_SkipListMap(in_name, invert);
-        run_EllenBinTreeMap(in_name, invert);
-        run_BronsonAVLTreeMap(in_name, invert);
-        run_StripedMap(in_name, invert);
-        run_RefinableMap(in_name, invert);
-        run_CuckooMap(in_name, invert);
-        run_StdMap(in_name, invert);
+        c_nMultiLevelMap_HeadBits = cfg.getSizeT("MultiLevelMapHeadBits", c_nMultiLevelMap_HeadBits);
+        c_nMultiLevelMap_ArrayBits = cfg.getSizeT("MultiLevelMapArrayBits", c_nMultiLevelMap_ArrayBits);
 
-        endTestCase();
+        if ( c_nInsertThreadCount == 0 )
+            c_nInsertThreadCount = std::thread::hardware_concurrency();
+        if ( c_nDeleteThreadCount == 0 )
+            c_nDeleteThreadCount = std::thread::hardware_concurrency();
     }
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string.h b/tests/unit/map2/map_insdel_string.h
index d7b5096c..b56eaf19 100644
--- a/tests/unit/map2/map_insdel_string.h
+++ b/tests/unit/map2/map_insdel_string.h
@@ -7,30 +7,44 @@
 
 namespace map2 {
 
-#   define TEST_MAP(IMPL, C, X)         void C::X() { test<map_type<IMPL, key_type, value_type>::X >(); }
-#   define TEST_MAP_NOLF(IMPL, C, X)    void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >(); }
-#   define TEST_MAP_EXTRACT(IMPL, C, X)  TEST_MAP(IMPL, C, X)
-#   define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
+#define TEST_CASE(TAG, X)  void X();
+
+//#   define TEST_MAP(IMPL, C, X)         void C::X() { test<map_type<IMPL, key_type, value_type>::X >(); }
+//#   define TEST_MAP_NOLF(IMPL, C, X)    void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >(); }
+//#   define TEST_MAP_EXTRACT(IMPL, C, X)  TEST_MAP(IMPL, C, X)
+//#   define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
 
     class Map_InsDel_string: public CppUnitMini::TestCase
     {
-        static size_t  c_nMapSize;            // map size
-        static size_t  c_nInsertThreadCount;  // count of insertion thread
-        static size_t  c_nDeleteThreadCount;  // count of deletion thread
-        static size_t  c_nThreadPassCount;    // pass count for each thread
-        static size_t  c_nMaxLoadFactor;      // maximum load factor
-        static bool    c_bPrintGCState;
+    public:
+        size_t  c_nMapSize = 1000000;      // map size
+        size_t  c_nInsertThreadCount = 4;  // count of insertion thread
+        size_t  c_nDeleteThreadCount = 4;  // count of deletion thread
+        size_t  c_nThreadPassCount = 4;    // pass count for each thread
+        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 (o - 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
+
+    private:
         typedef CppUnitMini::TestCase Base;
         typedef std::string key_type;
         typedef size_t      value_type;
 
         const std::vector<std::string> *  m_parrString;
 
-        template <class MAP>
+        template <class Map>
         class Inserter: public CppUnitMini::TestThread
         {
-            MAP&     m_Map;
+            Map&     m_Map;
 
             virtual Inserter *    clone()
             {
@@ -41,7 +55,7 @@ namespace map2 {
             size_t  m_nInsertFailed;
 
         public:
-            Inserter( CppUnitMini::ThreadPool& pool, MAP& rMap )
+            Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
                 : CppUnitMini::TestThread( pool )
                 , m_Map( rMap )
             {}
@@ -60,17 +74,19 @@ namespace map2 {
 
             virtual void test()
             {
-                MAP& rMap = m_Map;
+                Map& rMap = m_Map;
 
                 m_nInsertSuccess =
                     m_nInsertFailed = 0;
 
                 const std::vector<std::string>& arrString = *getTest().m_parrString;
                 size_t nArrSize = arrString.size();
+                size_t const nMapSize = getTest().c_nMapSize;
+                size_t const nPassCount = getTest().c_nThreadPassCount;
 
                 if ( m_nThreadNo & 1 ) {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
-                        for ( size_t nItem = 0; nItem < c_nMapSize; ++nItem ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( size_t nItem = 0; nItem < nMapSize; ++nItem ) {
                             if ( rMap.insert( arrString[nItem % nArrSize], nItem * 8 ) )
                                 ++m_nInsertSuccess;
                             else
@@ -79,8 +95,8 @@ namespace map2 {
                     }
                 }
                 else {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
-                        for ( size_t nItem = c_nMapSize; nItem > 0; --nItem ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( size_t nItem = nMapSize; nItem > 0; --nItem ) {
                             if ( rMap.insert( arrString[nItem % nArrSize], nItem * 8 ) )
                                 ++m_nInsertSuccess;
                             else
@@ -91,10 +107,10 @@ namespace map2 {
             }
         };
 
-        template <class MAP>
+        template <class Map>
         class Deleter: public CppUnitMini::TestThread
         {
-            MAP&     m_Map;
+            Map&     m_Map;
 
             virtual Deleter *    clone()
             {
@@ -105,7 +121,7 @@ namespace map2 {
             size_t  m_nDeleteFailed;
 
         public:
-            Deleter( CppUnitMini::ThreadPool& pool, MAP& rMap )
+            Deleter( CppUnitMini::ThreadPool& pool, Map& rMap )
                 : CppUnitMini::TestThread( pool )
                 , m_Map( rMap )
             {}
@@ -124,17 +140,19 @@ namespace map2 {
 
             virtual void test()
             {
-                MAP& rMap = m_Map;
+                Map& rMap = m_Map;
 
                 m_nDeleteSuccess =
                     m_nDeleteFailed = 0;
 
                 const std::vector<std::string>& arrString = *getTest().m_parrString;
                 size_t nArrSize = arrString.size();
+                size_t const nMapSize = getTest().c_nMapSize;
+                size_t const nPassCount = getTest().c_nThreadPassCount;
 
                 if ( m_nThreadNo & 1 ) {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
-                        for ( size_t nItem = 0; nItem < c_nMapSize; ++nItem ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( size_t nItem = 0; nItem < nMapSize; ++nItem ) {
                             if ( rMap.erase( arrString[nItem % nArrSize] ) )
                                 ++m_nDeleteSuccess;
                             else
@@ -143,8 +161,8 @@ namespace map2 {
                     }
                 }
                 else {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
-                        for ( size_t nItem = c_nMapSize; nItem > 0; --nItem ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( size_t nItem = nMapSize; nItem > 0; --nItem ) {
                             if ( rMap.erase( arrString[nItem % nArrSize] ) )
                                 ++m_nDeleteSuccess;
                             else
@@ -157,11 +175,11 @@ namespace map2 {
 
     protected:
 
-        template <class MAP>
-        void do_test( MAP& testMap )
+        template <class Map>
+        void do_test( Map& testMap )
         {
-            typedef Inserter<MAP>       InserterThread;
-            typedef Deleter<MAP>        DeleterThread;
+            typedef Inserter<Map>       InserterThread;
+            typedef Deleter<Map>        DeleterThread;
             cds::OS::Timer    timer;
 
             CppUnitMini::ThreadPool pool( *this );
@@ -208,8 +226,8 @@ namespace map2 {
             additional_cleanup( testMap );
         }
 
-        template <class MAP>
-        void test()
+        template <class Map>
+        void run_test()
         {
             m_parrString = &CppUnitMini::TestCase::getTestStrings();
 
@@ -219,56 +237,48 @@ namespace map2 {
                 << " map size=" << c_nMapSize
                 );
 
-            for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
-                CPPUNIT_MSG( "Load factor=" << nLoadFactor );
-                MAP  testMap( c_nMapSize, nLoadFactor );
+            if ( Map::c_bLoadFactorDepended ) {
+                for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
+                    CPPUNIT_MSG( "Load factor=" << nLoadFactor );
+                    Map  testMap( *this );
+                    do_test( testMap );
+                    if ( c_bPrintGCState )
+                        print_gc_state();
+                }
+            }
+            else {
+                Map testMap( *this );
                 do_test( testMap );
                 if ( c_bPrintGCState )
                     print_gc_state();
             }
         }
 
-        template <class MAP>
-        void test_nolf()
-        {
-            m_parrString = &CppUnitMini::TestCase::getTestStrings();
-
-            CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
-                << " delete=" << c_nDeleteThreadCount
-                << " pass count=" << c_nThreadPassCount
-                << " map size=" << c_nMapSize
-                );
-
-            MAP testMap;
-            do_test( testMap );
-            if ( c_bPrintGCState )
-                print_gc_state();
-        }
-
         void setUpParams( const CppUnitMini::TestCfg& cfg );
 
-        void run_MichaelMap(const char *in_name, bool invert = false);
-        void run_SplitList(const char *in_name, bool invert = false);
-        void run_StripedMap(const char *in_name, bool invert = false);
-        void run_RefinableMap(const char *in_name, bool invert = false);
-        void run_CuckooMap(const char *in_name, bool invert = false);
-        void run_SkipListMap(const char *in_name, bool invert = false);
-        void run_EllenBinTreeMap(const char *in_name, bool invert = false);
-        void run_BronsonAVLTreeMap(const char *in_name, bool invert = false);
-        void run_StdMap(const char *in_name, bool invert = false);
-
-        virtual void myRun(const char *in_name, bool invert = false);
-
-
 #   include "map2/map_defs.h"
         CDSUNIT_DECLARE_MichaelMap
         CDSUNIT_DECLARE_SplitList
         CDSUNIT_DECLARE_SkipListMap
         CDSUNIT_DECLARE_EllenBinTreeMap
         CDSUNIT_DECLARE_BronsonAVLTreeMap
+        CDSUNIT_DECLARE_MultiLevelHashMap
         CDSUNIT_DECLARE_StripedMap
         CDSUNIT_DECLARE_RefinableMap
         CDSUNIT_DECLARE_CuckooMap
         CDSUNIT_DECLARE_StdMap
+
+        CPPUNIT_TEST_SUITE(Map_InsDel_string)
+            CDSUNIT_TEST_MichaelMap
+            CDSUNIT_TEST_SplitList
+            CDSUNIT_TEST_SkipListMap
+            CDSUNIT_TEST_EllenBinTreeMap
+            CDSUNIT_TEST_BronsonAVLTreeMap
+            CDSUNIT_TEST_MultiLevelHashMap
+            CDSUNIT_TEST_CuckooMap
+            CDSUNIT_TEST_StripedMap
+            CDSUNIT_TEST_RefinableMap
+            CDSUNIT_TEST_StdMap
+        CPPUNIT_TEST_SUITE_END();
     };
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_bronsonavltree.cpp b/tests/unit/map2/map_insdel_string_bronsonavltree.cpp
index 8ba8b414..9b485aa1 100644
--- a/tests/unit/map2/map_insdel_string_bronsonavltree.cpp
+++ b/tests/unit/map2/map_insdel_string_bronsonavltree.cpp
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_bronson_avltree.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_BronsonAVLTreeMap( cc::bronson_avltree::implementation_tag, Map_InsDel_string)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_BronsonAVLTreeMap )
-        CDSUNIT_TEST_BronsonAVLTreeMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_BronsonAVLTreeMap
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_cuckoo.cpp b/tests/unit/map2/map_insdel_string_cuckoo.cpp
index 92e8c79c..89ca6c01 100644
--- a/tests/unit/map2/map_insdel_string_cuckoo.cpp
+++ b/tests/unit/map2/map_insdel_string_cuckoo.cpp
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_cuckoo.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_CuckooMap(cds::intrusive::cuckoo::implementation_tag, Map_InsDel_string)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_CuckooMap )
-        CDSUNIT_TEST_CuckooMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_CuckooMap
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_ellentree.cpp b/tests/unit/map2/map_insdel_string_ellentree.cpp
index cd00f031..4da122c6 100644
--- a/tests/unit/map2/map_insdel_string_ellentree.cpp
+++ b/tests/unit/map2/map_insdel_string_ellentree.cpp
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_ellen_bintree.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_EllenBinTreeMap( cc::ellen_bintree::implementation_tag, Map_InsDel_string)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_EllenBinTreeMap )
-        CDSUNIT_TEST_EllenBinTreeMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_EllenBinTreeMap
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_michael.cpp b/tests/unit/map2/map_insdel_string_michael.cpp
index 6a205ea0..513aa790 100644
--- a/tests/unit/map2/map_insdel_string_michael.cpp
+++ b/tests/unit/map2/map_insdel_string_michael.cpp
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_michael.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_MichaelMap( cc::michael_map::implementation_tag, Map_InsDel_string )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_MichaelMap )
-        CDSUNIT_TEST_MichaelMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_MichaelMap
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_multilevelhashmap.cpp b/tests/unit/map2/map_insdel_string_multilevelhashmap.cpp
new file mode 100644
index 00000000..202a81d9
--- /dev/null
+++ b/tests/unit/map2/map_insdel_string_multilevelhashmap.cpp
@@ -0,0 +1,12 @@
+//$$CDS-header$$
+
+#include "map2/map_insdel_string.h"
+#include "map2/map_type_multilevel_hashmap.h"
+
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
+
+namespace map2 {
+    CDSUNIT_DECLARE_MultiLevelHashMap
+} // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_refinable.cpp b/tests/unit/map2/map_insdel_string_refinable.cpp
deleted file mode 100644
index 74448fbf..00000000
--- a/tests/unit/map2/map_insdel_string_refinable.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-//$$CDS-header$$
-
-#include "map2/map_insdel_string.h"
-#include "map2/map_type_striped.h"
-
-namespace map2 {
-    CDSUNIT_DEFINE_RefinableMap(cc::striped_set::implementation_tag, Map_InsDel_string)
-
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_RefinableMap )
-        CDSUNIT_TEST_RefinableMap
-    CPPUNIT_TEST_SUITE_END_PART()
-} // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_skip.cpp b/tests/unit/map2/map_insdel_string_skip.cpp
index ba047749..ac442201 100644
--- a/tests/unit/map2/map_insdel_string_skip.cpp
+++ b/tests/unit/map2/map_insdel_string_skip.cpp
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_skip_list.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_SkipListMap( cc::skip_list::implementation_tag, Map_InsDel_string)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_SkipListMap )
-        CDSUNIT_TEST_SkipListMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_SkipListMap
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_split.cpp b/tests/unit/map2/map_insdel_string_split.cpp
index 1ab66aae..c14a7478 100644
--- a/tests/unit/map2/map_insdel_string_split.cpp
+++ b/tests/unit/map2/map_insdel_string_split.cpp
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_split_list.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_SplitList( cc::split_list::implementation_tag, Map_InsDel_string )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_SplitList )
-        CDSUNIT_TEST_SplitList
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_SplitList
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_std.cpp b/tests/unit/map2/map_insdel_string_std.cpp
index 5ec09658..cb64cf93 100644
--- a/tests/unit/map2/map_insdel_string_std.cpp
+++ b/tests/unit/map2/map_insdel_string_std.cpp
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_std.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_StdMap( map2::std_implementation_tag, Map_InsDel_string)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_StdMap )
-        CDSUNIT_TEST_StdMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_StdMap
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_string_striped.cpp b/tests/unit/map2/map_insdel_string_striped.cpp
index f24df486..57887608 100644
--- a/tests/unit/map2/map_insdel_string_striped.cpp
+++ b/tests/unit/map2/map_insdel_string_striped.cpp
@@ -3,10 +3,11 @@
 #include "map2/map_insdel_string.h"
 #include "map2/map_type_striped.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_StripedMap(cc::striped_set::implementation_tag, Map_InsDel_string)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_string::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_string, run_StripedMap )
-        CDSUNIT_TEST_StripedMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_StripedMap
+    CDSUNIT_DECLARE_RefinableMap
 } // namespace map2
-- 
2.34.1