Adds sequential map test cases
authorPeizhao Ou <peizhaoo@uci.edu>
Tue, 16 Jan 2018 23:34:51 +0000 (15:34 -0800)
committerPeizhao Ou <peizhaoo@uci.edu>
Tue, 16 Jan 2018 23:34:51 +0000 (15:34 -0800)
110 files changed:
test/stress/sequential/CMakeLists.txt
test/stress/sequential/sequential-map/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3.h [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3_cuckoo.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3_ellentree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3_feldman_hashmap.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3_michael.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3_skip.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/del3/map_del3_split.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd.h [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd_cuckoo.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd_ellentree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd_feldman_hashmap.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd_michael.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd_skip.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/delodd/map_delodd_split.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string.h [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_cuckoo.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_ellentree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_feldman_hashset.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_michael.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_skip.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_split.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_std.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/find_string/map_find_string_striped.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func.h [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_cuckoo.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_ellentree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_feldman_hashset.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_michael.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_skip.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_split.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_func/map_insdel_func_striped.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int.h [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_cuckoo.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_ellentree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_feldman_hashset.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_michael.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_skip.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_split.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_striped.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string.h [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_cuckoo.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_ellentree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_feldman_hashset.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_michael.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_skip.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_split.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_std.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdel_string/map_insdel_string_striped.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind.h [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_cuckoo.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_ellentree_hp.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_ellentree_rcu.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_feldman_hashset_hp.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_feldman_hashset_rcu.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_michael_hp.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_michael_rcu.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_skip_hp.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_skip_rcu.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_split_hp.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_split_rcu.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_std.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/insdelfind/map_insdelfind_striped.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/iter_erase/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/iter_erase/map_iter_erase.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/iter_erase/map_iter_erase.h [new file with mode: 0644]
test/stress/sequential/sequential-map/iter_erase/map_iter_erase_feldman_hashmap.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/iter_erase/map_iter_erase_michael.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/iter_erase/map_iter_erase_split.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_bronson_avltree.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_cuckoo.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_ellen_bintree.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_feldman_hashmap.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_iterable_list.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_lazy_list.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_michael.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_michael_list.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_skip_list.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_split_list.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_std.h [new file with mode: 0644]
test/stress/sequential/sequential-map/map_type_striped.h [new file with mode: 0644]
test/stress/sequential/sequential-map/minmax/CMakeLists.txt [new file with mode: 0644]
test/stress/sequential/sequential-map/minmax/map_minmax.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/minmax/map_minmax.h [new file with mode: 0644]
test/stress/sequential/sequential-map/minmax/map_minmax_bronsonavltree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/minmax/map_minmax_ellentree.cpp [new file with mode: 0644]
test/stress/sequential/sequential-map/minmax/map_minmax_skip.cpp [new file with mode: 0644]

index 3d0907804bc3ace4b22d13efd79d6da5b4337a59..059bb6f4cfec6ceb5362bc9a2c83b61b1bd15157 100644 (file)
@@ -1,6 +1,7 @@
 set(PACKAGE_NAME stress-sequential)
 
 add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/sequential-set)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/sequential-map)
 
 set(CDSSTRESS_STACK_SOURCES
     ../main.cpp
@@ -23,4 +24,5 @@ add_custom_target( stress-sequential-all
     DEPENDS
         stress-sequential
         stress-sequential-set
+        stress-sequential-map
 )
diff --git a/test/stress/sequential/sequential-map/CMakeLists.txt b/test/stress/sequential/sequential-map/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6cd9e10
--- /dev/null
@@ -0,0 +1,25 @@
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCDSUNIT_USE_URCU")
+
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/delodd)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/del3)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/find_string)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_func)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_string)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_item_int)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdelfind)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/minmax)
+#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/iter_erase)
+
+add_custom_target( stress-sequential-map
+    DEPENDS
+        stress-sequential-map-delodd
+        stress-sequential-map-del3
+        stress-sequential-map-find-string
+        stress-sequential-map-insdel-func
+        stress-sequential-map-insdel-string
+        stress-sequential-map-insdel-item-int
+        stress-sequential-map-insdelfind
+        stress-sequential-map-minmax
+        #stress-sequential-map-iter-erase
+)
diff --git a/test/stress/sequential/sequential-map/del3/CMakeLists.txt b/test/stress/sequential/sequential-map/del3/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1098f44
--- /dev/null
@@ -0,0 +1,23 @@
+set(PACKAGE_NAME stress-sequential-map-del3)
+
+set(CDSSTRESS_MAP_DEL3_SOURCES
+    ../../../main.cpp
+    map_del3.cpp
+    map_del3_bronsonavltree.cpp
+    map_del3_cuckoo.cpp
+    map_del3_ellentree.cpp
+    map_del3_feldman_hashmap.cpp
+    map_del3_michael.cpp
+    map_del3_skip.cpp
+    map_del3_split.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_DEL3_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/del3/map_del3.cpp b/test/stress/sequential/sequential-map/del3/map_del3.cpp
new file mode 100644 (file)
index 0000000..6332394
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+
+namespace map {
+
+    size_t  Map_Del3::s_nMapSize = 10000;
+    size_t  Map_Del3::s_nInsThreadCount = 4;
+    size_t  Map_Del3::s_nDelThreadCount = 4;
+    size_t  Map_Del3::s_nExtractThreadCount = 4;
+    size_t  Map_Del3::s_nFindThreadCount = 2;
+    size_t  Map_Del3::s_nMaxLoadFactor = 8;
+    size_t  Map_Del3::s_nInsertPassCount = 100;
+    size_t  Map_Del3::s_nOriginalPassCount = 100;
+    size_t  Map_Del3::s_nPassCount = 100;
+    size_t  Map_Del3::s_nFeldmanPassCount = 100;
+    size_t  Map_Del3::s_nBronsonAVLTreeMapPassCount = 100;
+    size_t  Map_Del3::s_nEllenBinTreeMapPassCount= 100;
+    size_t  Map_Del3::s_nMichaelMapPassCount= 100;
+    size_t  Map_Del3::s_nSkipListMapPassCount= 100;
+
+    size_t  Map_Del3::s_nCuckooInitialSize = 1024;
+    size_t  Map_Del3::s_nCuckooProbesetSize = 16;
+    size_t  Map_Del3::s_nCuckooProbesetThreshold = 0;
+
+    size_t Map_Del3::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_Del3::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_Del3::s_nLoadFactor = 1;
+    std::vector<size_t> Map_Del3::m_arrElements;
+
+    void Map_Del3::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "sequential_real_map_delodd" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsThreadCount = cfg.get_size_t( "InsThreadCount", s_nInsThreadCount );
+        if ( s_nInsThreadCount == 0 )
+            s_nInsThreadCount = 1;
+
+        s_nDelThreadCount = cfg.get_size_t( "DelThreadCount", s_nDelThreadCount );
+        s_nExtractThreadCount = cfg.get_size_t( "ExtractThreadCount", s_nExtractThreadCount );
+        s_nFindThreadCount = cfg.get_size_t( "FindThreadCount", s_nFindThreadCount );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nInsertPassCount = cfg.get_size_t( "InsertPassCount", s_nInsertPassCount );
+        if ( s_nInsertPassCount == 0 )
+            s_nInsertPassCount = 100;
+
+        s_nPassCount = cfg.get_size_t("PassCount", s_nPassCount);
+        if (s_nPassCount == 0)
+          s_nPassCount = 100;
+        s_nOriginalPassCount = s_nPassCount;
+
+        s_nFeldmanPassCount =
+            cfg.get_size_t("FeldmanPassCount", s_nFeldmanPassCount);
+        if (s_nFeldmanPassCount == 0)
+          s_nFeldmanPassCount = 500;
+
+        s_nBronsonAVLTreeMapPassCount = cfg.get_size_t(
+            "BronsonAVLTreeMapPassCount", s_nBronsonAVLTreeMapPassCount);
+        if (s_nBronsonAVLTreeMapPassCount == 0)
+          s_nBronsonAVLTreeMapPassCount = 500;
+
+        s_nEllenBinTreeMapPassCount = cfg.get_size_t(
+            "EllenBinTreeMapPassCount", s_nEllenBinTreeMapPassCount);
+        if (s_nEllenBinTreeMapPassCount == 0)
+          s_nEllenBinTreeMapPassCount = 500;
+
+        s_nMichaelMapPassCount =
+            cfg.get_size_t("MichaelMapPassCount", s_nMichaelMapPassCount);
+        if (s_nMichaelMapPassCount == 0)
+          s_nMichaelMapPassCount = 500;
+
+        s_nSkipListMapPassCount =
+            cfg.get_size_t("SkipListMapPassCount", s_nSkipListMapPassCount);
+        if (s_nSkipListMapPassCount == 0)
+          s_nSkipListMapPassCount = 500;
+
+        s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
+        if ( s_nCuckooInitialSize < 256 )
+            s_nCuckooInitialSize = 256;
+
+        s_nCuckooProbesetSize = cfg.get_size_t( "CuckooProbesetSize", s_nCuckooProbesetSize );
+        if ( s_nCuckooProbesetSize < 8 )
+            s_nCuckooProbesetSize = 8;
+
+        s_nCuckooProbesetThreshold = cfg.get_size_t( "CuckooProbesetThreshold", s_nCuckooProbesetThreshold );
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+
+        m_arrElements.resize( s_nMapSize );
+        for ( size_t i = 0; i < s_nMapSize; ++i )
+            m_arrElements[i] = i;;
+        shuffle( m_arrElements.begin(), m_arrElements.end());
+    }
+
+    void Map_Del3::TearDownTestCase()
+    {
+        m_arrElements.clear();
+    }
+
+    std::vector<size_t> Map_Del3_LF::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_delodd" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_Del3_LF, ::testing::ValuesIn( Map_Del3_LF::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_Del3_LF, ::testing::ValuesIn( Map_Del3_LF::get_load_factors()));
+#endif
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3.h b/test/stress/sequential/sequential-map/del3/map_del3.h
new file mode 100644 (file)
index 0000000..38cc872
--- /dev/null
@@ -0,0 +1,739 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+#include <cds/os/topology.h>
+
+namespace map {
+
+    namespace {
+        struct key_thread
+        {
+            uint32_t  nKey;
+            uint16_t  nThread;
+
+            key_thread( size_t key, size_t threadNo )
+                : nKey( static_cast<uint32_t>(key))
+                , nThread( static_cast<uint16_t>(threadNo))
+            {}
+
+            key_thread()
+                : nKey()
+                , nThread()
+            {}
+        };
+
+        static_assert(sizeof( key_thread ) % 8 == 0, "Key size mismatch!!!");
+    } // namespace
+
+    template <>
+    struct cmp<key_thread> {
+        int operator ()(key_thread const& k1, key_thread const& k2) const
+        {
+            if ( k1.nKey < k2.nKey )
+                return -1;
+            if ( k1.nKey > k2.nKey )
+                return 1;
+            if ( k1.nThread < k2.nThread )
+                return -1;
+            if ( k1.nThread > k2.nThread )
+                return 1;
+            return 0;
+        }
+        int operator ()(key_thread const& k1, size_t k2) const
+        {
+            if ( k1.nKey < k2 )
+                return -1;
+            if ( k1.nKey > k2 )
+                return 1;
+            return 0;
+        }
+        int operator ()(size_t k1, key_thread const& k2) const
+        {
+            if ( k1 < k2.nKey )
+                return -1;
+            if ( k1 > k2.nKey )
+                return 1;
+            return 0;
+        }
+    };
+
+    template <>
+    struct less<key_thread>
+    {
+        bool operator()( key_thread const& k1, key_thread const& k2 ) const
+        {
+            if ( k1.nKey <= k2.nKey )
+                return k1.nKey < k2.nKey || k1.nThread < k2.nThread;
+            return false;
+        }
+    };
+
+    template <>
+    struct hash<key_thread>
+    {
+        typedef size_t             result_type;
+        typedef key_thread    argument_type;
+
+        size_t operator()( key_thread const& k ) const
+        {
+            return std::hash<size_t>()(k.nKey);
+        }
+        size_t operator()( size_t k ) const
+        {
+            return std::hash<size_t>()(k);
+        }
+    };
+
+    class Map_Del3: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nInsThreadCount;      // insert thread count
+        static size_t s_nDelThreadCount;      // delete thread count
+        static size_t s_nExtractThreadCount;  // extract thread count
+        static size_t s_nMapSize;             // max map size
+        static size_t s_nMaxLoadFactor;       // maximum load factor
+        static size_t s_nInsertPassCount;
+        static size_t s_nOriginalPassCount;
+        static size_t s_nPassCount;
+        static size_t s_nBronsonAVLTreeMapPassCount;
+        static size_t s_nEllenBinTreeMapPassCount;
+        static size_t s_nFeldmanPassCount;
+        static size_t s_nMichaelMapPassCount;
+        static size_t s_nSkipListMapPassCount;
+
+        static size_t s_nFindThreadCount;     // find thread count
+
+        static size_t s_nCuckooInitialSize;       // initial size for CuckooMap
+        static size_t s_nCuckooProbesetSize;      // CuckooMap probeset size (only for list-based probeset)
+        static size_t s_nCuckooProbesetThreshold; // CuckooMap probeset threshold (0 - use default)
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static std::vector<size_t> m_arrElements;
+
+        static void SetUpTestCase();
+        static void TearDownTestCase();
+
+        template <typename Pred>
+        static void prepare_array( std::vector<size_t>& arr, Pred pred )
+        {
+            arr.reserve( m_arrElements.size());
+            for ( auto el : m_arrElements ) {
+                if ( pred( el ))
+                    arr.push_back( el );
+            }
+            arr.resize( arr.size());
+            shuffle( arr.begin(), arr.end());
+        }
+
+    protected:
+        typedef key_thread  key_type;
+        typedef size_t      value_type;
+        typedef std::pair<key_type const, value_type> pair_type;
+
+        atomics::atomic<size_t> m_nInsThreadCount;
+
+        enum {
+            inserter_thread,
+            deleter_thread,
+            extractor_thread,
+            find_thread,
+        };
+
+        // Inserts keys from [0..N)
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            struct update_func
+            {
+                template <typename Q>
+                void operator()( bool /*bNew*/, Q const& ) const
+                {}
+
+                template <typename Q, typename V>
+                void operator()( bool /*bNew*/, Q const&, V& ) const
+                {}
+
+                // FeldmanHashMap
+                template <typename Q>
+                void operator()( Q&, Q*) const
+                {}
+            };
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t ) -> bool { return true; } );
+                for ( size_t i = 0; i < m_arr.size(); ++i ) {
+                    if ( m_Map.insert( key_type( m_arr[i], id())))
+                        ++m_nInsertInitSuccess;
+                    else
+                        ++m_nInsertInitFailed;
+                }
+            }
+
+        public:
+            size_t m_nInsertSuccess = 0;
+            size_t m_nInsertFailed = 0;
+            size_t m_nInsertInitSuccess = 0;
+            size_t m_nInsertInitFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, inserter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_Del3& fixture = pool().template fixture<Map_Del3>();
+
+                update_func f;
+
+                for (auto el : m_arr) {
+                  if (el & 3) {
+                    if (rMap.insert(key_type(el, id())))
+                      ++m_nInsertSuccess;
+                    else
+                      ++m_nInsertFailed;
+                  }
+                }
+                m_arr.resize(0);
+            }
+        };
+
+        struct key_equal {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey == k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 == k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey == k2;
+            }
+        };
+
+        struct key_less {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey < k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 < k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey < k2;
+            }
+
+            typedef key_equal equal_to;
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class Map>
+        class Deleter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Deleter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, deleter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Deleter( Deleter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Deleter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                Map_Del3& fixture = pool().template fixture<Map_Del3>();
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                for (auto el : m_arr) {
+                  for (size_t k = 0; k < nInsThreadCount; ++k) {
+                    if (rMap.erase(key_type(el, k)))
+                      ++m_nDeleteSuccess;
+                    else
+                      ++m_nDeleteFailed;
+                  }
+                }
+                m_arr.resize( 0 );
+            }
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class GC, class Map >
+        class Extractor: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                typename Map::guarded_ptr gp;
+                Map_Del3& fixture = pool().template fixture<Map_Del3>();
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                for (auto el : m_arr) {
+                  for (size_t k = 0; k < nInsThreadCount; ++k) {
+                    gp = rMap.extract(key_type(el, k));
+                    if (gp)
+                      ++m_nDeleteSuccess;
+                    else
+                      ++m_nDeleteFailed;
+                    gp.release();
+                  }
+                }
+                m_arr.resize( 0 );
+            }
+        };
+
+        template <class RCU, class Map >
+        class Extractor< cds::urcu::gc<RCU>, Map > : public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) -> bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_Del3& fixture = pool().template fixture<Map_Del3>();
+
+                typename Map::exempt_ptr xp;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                for (size_t k = 0; k < nInsThreadCount; ++k) {
+                  for (auto el : m_arr) {
+                    if (Map::c_bExtractLockExternal) {
+                      typename Map::rcu_lock l;
+                      xp = rMap.extract(key_type(el, k));
+                      if (xp)
+                        ++m_nDeleteSuccess;
+                      else
+                        ++m_nDeleteFailed;
+                    } else {
+                      xp = rMap.extract(key_type(el, k));
+                      if (xp)
+                        ++m_nDeleteSuccess;
+                      else
+                        ++m_nDeleteFailed;
+                    }
+                    xp.release();
+                  }
+                }
+                m_arr.resize(0);
+            }
+        };
+
+        // Finds keys
+        template <class Map>
+        class Observer: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&                m_Map;
+
+        public:
+            size_t m_nFindEvenSuccess = 0;
+            size_t m_nFindEvenFailed  = 0;
+            size_t m_nFindOddSuccess  = 0;
+            size_t m_nFindOddFailed   = 0;
+
+        public:
+            Observer( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, find_thread )
+                , m_Map( map )
+            {}
+
+            Observer( Observer& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Observer( *this );
+            }
+
+            virtual void test()
+            {
+                Map& map = m_Map;
+                Map_Del3& fixture = pool().template fixture<Map_Del3>();
+                std::vector<size_t> const& arr = m_arrElements;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                for (size_t key : arr) {
+                  if (key & 3) {
+                    for (size_t k = 0; k < nInsThreadCount; ++k) {
+                      if (map.contains(key_thread(key, k)))
+                        ++m_nFindOddSuccess;
+                      else
+                        ++m_nFindOddFailed;
+                    }
+                  } else {
+                    // even keys MUST be in the map
+                    for (size_t k = 0; k < nInsThreadCount; ++k) {
+                      if (map.contains(key_thread(key, k)))
+                        ++m_nFindEvenSuccess;
+                      else
+                        ++m_nFindEvenFailed;
+                    }
+                  }
+                }
+            }
+        };
+
+    protected:
+        template <class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map>  delete_thread;
+            typedef Observer<Map> observer_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            pool.add( new delete_thread( pool, testMap ), s_nDelThreadCount ? s_nDelThreadCount : cds::OS::topology::processor_count());
+            if ( s_nFindThreadCount )
+                pool.add( new observer_thread( pool, testMap ), s_nFindThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
+                << std::make_pair( "find_thread_count", s_nFindThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nInsertPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertInitFailed = 0;
+            size_t nInsertInitSuccess = 0;
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+
+            size_t nFindEvenSuccess = 0;
+            size_t nFindEvenFailed = 0;
+            size_t nFindOddSuccess = 0;
+            size_t nFindOddFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                    {
+                        insert_thread& inserter = static_cast<insert_thread&>( thr );
+                        nInsertSuccess += inserter.m_nInsertSuccess;
+                        nInsertFailed += inserter.m_nInsertFailed;
+                        nInsertInitSuccess += inserter.m_nInsertInitSuccess;
+                        nInsertInitFailed += inserter.m_nInsertInitFailed;
+                    }
+                    break;
+                case deleter_thread:
+                    {
+                        delete_thread& deleter = static_cast<delete_thread&>( thr );
+                        nDeleteSuccess += deleter.m_nDeleteSuccess;
+                        nDeleteFailed += deleter.m_nDeleteFailed;
+                    }
+                    break;
+                case find_thread:
+                    {
+                        observer_thread& observer = static_cast<observer_thread&>( thr );
+                        nFindEvenSuccess = observer.m_nFindEvenSuccess;
+                        nFindEvenFailed = observer.m_nFindEvenFailed;
+                        nFindOddSuccess = observer.m_nFindOddSuccess;
+                        nFindOddFailed = observer.m_nFindOddFailed;
+                    }
+                    break;
+                }
+            }
+
+            size_t const nInitialOddKeys = ( s_nMapSize * s_nInsThreadCount ) * 3 / 4;
+
+            EXPECT_EQ( nInsertInitFailed, 0u );
+            EXPECT_EQ( nInsertInitSuccess, s_nMapSize * s_nInsThreadCount );
+            EXPECT_EQ( nFindEvenFailed, 0u );
+            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess );
+            EXPECT_LE( nInsertSuccess, nDeleteSuccess );
+
+            propout()
+                << std::make_pair( "insert_init_success", nInsertInitSuccess )
+                << std::make_pair( "insert_init_failed", nInsertInitFailed )
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "find_even_success", nFindEvenSuccess )
+                << std::make_pair( "find_even_failed", nFindEvenFailed )
+                << std::make_pair( "find_odd_success", nFindOddSuccess )
+                << std::make_pair( "find_odd_failed", nFindOddFailed );
+
+            analyze( testMap );
+        }
+
+        template <class Map>
+        void do_test_extract( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map> delete_thread;
+            typedef Extractor< typename Map::gc, Map > extract_thread;
+            typedef Observer<Map> observer_thread;
+
+            cds_test::thread_pool &pool = get_pool();
+            std::unique_ptr<insert_thread> inserter(
+                new insert_thread(pool, testMap));
+            std::unique_ptr<delete_thread> deleter(
+                new delete_thread(pool, testMap));
+            std::unique_ptr<extract_thread> extractor(
+                new extract_thread(pool, testMap));
+            std::unique_ptr<observer_thread> observer(
+                new observer_thread(pool, testMap));
+
+            for (size_t nPass = 0; nPass < s_nPassCount; ++nPass) {
+              testMap.clear();
+              inserter->test();
+              observer->test();
+              deleter->test();
+              observer->test();
+              testMap.clear();
+              inserter->test();
+              extractor->test();
+              observer->test();
+            }
+        }
+
+        template <class Map>
+        void analyze( Map& testMap )
+        {
+            // All even keys must be in the map
+            {
+                for ( size_t n = 0; n < s_nMapSize; n +=4 ) {
+                    for ( size_t i = 0; i < s_nInsThreadCount; ++i ) {
+                        EXPECT_TRUE( testMap.contains( key_type( n, i ))) << "key=" << n << "/" << i;
+                    }
+                }
+            }
+
+            print_stat( propout(), testMap );
+
+            check_before_cleanup( testMap );
+            testMap.clear();
+            EXPECT_TRUE( testMap.empty()) << "map.size=" << testMap.size();
+
+            additional_check( testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test_extract()
+        {
+            static_assert( Map::c_bExtractSupported, "Map class must support extract() method" );
+
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test_extract( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test( testMap );
+        }
+
+        template <class Map>
+        void run_feldman();
+
+        template <class Map>
+        void run_bronson_avl_tree();
+
+        template <class Map>
+        void run_ellen_bin_tree();
+
+        template <class Map>
+        void run_skip_list();
+
+        template <class Map>
+        void run_michael();
+    };
+
+    class Map_Del3_LF: public Map_Del3
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Map>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_Del3::run_test<Map>();
+        }
+
+        template <class Map>
+        void run_test_extract()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_Del3::run_test_extract<Map>();
+        }
+
+        static std::vector<size_t> get_load_factors();
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3_bronsonavltree.cpp b/test/stress/sequential/sequential-map/del3/map_del3_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..d7b3435
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    template <class Map>
+    void Map_Del3::run_bronson_avl_tree()
+    {
+        Map_Del3::s_nPassCount = Map_Del3::s_nBronsonAVLTreeMapPassCount;
+        run_test_extract<Map>();
+    }
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_Del3, run_bronson_avl_tree, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3_cuckoo.cpp b/test/stress/sequential/sequential-map/del3/map_del3_cuckoo.cpp
new file mode 100644 (file)
index 0000000..4c1266b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+#include "map_type_cuckoo.h"
+
+namespace map {
+
+//    CDSSTRESS_CuckooMap( Map_Del3, run_test, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3_ellentree.cpp b/test/stress/sequential/sequential-map/del3/map_del3_ellentree.cpp
new file mode 100644 (file)
index 0000000..21c292c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+       template <class Map>
+    void Map_Del3::run_ellen_bin_tree()
+    {
+        Map_Del3::s_nPassCount = Map_Del3::s_nEllenBinTreeMapPassCount;
+        run_test_extract<Map>();
+    }
+
+    CDSSTRESS_EllenBinTreeMap( Map_Del3, run_ellen_bin_tree, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3_feldman_hashmap.cpp b/test/stress/sequential/sequential-map/del3/map_del3_feldman_hashmap.cpp
new file mode 100644 (file)
index 0000000..4bfa673
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    template <class Map>
+    void Map_Del3::run_feldman()
+    {
+        typedef typename Map::traits original_traits;
+        struct traits: public original_traits {
+            enum { hash_size = sizeof( uint32_t ) + sizeof( uint16_t ) };
+        };
+        typedef typename Map::template rebind_traits< traits >::result map_type;
+
+        Map_Del3::s_nPassCount = Map_Del3::s_nFeldmanPassCount;
+        run_test_extract<map_type>();
+    }
+
+    CDSSTRESS_FeldmanHashMap_fixed( Map_Del3, run_feldman, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3_michael.cpp b/test/stress/sequential/sequential-map/del3/map_del3_michael.cpp
new file mode 100644 (file)
index 0000000..e428408
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    template <class Map>
+    void Map_Del3::run_michael()
+    {
+        Map_Del3::s_nPassCount = Map_Del3::s_nMichaelMapPassCount;
+        run_test_extract<Map>();
+    }
+
+    CDSSTRESS_MichaelMap( Map_Del3_LF, run_michael, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3_skip.cpp b/test/stress/sequential/sequential-map/del3/map_del3_skip.cpp
new file mode 100644 (file)
index 0000000..4b02361
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    template <class Map>
+    void Map_Del3::run_skip_list()
+    {
+        Map_Del3::s_nPassCount = Map_Del3::s_nSkipListMapPassCount;
+        run_test_extract<Map>();
+    }
+
+    CDSSTRESS_SkipListMap( Map_Del3, run_skip_list, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/del3/map_del3_split.cpp b/test/stress/sequential/sequential-map/del3/map_del3_split.cpp
new file mode 100644 (file)
index 0000000..a64ec5a
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_del3.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap( Map_Del3_LF, run_test_extract, key_thread, size_t )
+    CDSSTRESS_SplitListIterableMap( Map_Del3_LF, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/CMakeLists.txt b/test/stress/sequential/sequential-map/delodd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3b7a92b
--- /dev/null
@@ -0,0 +1,23 @@
+set(PACKAGE_NAME stress-sequential-map-delodd)
+
+set(CDSSTRESS_MAP_DELODD_SOURCES
+    ../../../main.cpp
+    map_delodd.cpp
+    map_delodd_bronsonavltree.cpp
+    map_delodd_cuckoo.cpp
+    map_delodd_ellentree.cpp
+    map_delodd_feldman_hashmap.cpp
+    map_delodd_michael.cpp
+    map_delodd_skip.cpp
+    map_delodd_split.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_DELODD_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd.cpp
new file mode 100644 (file)
index 0000000..410327f
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+
+namespace map {
+
+    size_t  Map_DelOdd::s_nMapSize = 10000;
+    size_t  Map_DelOdd::s_nInsThreadCount = 4;
+    size_t  Map_DelOdd::s_nDelThreadCount = 4;
+    size_t  Map_DelOdd::s_nExtractThreadCount = 4;
+    size_t  Map_DelOdd::s_nFindThreadCount = 2;
+    size_t  Map_DelOdd::s_nMaxLoadFactor = 8;
+    size_t  Map_DelOdd::s_nInsertPassCount = 100;
+
+    size_t  Map_DelOdd::s_nCuckooInitialSize = 1024;
+    size_t  Map_DelOdd::s_nCuckooProbesetSize = 16;
+    size_t  Map_DelOdd::s_nCuckooProbesetThreshold = 0;
+
+    size_t Map_DelOdd::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_DelOdd::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_DelOdd::s_nLoadFactor = 1;
+    std::vector<size_t> Map_DelOdd::m_arrElements;
+
+    void Map_DelOdd::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "map_delodd" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsThreadCount = cfg.get_size_t( "InsThreadCount", s_nInsThreadCount );
+        if ( s_nInsThreadCount == 0 )
+            s_nInsThreadCount = 1;
+
+        s_nDelThreadCount = cfg.get_size_t( "DelThreadCount", s_nDelThreadCount );
+        s_nExtractThreadCount = cfg.get_size_t( "ExtractThreadCount", s_nExtractThreadCount );
+        s_nFindThreadCount = cfg.get_size_t( "FindThreadCount", s_nFindThreadCount );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nInsertPassCount = cfg.get_size_t( "PassCount", s_nInsertPassCount );
+        if ( s_nInsertPassCount == 0 )
+            s_nInsertPassCount = 100;
+
+        s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
+        if ( s_nCuckooInitialSize < 256 )
+            s_nCuckooInitialSize = 256;
+
+        s_nCuckooProbesetSize = cfg.get_size_t( "CuckooProbesetSize", s_nCuckooProbesetSize );
+        if ( s_nCuckooProbesetSize < 8 )
+            s_nCuckooProbesetSize = 8;
+
+        s_nCuckooProbesetThreshold = cfg.get_size_t( "CuckooProbesetThreshold", s_nCuckooProbesetThreshold );
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+
+        m_arrElements.resize( s_nMapSize );
+        for ( size_t i = 0; i < s_nMapSize; ++i )
+            m_arrElements[i] = i;;
+        shuffle( m_arrElements.begin(), m_arrElements.end());
+    }
+
+    void Map_DelOdd::TearDownTestCase()
+    {
+        m_arrElements.clear();
+    }
+
+    std::vector<size_t> Map_DelOdd_LF::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_delodd" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_DelOdd_LF, ::testing::ValuesIn( Map_DelOdd_LF::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_DelOdd_LF, ::testing::ValuesIn( Map_DelOdd_LF::get_load_factors()));
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd.h b/test/stress/sequential/sequential-map/delodd/map_delodd.h
new file mode 100644 (file)
index 0000000..f4db078
--- /dev/null
@@ -0,0 +1,881 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+#include <cds/os/topology.h>
+
+namespace map {
+
+    namespace {
+        struct key_thread
+        {
+            uint32_t  nKey;
+            uint16_t  nThread;
+
+            key_thread( size_t key, size_t threadNo )
+                : nKey( static_cast<uint32_t>(key))
+                , nThread( static_cast<uint16_t>(threadNo))
+            {}
+
+            key_thread()
+                : nKey()
+                , nThread()
+            {}
+        };
+
+        static_assert(sizeof( key_thread ) % 8 == 0, "Key size mismatch!!!");
+    } // namespace
+
+    template <>
+    struct cmp<key_thread> {
+        int operator ()(key_thread const& k1, key_thread const& k2) const
+        {
+            if ( k1.nKey < k2.nKey )
+                return -1;
+            if ( k1.nKey > k2.nKey )
+                return 1;
+            if ( k1.nThread < k2.nThread )
+                return -1;
+            if ( k1.nThread > k2.nThread )
+                return 1;
+            return 0;
+        }
+        int operator ()(key_thread const& k1, size_t k2) const
+        {
+            if ( k1.nKey < k2 )
+                return -1;
+            if ( k1.nKey > k2 )
+                return 1;
+            return 0;
+        }
+        int operator ()(size_t k1, key_thread const& k2) const
+        {
+            if ( k1 < k2.nKey )
+                return -1;
+            if ( k1 > k2.nKey )
+                return 1;
+            return 0;
+        }
+    };
+
+    template <>
+    struct less<key_thread>
+    {
+        bool operator()( key_thread const& k1, key_thread const& k2 ) const
+        {
+            if ( k1.nKey <= k2.nKey )
+                return k1.nKey < k2.nKey || k1.nThread < k2.nThread;
+            return false;
+        }
+    };
+
+    template <>
+    struct hash<key_thread>
+    {
+        typedef size_t             result_type;
+        typedef key_thread    argument_type;
+
+        size_t operator()( key_thread const& k ) const
+        {
+            return std::hash<size_t>()(k.nKey);
+        }
+        size_t operator()( size_t k ) const
+        {
+            return std::hash<size_t>()(k);
+        }
+    };
+
+    class Map_DelOdd: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nInsThreadCount;      // insert thread count
+        static size_t s_nDelThreadCount;      // delete thread count
+        static size_t s_nExtractThreadCount;  // extract thread count
+        static size_t s_nMapSize;             // max map size
+        static size_t s_nMaxLoadFactor;       // maximum load factor
+        static size_t s_nInsertPassCount;
+        static size_t s_nFindThreadCount;     // find thread count
+
+        static size_t s_nCuckooInitialSize;       // initial size for CuckooMap
+        static size_t s_nCuckooProbesetSize;      // CuckooMap probeset size (only for list-based probeset)
+        static size_t s_nCuckooProbesetThreshold; // CuckooMap probeset threshold (0 - use default)
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static std::vector<size_t> m_arrElements;
+
+        static void SetUpTestCase();
+        static void TearDownTestCase();
+
+        template <typename Pred>
+        static void prepare_array( std::vector<size_t>& arr, Pred pred )
+        {
+            arr.reserve( m_arrElements.size());
+            for ( auto el : m_arrElements ) {
+                if ( pred( el ))
+                    arr.push_back( el );
+            }
+            arr.resize( arr.size());
+            shuffle( arr.begin(), arr.end());
+        }
+
+    protected:
+        typedef key_thread  key_type;
+        typedef size_t      value_type;
+        typedef std::pair<key_type const, value_type> pair_type;
+
+        atomics::atomic<size_t> m_nInsThreadCount;
+
+        enum {
+            inserter_thread,
+            deleter_thread,
+            extractor_thread,
+            find_thread,
+        };
+
+        // Inserts keys from [0..N)
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            struct update_func
+            {
+                template <typename Q>
+                void operator()( bool /*bNew*/, Q const& ) const
+                {}
+
+                template <typename Q, typename V>
+                void operator()( bool /*bNew*/, Q const&, V& ) const
+                {}
+
+                // FeldmanHashMap
+                template <typename Q>
+                void operator()( Q&, Q*) const
+                {}
+            };
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t ) -> bool { return true; } );
+                for ( size_t i = 0; i < m_arr.size(); ++i ) {
+                    if ( m_Map.insert( key_type( m_arr[i], id())))
+                        ++m_nInsertInitSuccess;
+                    else
+                        ++m_nInsertInitFailed;
+                }
+            }
+
+        public:
+            size_t m_nInsertSuccess = 0;
+            size_t m_nInsertFailed = 0;
+            size_t m_nInsertInitSuccess = 0;
+            size_t m_nInsertInitFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, inserter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_DelOdd& fixture = pool().template fixture<Map_DelOdd>();
+
+                update_func f;
+
+                for ( size_t nPass = 0; nPass < s_nInsertPassCount; ++nPass ) {
+                    if ( nPass & 1 ) {
+                        // insert pass
+                        for ( auto el : m_arr ) {
+                            if ( el & 1 ) {
+                                if ( rMap.insert( key_type( el, id())))
+                                    ++m_nInsertSuccess;
+                                else
+                                    ++m_nInsertFailed;
+                            }
+                        }
+                    }
+                    else {
+                        // update pass
+                        for ( auto el : m_arr ) {
+                            if ( el & 1 ) {
+                                bool success;
+                                bool inserted;
+                                std::tie( success, inserted ) = rMap.update( key_type( el, id()), f );
+                                if ( success && inserted )
+                                    ++m_nInsertSuccess;
+                                else
+                                    ++m_nInsertFailed;
+                            }
+                        }
+                    }
+                }
+
+                fixture.m_nInsThreadCount.fetch_sub( 1, atomics::memory_order_release );
+                m_arr.resize( 0 );
+            }
+        };
+
+        struct key_equal {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey == k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 == k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey == k2;
+            }
+        };
+
+        struct key_less {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey < k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 < k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey < k2;
+            }
+
+            typedef key_equal equal_to;
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class Map>
+        class Deleter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 1 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Deleter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, deleter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Deleter( Deleter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Deleter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                Map_DelOdd& fixture = pool().template fixture<Map_DelOdd>();
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    if ( id() & 1 ) {
+                        for ( auto el: m_arr ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( rMap.erase( key_type( el, k )))
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                            }
+                        }
+                    }
+                    else {
+                        for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                            for ( auto el: m_arr ) {
+                                if ( rMap.erase( key_type( el, k )))
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                m_arr.resize( 0 );
+            }
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class GC, class Map >
+        class Extractor: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 1 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                typename Map::guarded_ptr gp;
+                Map_DelOdd& fixture = pool().template fixture<Map_DelOdd>();
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    if ( id() & 1 ) {
+                        for ( auto el : m_arr ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                gp = rMap.extract( key_type( el, k ));
+                                if ( gp )
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                                gp.release();
+                            }
+                        }
+                    }
+                    else {
+                        for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                            for ( auto el: m_arr ) {
+                                gp = rMap.extract( key_type( el, k ));
+                                if ( gp )
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                                gp.release();
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                m_arr.resize( 0 );
+            }
+        };
+
+        template <class RCU, class Map >
+        class Extractor< cds::urcu::gc<RCU>, Map > : public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) -> bool { return ( el & 1 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_DelOdd& fixture = pool().template fixture<Map_DelOdd>();
+
+                typename Map::exempt_ptr xp;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    if ( id() & 1 ) {
+                        for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                            for ( auto el: m_arr ) {
+                                if ( Map::c_bExtractLockExternal ) {
+                                    typename Map::rcu_lock l;
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                else {
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                xp.release();
+                            }
+                        }
+                    }
+                    else {
+                        for ( auto el : m_arr ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( Map::c_bExtractLockExternal ) {
+                                    typename Map::rcu_lock l;
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                else {
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                xp.release();
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                m_arr.resize( 0 );
+            }
+        };
+
+        // Finds keys
+        template <class Map>
+        class Observer: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&                m_Map;
+
+        public:
+            size_t m_nFindEvenSuccess = 0;
+            size_t m_nFindEvenFailed  = 0;
+            size_t m_nFindOddSuccess  = 0;
+            size_t m_nFindOddFailed   = 0;
+
+        public:
+            Observer( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, find_thread )
+                , m_Map( map )
+            {}
+
+            Observer( Observer& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Observer( *this );
+            }
+
+            virtual void test()
+            {
+                Map& map = m_Map;
+                Map_DelOdd& fixture = pool().template fixture<Map_DelOdd>();
+                std::vector<size_t> const& arr = m_arrElements;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    for ( size_t key : arr ) {
+                        if ( key & 1 ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( map.contains( key_thread( key, k )))
+                                    ++m_nFindOddSuccess;
+                                else
+                                    ++m_nFindOddFailed;
+                            }
+                        }
+                        else {
+                            // even keys MUST be in the map
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( map.contains( key_thread( key, k )))
+                                    ++m_nFindEvenSuccess;
+                                else
+                                    ++m_nFindEvenFailed;
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+            }
+        };
+
+    protected:
+        template <class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map>  delete_thread;
+            typedef Observer<Map> observer_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            pool.add( new delete_thread( pool, testMap ), s_nDelThreadCount ? s_nDelThreadCount : cds::OS::topology::processor_count());
+            if ( s_nFindThreadCount )
+                pool.add( new observer_thread( pool, testMap ), s_nFindThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
+                << std::make_pair( "find_thread_count", s_nFindThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nInsertPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertInitFailed = 0;
+            size_t nInsertInitSuccess = 0;
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+
+            size_t nFindEvenSuccess = 0;
+            size_t nFindEvenFailed = 0;
+            size_t nFindOddSuccess = 0;
+            size_t nFindOddFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                    {
+                        insert_thread& inserter = static_cast<insert_thread&>( thr );
+                        nInsertSuccess += inserter.m_nInsertSuccess;
+                        nInsertFailed += inserter.m_nInsertFailed;
+                        nInsertInitSuccess += inserter.m_nInsertInitSuccess;
+                        nInsertInitFailed += inserter.m_nInsertInitFailed;
+                    }
+                    break;
+                case deleter_thread:
+                    {
+                        delete_thread& deleter = static_cast<delete_thread&>( thr );
+                        nDeleteSuccess += deleter.m_nDeleteSuccess;
+                        nDeleteFailed += deleter.m_nDeleteFailed;
+                    }
+                    break;
+                case find_thread:
+                    {
+                        observer_thread& observer = static_cast<observer_thread&>( thr );
+                        nFindEvenSuccess = observer.m_nFindEvenSuccess;
+                        nFindEvenFailed = observer.m_nFindEvenFailed;
+                        nFindOddSuccess = observer.m_nFindOddSuccess;
+                        nFindOddFailed = observer.m_nFindOddFailed;
+                    }
+                    break;
+                }
+            }
+
+            size_t const nInitialOddKeys = ( s_nMapSize * s_nInsThreadCount ) / 2;
+
+            EXPECT_EQ( nInsertInitFailed, 0u );
+            EXPECT_EQ( nInsertInitSuccess, s_nMapSize * s_nInsThreadCount );
+            EXPECT_EQ( nFindEvenFailed, 0u );
+            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess );
+            EXPECT_LE( nInsertSuccess, nDeleteSuccess );
+
+            propout()
+                << std::make_pair( "insert_init_success", nInsertInitSuccess )
+                << std::make_pair( "insert_init_failed", nInsertInitFailed )
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "find_even_success", nFindEvenSuccess )
+                << std::make_pair( "find_even_failed", nFindEvenFailed )
+                << std::make_pair( "find_odd_success", nFindOddSuccess )
+                << std::make_pair( "find_odd_failed", nFindOddFailed );
+
+            analyze( testMap );
+        }
+
+        template <class Map>
+        void do_test_extract( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map> delete_thread;
+            typedef Extractor< typename Map::gc, Map > extract_thread;
+            typedef Observer<Map> observer_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            if ( s_nDelThreadCount )
+                pool.add( new delete_thread( pool, testMap ), s_nDelThreadCount );
+            if ( s_nExtractThreadCount )
+                pool.add( new extract_thread( pool, testMap ), s_nExtractThreadCount );
+            if ( s_nFindThreadCount )
+                pool.add( new observer_thread( pool, testMap ), s_nFindThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
+                << std::make_pair( "extract_thread_count", s_nExtractThreadCount )
+                << std::make_pair( "find_thread_count", s_nFindThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nInsertPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertInitFailed = 0;
+            size_t nInsertInitSuccess = 0;
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+            size_t nExtractSuccess = 0;
+            size_t nExtractFailed = 0;
+
+            size_t nFindEvenSuccess = 0;
+            size_t nFindEvenFailed = 0;
+            size_t nFindOddSuccess = 0;
+            size_t nFindOddFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                {
+                    insert_thread& inserter = static_cast<insert_thread&>(thr);
+                    nInsertSuccess += inserter.m_nInsertSuccess;
+                    nInsertFailed += inserter.m_nInsertFailed;
+                    nInsertInitSuccess += inserter.m_nInsertInitSuccess;
+                    nInsertInitFailed += inserter.m_nInsertInitFailed;
+                }
+                break;
+                case deleter_thread:
+                {
+                    delete_thread& deleter = static_cast<delete_thread&>(thr);
+                    nDeleteSuccess += deleter.m_nDeleteSuccess;
+                    nDeleteFailed += deleter.m_nDeleteFailed;
+                }
+                break;
+                case extractor_thread:
+                {
+                    extract_thread& extractor = static_cast<extract_thread&>(thr);
+                    nExtractSuccess += extractor.m_nDeleteSuccess;
+                    nExtractFailed += extractor.m_nDeleteFailed;
+                }
+                break;
+                case find_thread:
+                {
+                    observer_thread& observer = static_cast<observer_thread&>( thr );
+                    nFindEvenSuccess = observer.m_nFindEvenSuccess;
+                    nFindEvenFailed = observer.m_nFindEvenFailed;
+                    nFindOddSuccess = observer.m_nFindOddSuccess;
+                    nFindOddFailed = observer.m_nFindOddFailed;
+                }
+                break;
+                default:
+                    assert( false );
+                }
+            }
+
+            size_t const nInitialOddKeys = ( s_nMapSize * s_nInsThreadCount ) / 2;
+
+            EXPECT_EQ( nInsertInitFailed, 0u );
+            EXPECT_EQ( nInsertInitSuccess, s_nMapSize * s_nInsThreadCount );
+            EXPECT_EQ( nFindEvenFailed, 0u );
+            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess + nExtractSuccess );
+            EXPECT_LE( nInsertSuccess, nDeleteSuccess + nExtractSuccess );
+
+            propout()
+                << std::make_pair( "insert_init_success", nInsertInitSuccess )
+                << std::make_pair( "insert_init_failed", nInsertInitFailed )
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "extract_success", nExtractSuccess )
+                << std::make_pair( "extract_failed", nExtractFailed )
+                << std::make_pair( "find_even_success", nFindEvenSuccess )
+                << std::make_pair( "find_even_failed", nFindEvenFailed )
+                << std::make_pair( "find_odd_success", nFindOddSuccess )
+                << std::make_pair( "find_odd_failed", nFindOddFailed );
+
+            analyze( testMap );
+        }
+
+        template <class Map>
+        void analyze( Map& testMap )
+        {
+            // All even keys must be in the map
+            {
+                for ( size_t n = 0; n < s_nMapSize; n +=2 ) {
+                    for ( size_t i = 0; i < s_nInsThreadCount; ++i ) {
+                        EXPECT_TRUE( testMap.contains( key_type( n, i ))) << "key=" << n << "/" << i;
+                    }
+                }
+            }
+
+            print_stat( propout(), testMap );
+
+            check_before_cleanup( testMap );
+            testMap.clear();
+            EXPECT_TRUE( testMap.empty()) << "map.size=" << testMap.size();
+
+            additional_check( testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test_extract()
+        {
+            static_assert( Map::c_bExtractSupported, "Map class must support extract() method" );
+
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test_extract( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test( testMap );
+        }
+
+        template <class Map>
+        void run_feldman();
+    };
+
+    class Map_DelOdd_LF: public Map_DelOdd
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Map>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_DelOdd::run_test<Map>();
+        }
+
+        template <class Map>
+        void run_test_extract()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_DelOdd::run_test_extract<Map>();
+        }
+
+        static std::vector<size_t> get_load_factors();
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd_bronsonavltree.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..ec1ffe0
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_DelOdd, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd_cuckoo.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd_cuckoo.cpp
new file mode 100644 (file)
index 0000000..f9b1b40
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+#include "map_type_cuckoo.h"
+
+namespace map {
+
+//    CDSSTRESS_CuckooMap( Map_DelOdd, run_test, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd_ellentree.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd_ellentree.cpp
new file mode 100644 (file)
index 0000000..9170785
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap( Map_DelOdd, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd_feldman_hashmap.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd_feldman_hashmap.cpp
new file mode 100644 (file)
index 0000000..aa2a5fa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    template <class Map>
+    void Map_DelOdd::run_feldman()
+    {
+        typedef typename Map::traits original_traits;
+        struct traits: public original_traits {
+            enum { hash_size = sizeof( uint32_t ) + sizeof( uint16_t ) };
+        };
+        typedef typename Map::template rebind_traits< traits >::result map_type;
+
+        run_test_extract<map_type>();
+    }
+
+    CDSSTRESS_FeldmanHashMap_fixed( Map_DelOdd, run_feldman, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd_michael.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd_michael.cpp
new file mode 100644 (file)
index 0000000..49d3f43
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    CDSSTRESS_MichaelMap( Map_DelOdd_LF, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd_skip.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd_skip.cpp
new file mode 100644 (file)
index 0000000..139dc36
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap( Map_DelOdd, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/delodd/map_delodd_split.cpp b/test/stress/sequential/sequential-map/delodd/map_delodd_split.cpp
new file mode 100644 (file)
index 0000000..8553b27
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_delodd.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap( Map_DelOdd_LF, run_test_extract, key_thread, size_t )
+    CDSSTRESS_SplitListIterableMap( Map_DelOdd_LF, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/CMakeLists.txt b/test/stress/sequential/sequential-map/find_string/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f079ba5
--- /dev/null
@@ -0,0 +1,25 @@
+set(PACKAGE_NAME stress-sequential-map-find-string)
+
+set(CDSSTRESS_MAP_FIND_STRING_SOURCES
+    ../../../main.cpp
+    map_find_string.cpp
+    map_find_string_bronsonavltree.cpp
+    map_find_string_cuckoo.cpp
+    map_find_string_ellentree.cpp
+    map_find_string_feldman_hashset.cpp
+    map_find_string_michael.cpp
+    map_find_string_skip.cpp
+    map_find_string_split.cpp
+    map_find_string_std.cpp
+    map_find_string_striped.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_FIND_STRING_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string.cpp
new file mode 100644 (file)
index 0000000..7da0e8d
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include <cds_test/hash_func.h>
+
+namespace map {
+
+    size_t Map_find_string::s_nThreadCount = 8;
+    size_t Map_find_string::s_nMapSize = 10000000;
+    size_t Map_find_string::s_nMaxLoadFactor = 8;
+    size_t Map_find_string::s_nPercentExists = 50;
+    size_t Map_find_string::s_nPassCount = 2;
+
+    size_t Map_find_string::s_nCuckooInitialSize = 1024;
+    size_t Map_find_string::s_nCuckooProbesetSize = 16;
+    size_t Map_find_string::s_nCuckooProbesetThreshold = 0;
+
+    size_t Map_find_string::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_find_string::s_nFeldmanMap_ArrayBits = 4;
+
+
+    size_t Map_find_string::s_nLoadFactor = 1;
+    Map_find_string::value_vector Map_find_string::s_Data;
+    std::vector<std::string> Map_find_string::s_arrString;
+
+    void Map_find_string::setup_test_case()
+    {
+        cds_test::config const& cfg = get_config( "map_find_string" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nThreadCount = cfg.get_size_t( "ThreadCount", s_nThreadCount );
+        if ( s_nThreadCount == 0 )
+            s_nThreadCount = 1;
+
+        s_nPercentExists = cfg.get_size_t( "PercentExists", s_nPercentExists );
+        if ( s_nPercentExists > 100 )
+            s_nPercentExists = 100;
+        else if ( s_nPercentExists < 1 )
+            s_nPercentExists = 1;
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
+        if ( s_nCuckooInitialSize < 256 )
+            s_nCuckooInitialSize = 256;
+
+        s_nCuckooProbesetSize = cfg.get_size_t( "CuckooProbesetSize", s_nCuckooProbesetSize );
+        if ( s_nCuckooProbesetSize < 8 )
+            s_nCuckooProbesetSize = 8;
+
+        s_nCuckooProbesetThreshold = cfg.get_size_t( "CuckooProbesetThreshold", s_nCuckooProbesetThreshold );
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+
+        s_arrString = load_dictionary();
+    }
+
+    void Map_find_string::TearDownTestCase()
+    {
+        s_arrString.clear();
+        s_Data.clear();
+    }
+
+    void Map_find_string::SetUpTestCase()
+    {
+        setup_test_case();
+
+        s_Data.clear();
+
+        size_t nSize = s_arrString.size();
+        if ( nSize > s_nMapSize )
+            nSize = s_nMapSize;
+        s_Data.reserve( nSize );
+
+        size_t nActualSize = 0;
+        for ( size_t i = 0; i < nSize; ++i ) {
+            bool bExists = rand( 100 ) <= s_nPercentExists;
+            if ( bExists )
+                ++nActualSize;
+            s_Data.push_back( { &s_arrString.at( i ), bExists } );
+        }
+        s_nMapSize = nActualSize;
+    }
+
+    template <typename Hash>
+    void Map_find_string::fill_string_array()
+    {
+        typedef Hash hasher;
+        typedef typename hasher::result_type hash_type;
+
+        std::map<hash_type, size_t> mapHash;
+        s_Data.clear();
+
+        size_t nSize = s_arrString.size();
+        if ( nSize > s_nMapSize )
+            nSize = s_nMapSize;
+        s_Data.reserve( nSize );
+
+        size_t nActualSize = 0;
+        size_t nDiffHash = 0;
+        hasher h;
+        for ( size_t i = 0; i < s_arrString.size(); ++i ) {
+            hash_type hash = h( s_arrString.at( i ));
+            if ( mapHash.insert( std::make_pair( hash, i )).second ) {
+                if ( ++nDiffHash >= nSize )
+                    break;
+                bool bExists = rand( 100 ) <= s_nPercentExists;
+                if ( bExists )
+                    ++nActualSize;
+                s_Data.push_back( { &s_arrString.at( i ), bExists } );
+            }
+        }
+        s_nMapSize = nActualSize;
+
+    }
+
+    void Map_find_string_stdhash::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<std::hash<std::string>>();
+    }
+
+#if CDS_BUILD_BITS == 64
+    void Map_find_string_city32::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<cds_test::city32>();
+    }
+
+    void Map_find_string_city64::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<cds_test::city64>();
+    }
+
+    void Map_find_string_city128::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<cds_test::city128>();
+    }
+
+#endif
+
+    std::vector<size_t> Map_find_string::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_find_string" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_find_string_LF, ::testing::ValuesIn( Map_find_string::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_find_string_LF, ::testing::ValuesIn( Map_find_string::get_load_factors()));
+#endif
+
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string.h b/test/stress/sequential/sequential-map/find_string/map_find_string.h
new file mode 100644 (file)
index 0000000..5479e3b
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+
+namespace map {
+
+    class Map_find_string: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nThreadCount;       // thread count
+        static size_t s_nMapSize;           // map size (count of searching item)
+        static size_t s_nPercentExists;     // percent of existing keys in searching sequence
+        static size_t s_nPassCount;
+        static size_t s_nMaxLoadFactor;     // maximum load factor
+
+        static size_t s_nCuckooInitialSize;         // initial size for CuckooMap
+        static size_t s_nCuckooProbesetSize;        // CuckooMap probeset size (only for list-based probeset)
+        static size_t s_nCuckooProbesetThreshold;   // CUckooMap probeset threshold (o - use default)
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t s_nLoadFactor;  // current load factor
+
+        typedef std::string  key_type;
+        struct value_type {
+            std::string const* pKey;
+            bool        bExists ;   // true - key in map, false - key not in map
+        };
+
+        typedef std::vector<value_type> value_vector;
+        static std::vector<std::string> s_arrString;
+        static value_vector s_Data;
+
+        static void SetUpTestCase();
+        static void TearDownTestCase();
+
+        static void setup_test_case();
+        static std::vector<size_t> get_load_factors();
+
+    private:
+        template <typename Iterator, typename Map>
+        static bool check_result( Iterator const& it, Map const& map )
+        {
+            return it != map.end();
+        }
+        template <typename Map>
+        static bool check_result( bool b, Map const& )
+        {
+            return b;
+        }
+
+        template <class Map>
+        class Worker: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+        public:
+            struct Stat {
+                size_t      nSuccess = 0;
+                size_t      nFailed = 0;
+            };
+
+            Stat    m_KeyExists;
+            Stat    m_KeyNotExists;
+
+        public:
+            Worker( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool )
+                , m_Map( map )
+                , m_KeyExists()
+                , m_KeyNotExists()
+            {}
+
+            Worker( Worker& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+                , m_KeyExists()
+                , m_KeyNotExists()
+            {}
+
+            virtual thread * clone()
+            {
+                return new Worker( *this );
+            }
+            virtual void test()
+            {
+                size_t const nPassCount = s_nPassCount;
+
+                Map& rMap = m_Map;
+                for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                    if ( id() & 1 ) {
+                        auto itEnd = s_Data.cend();
+                        for ( auto it = s_Data.cbegin(); it != itEnd; ++it ) {
+                            auto bFound = rMap.contains( *(it->pKey));
+                            if ( it->bExists ) {
+                                if ( check_result(bFound, rMap))
+                                    ++m_KeyExists.nSuccess;
+                                else
+                                    ++m_KeyExists.nFailed;
+                            }
+                            else {
+                                if ( check_result(bFound, rMap))
+                                    ++m_KeyNotExists.nFailed;
+                                else
+                                    ++m_KeyNotExists.nSuccess;
+                            }
+                        }
+                    }
+                    else {
+                        auto itEnd = s_Data.crend();
+                        for ( auto it = s_Data.crbegin(); it != itEnd; ++it ) {
+                            auto bFound = rMap.contains( *(it->pKey));
+                            if ( it->bExists ) {
+                                if ( check_result(bFound, rMap))
+                                    ++m_KeyExists.nSuccess;
+                                else
+                                    ++m_KeyExists.nFailed;
+                            }
+                            else {
+                                if ( check_result( bFound, rMap ))
+                                    ++m_KeyNotExists.nFailed;
+                                else
+                                    ++m_KeyNotExists.nSuccess;
+                            }
+                        }
+                    }
+                }
+            }
+        };
+
+    protected:
+        template <typename Hash>
+        static void fill_string_array();
+
+        template <class Map>
+        void test( Map& testMap )
+        {
+            typedef Worker<Map> worker;
+
+            // Fill the map
+            for ( size_t i = 0; i < s_Data.size(); ++i ) {
+                // All keys in arrData are unique, insert() must be successful
+                if ( s_Data[i].bExists ) {
+                    EXPECT_TRUE( check_result( testMap.insert( *(s_Data[i].pKey), s_Data[i] ), testMap ));
+                }
+            }
+
+            propout() << std::make_pair( "thread_count", s_nThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "percent_exist", s_nPercentExists )
+                << std::make_pair( "pass_count", s_nPassCount );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new worker( pool, testMap ), s_nThreadCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nExistSuccess = 0;
+            size_t nExistFailed = 0;
+            size_t nMissingSuccess = 0;
+            size_t nMissingFailed = 0;
+
+            // Postcondition: the number of success searching == the number of map item
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                worker& w = static_cast<worker&>(pool.get( i ));
+                nExistSuccess += w.m_KeyExists.nSuccess;
+                nExistFailed += w.m_KeyExists.nFailed;
+                nMissingSuccess += w.m_KeyNotExists.nSuccess;
+                nMissingFailed += w.m_KeyNotExists.nFailed;
+
+                EXPECT_EQ( w.m_KeyExists.nSuccess, s_nMapSize * s_nPassCount ) << "thread " << i;
+                EXPECT_EQ( w.m_KeyExists.nFailed, 0u ) << "thread " << i;
+                EXPECT_EQ( w.m_KeyNotExists.nSuccess, (s_Data.size() - s_nMapSize) * s_nPassCount ) << "thread " << i;
+                EXPECT_EQ( w.m_KeyNotExists.nFailed, 0u ) << "thread " << i;
+            }
+
+            propout()
+                << std::make_pair( "exist_found", nExistSuccess )
+                << std::make_pair( "exist_not_found", nExistFailed )  // must = 0
+                << std::make_pair( "missing_not_found", nMissingSuccess )
+                << std::make_pair( "missing_found", nMissingFailed );  // must = 0
+
+            check_before_cleanup( testMap );
+
+            testMap.clear();
+            additional_check( testMap );
+            print_stat( propout(), testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            ASSERT_GT( s_Data.size(), 0u );
+
+            Map testMap( *this );
+            test( testMap );
+        }
+    };
+
+    class Map_find_string_stdhash: public Map_find_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_find_string::run_test<Map>();
+        }
+    };
+
+#if CDS_BUILD_BITS == 64
+    class Map_find_string_city32: public Map_find_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_find_string::run_test<Map>();
+        }
+    };
+
+    class Map_find_string_city64: public Map_find_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_find_string::run_test<Map>();
+        }
+    };
+
+    class Map_find_string_city128: public Map_find_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_find_string::run_test<Map>();
+        }
+    };
+
+#endif // #if CDS_BUILD_BITS == 64
+
+    class Map_find_string_LF: public Map_find_string
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Map>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_find_string::run_test<Map>();
+        }
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_bronsonavltree.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..fe18050
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_find_string, run_test, std::string, Map_find_string::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_cuckoo.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_cuckoo.cpp
new file mode 100644 (file)
index 0000000..4e4bb1d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_cuckoo.h"
+
+namespace map {
+
+//    CDSSTRESS_CuckooMap( Map_find_string, run_test, std::string, Map_find_string::value_type )
+#if CDS_BUILD_BITS == 64
+//    CDSSTRESS_CuckooMap_city64( Map_find_string, run_test, std::string, Map_find_string::value_type )
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_ellentree.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_ellentree.cpp
new file mode 100644 (file)
index 0000000..9cd3da2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap( Map_find_string, run_test, std::string, Map_find_string::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_feldman_hashset.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_feldman_hashset.cpp
new file mode 100644 (file)
index 0000000..84b370e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    CDSSTRESS_FeldmanHashMap_stdhash( Map_find_string_stdhash, run_test, std::string, Map_find_string::value_type )
+#if CDS_BUILD_BITS == 64
+    CDSSTRESS_FeldmanHashMap_city64(  Map_find_string_city64,  run_test, std::string, Map_find_string::value_type )
+    CDSSTRESS_FeldmanHashMap_city128( Map_find_string_city128, run_test, std::string, Map_find_string::value_type )
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_michael.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_michael.cpp
new file mode 100644 (file)
index 0000000..b649f37
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    CDSSTRESS_MichaelMap(      Map_find_string_LF, run_test, std::string, Map_find_string::value_type )
+    CDSSTRESS_MichaelMap_nogc( Map_find_string_LF, run_test, std::string, Map_find_string::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_skip.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_skip.cpp
new file mode 100644 (file)
index 0000000..e790568
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap(      Map_find_string, run_test, std::string, Map_find_string::value_type )
+    CDSSTRESS_SkipListMap_nogc( Map_find_string, run_test, std::string, Map_find_string::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_split.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_split.cpp
new file mode 100644 (file)
index 0000000..b90be37
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap(      Map_find_string_LF, run_test, std::string, Map_find_string::value_type )
+    CDSSTRESS_SplitListIterableMap( Map_find_string_LF, run_test, std::string, Map_find_string::value_type )
+    CDSSTRESS_SplitListMap_nogc( Map_find_string_LF, run_test, std::string, Map_find_string::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_std.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_std.cpp
new file mode 100644 (file)
index 0000000..0f1081f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_std.h"
+
+namespace map {
+
+//    CDSSTRESS_StdMap(        Map_find_string, run_test, std::string, Map_find_string::value_type )
+//    CDSSTRESS_StdMap_nolock( Map_find_string, run_test, std::string, Map_find_string::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/find_string/map_find_string_striped.cpp b/test/stress/sequential/sequential-map/find_string/map_find_string_striped.cpp
new file mode 100644 (file)
index 0000000..aefd638
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_find_string.h"
+#include "map_type_striped.h"
+
+namespace map {
+
+//    CDSSTRESS_StripedMap( Map_find_string_LF, run_test, std::string, Map_find_string::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/CMakeLists.txt b/test/stress/sequential/sequential-map/insdel_func/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8a0846f
--- /dev/null
@@ -0,0 +1,24 @@
+set(PACKAGE_NAME stress-sequential-map-insdel-func)
+
+set(CDSSTRESS_MAP_INSDEL_FUNC_SOURCES
+    ../../../main.cpp
+    map_insdel_func.cpp
+    map_insdel_func_bronsonavltree.cpp
+    map_insdel_func_cuckoo.cpp
+    map_insdel_func_ellentree.cpp
+    map_insdel_func_feldman_hashset.cpp
+    map_insdel_func_michael.cpp
+    map_insdel_func_skip.cpp
+    map_insdel_func_split.cpp
+    map_insdel_func_striped.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_INSDEL_FUNC_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func.cpp
new file mode 100644 (file)
index 0000000..a5245f3
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+
+namespace map {
+
+    size_t Map_InsDel_func::s_nMapSize = 1000000;      // map size
+    size_t Map_InsDel_func::s_nInsertThreadCount = 4;  // count of insertion thread
+    size_t Map_InsDel_func::s_nDeleteThreadCount = 4;  // count of deletion thread
+    size_t Map_InsDel_func::s_nUpdateThreadCount = 4;  // count of ensure thread
+    size_t Map_InsDel_func::s_nThreadPassCount = 4;    // pass count for each thread
+    size_t Map_InsDel_func::s_nMaxLoadFactor = 8;      // maximum load factor
+
+    size_t Map_InsDel_func::s_nCuckooInitialSize = 1024;// initial size for CuckooSet
+    size_t Map_InsDel_func::s_nCuckooProbesetSize = 16; // CuckooSet probeset size (only for list-based probeset)
+    size_t Map_InsDel_func::s_nCuckooProbesetThreshold = 0; // CUckooSet probeset threshold (0 - use default)
+
+    size_t Map_InsDel_func::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_InsDel_func::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_InsDel_func::s_nLoadFactor = 1;
+    Map_InsDel_func::key_array Map_InsDel_func::s_arrKeys;
+
+    void Map_InsDel_func::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "map_insdel_func" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsertThreadCount = cfg.get_size_t( "InsertThreadCount", s_nInsertThreadCount );
+        if ( s_nInsertThreadCount == 0 )
+            s_nInsertThreadCount = 2;
+
+        s_nDeleteThreadCount = cfg.get_size_t( "DeleteThreadCount", s_nDeleteThreadCount );
+        if ( s_nDeleteThreadCount == 0 )
+            s_nDeleteThreadCount = 2;
+
+        s_nUpdateThreadCount = cfg.get_size_t( "UpdateThreadCount", s_nUpdateThreadCount );
+        //if ( s_nUpdateThreadCount == 0 )
+        //    s_nUpdateThreadCount = 2;
+
+        s_nThreadPassCount = cfg.get_size_t( "ThreadPassCount", s_nThreadPassCount );
+        if ( s_nThreadPassCount == 0 )
+            s_nThreadPassCount = 4;
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
+        if ( s_nCuckooInitialSize < 256 )
+            s_nCuckooInitialSize = 256;
+
+        s_nCuckooProbesetSize = cfg.get_size_t( "CuckooProbesetSize", s_nCuckooProbesetSize );
+        if ( s_nCuckooProbesetSize < 8 )
+            s_nCuckooProbesetSize = 8;
+
+        s_nCuckooProbesetThreshold = cfg.get_size_t( "CuckooProbesetThreshold", s_nCuckooProbesetThreshold );
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+
+        s_arrKeys.clear();
+        s_arrKeys.reserve( s_nMapSize );
+        for ( size_t i = 0; i < s_nMapSize; ++i )
+            s_arrKeys.push_back( i );
+        shuffle( s_arrKeys.begin(), s_arrKeys.end());
+    }
+
+    void Map_InsDel_func::TearDownTestCase()
+    {
+        s_arrKeys.clear();
+    }
+
+    std::vector<size_t> Map_InsDel_func_LF::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_insdel_func" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDel_func_LF, ::testing::ValuesIn( Map_InsDel_func_LF::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDel_func_LF, ::testing::ValuesIn( Map_InsDel_func_LF::get_load_factors()));
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func.h b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func.h
new file mode 100644 (file)
index 0000000..b2605ca
--- /dev/null
@@ -0,0 +1,572 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+
+namespace map {
+
+    class Map_InsDel_func: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nMapSize;           // map size
+        static size_t s_nInsertThreadCount; // count of insertion thread
+        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_nMaxLoadFactor;     // maximum load factor
+
+        static size_t s_nCuckooInitialSize;         // initial size for CuckooMap
+        static size_t s_nCuckooProbesetSize;        // CuckooMap probeset size (only for list-based probeset)
+        static size_t s_nCuckooProbesetThreshold;   // CuckooMap probeset threshold (o - use default)
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t s_nLoadFactor;  // current load factor
+
+        static void SetUpTestCase();
+        static void TearDownTestCase();
+
+        typedef size_t  key_type;
+        struct value_type {
+            size_t      nKey;
+            size_t      nData;
+            size_t      nUpdateCall;
+            atomics::atomic<bool>   bInitialized;
+            cds::OS::ThreadId       threadId;   // inserter thread id
+
+            typedef cds::sync::spin_lock< cds::backoff::pause > lock_type;
+            mutable lock_type   m_access;
+
+            value_type()
+                : nKey(0)
+                , nData(0)
+                , nUpdateCall(0)
+                , bInitialized( false )
+                , threadId( cds::OS::get_current_thread_id())
+            {}
+
+            value_type( value_type const& s )
+                : nKey(s.nKey)
+                , nData(s.nData)
+                , nUpdateCall( s.nUpdateCall )
+                , bInitialized( s.bInitialized.load(atomics::memory_order_relaxed))
+                , threadId( cds::OS::get_current_thread_id())
+                , m_access()
+            {}
+
+            // boost::container::flat_map requires operator =
+            // cppcheck-suppress operatorEqVarError
+            value_type& operator=( value_type const& v )
+            {
+                nKey = v.nKey;
+                nData = v.nData;
+                nUpdateCall = v.nUpdateCall;
+                threadId = v.threadId;
+                bInitialized.store(v.bInitialized.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed);
+
+                return *this;
+            }
+        };
+
+        typedef std::vector<key_type>   key_array;
+        static key_array                s_arrKeys;
+
+    protected:
+        enum {
+            insert_thread,
+            delete_thread,
+            update_thread
+        };
+
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            struct insert_functor {
+                size_t nTestFunctorRef;
+
+                insert_functor()
+                    : nTestFunctorRef(0)
+                {}
+
+                template <typename Pair>
+                void operator()( Pair& val )
+                {
+                    operator()( val.first, val.second );
+                }
+
+                template <typename Key, typename Val >
+                void operator()( Key const& key, Val& v )
+                {
+                    std::unique_lock< typename value_type::lock_type> ac( v.m_access );
+
+                    v.nKey  = key;
+                    v.nData = key * 8;
+
+                    ++nTestFunctorRef;
+                    v.bInitialized.store( true, atomics::memory_order_relaxed);
+                }
+            };
+
+        public:
+            size_t  m_nInsertSuccess = 0;
+            size_t  m_nInsertFailed = 0;
+
+            size_t  m_nTestFunctorRef = 0;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, insert_thread )
+                , m_Map( map )
+            {}
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                // func is passed by reference
+                insert_functor  func;
+                size_t const nPassCount = s_nThreadPassCount;
+
+                if ( id() & 1 ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( key_array::const_iterator it = s_arrKeys.begin(), itEnd = s_arrKeys.end(); it != itEnd; ++it ) {
+                            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 = s_arrKeys.rbegin(), itEnd = s_arrKeys.rend(); it != itEnd; ++it ) {
+                            if ( rMap.insert_with( *it, std::ref(func)))
+                                ++m_nInsertSuccess;
+                            else
+                                ++m_nInsertFailed;
+                        }
+                    }
+                }
+
+                m_nTestFunctorRef = func.nTestFunctorRef;
+            }
+        };
+
+        template <class Map>
+        class Updater: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            struct update_functor {
+                size_t  nCreated = 0;
+                size_t  nModified = 0;
+
+                update_functor() = default;
+
+                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 );
+                    if ( !v.bInitialized.load( atomics::memory_order_acquire )) {
+                        ++nCreated;
+                        v.nKey = key;
+                        v.nData = key * 8;
+                        v.bInitialized.store( true, atomics::memory_order_relaxed);
+                    }
+                    else {
+                        ++v.nUpdateCall;
+                        ++nModified;
+                    }
+                }
+
+                template <typename Pair>
+                void operator()( bool bNew, Pair& val )
+                {
+                    operator()( bNew, val.first, val.second );
+                }
+
+                // For FeldmanHashMap, IterableList
+                template <typename Val>
+                void operator()( Val& cur, Val * old )
+                {
+                    if ( old ) {
+                        // If a key exists, FeldmanHashMap creates a new node too
+                        // We should manually copy important values from old to cur
+                        std::unique_lock<typename value_type::lock_type> ac( cur.second.m_access );
+                        cur.second.nKey = cur.first;
+                        cur.second.nData = cur.first * 8;
+                        cur.second.bInitialized.store( true, atomics::memory_order_release );
+                    }
+                    operator()( old == nullptr, cur.first, cur.second );
+                }
+
+            private:
+                update_functor(const update_functor& ) = delete;
+            };
+
+        public:
+            size_t  m_nUpdateFailed = 0;
+            size_t  m_nUpdateCreated = 0;
+            size_t  m_nUpdateExisted = 0;
+            size_t  m_nFunctorCreated = 0;
+            size_t  m_nFunctorModified = 0;
+
+        public:
+            Updater( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, update_thread )
+                , m_Map( map )
+            {}
+
+            Updater( Updater& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Updater( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                update_functor func;
+                size_t const nPassCount = s_nThreadPassCount;
+
+                if ( id() & 1 ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( key_array::const_iterator it = s_arrKeys.begin(), itEnd = s_arrKeys.end(); it != itEnd; ++it ) {
+                            std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ));
+                            if ( ret.first  ) {
+                                if ( ret.second )
+                                    ++m_nUpdateCreated;
+                                else
+                                    ++m_nUpdateExisted;
+                            }
+                            else
+                                ++m_nUpdateFailed;
+                        }
+                    }
+                }
+                else {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( key_array::const_reverse_iterator it = s_arrKeys.rbegin(), itEnd = s_arrKeys.rend(); it != itEnd; ++it ) {
+                            std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ));
+                            if ( ret.first  ) {
+                                if ( ret.second )
+                                    ++m_nUpdateCreated;
+                                else
+                                    ++m_nUpdateExisted;
+                            }
+                            else
+                                ++m_nUpdateFailed;
+                        }
+                    }
+                }
+
+                m_nFunctorCreated = func.nCreated;
+                m_nFunctorModified = func.nModified;
+            }
+        };
+
+        template <class Map>
+        class Deleter: public cds_test::thread
+        {
+            Map&     m_Map;
+            typedef cds_test::thread base_class;
+            typedef typename Map::mapped_type value_type;
+
+            struct value_container
+            {
+                size_t      nKeyExpected;
+
+                size_t      nSuccessItem;
+                size_t      nFailedItem;
+
+                value_container()
+                    : nKeyExpected()
+                    , nSuccessItem(0)
+                    , nFailedItem(0)
+                {}
+            };
+
+            struct erase_functor {
+                value_container     m_cnt;
+
+                template <typename Key, typename Val>
+                void operator()( Key const& /*key*/, Val& v )
+                {
+                    while ( true ) {
+                        if ( v.bInitialized.load( atomics::memory_order_relaxed )) {
+                            std::unique_lock< typename value_type::lock_type> ac( v.m_access );
+
+                            if ( m_cnt.nKeyExpected == v.nKey && m_cnt.nKeyExpected * 8 == v.nData )
+                                ++m_cnt.nSuccessItem;
+                            else
+                                ++m_cnt.nFailedItem;
+                            v.nData++;
+                            v.nKey = 0;
+                            break;
+                        }
+                        else
+                            cds::backoff::yield()();
+                    }
+                }
+
+                template <typename Pair>
+                void operator ()( Pair& item )
+                {
+                    operator()( item.first, item.second );
+                }
+            };
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+            size_t  m_nValueSuccess = 0;
+            size_t  m_nValueFailed = 0;
+
+        public:
+            Deleter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, delete_thread )
+                , m_Map( map )
+            {}
+
+            Deleter( Deleter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Deleter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                erase_functor   func;
+                size_t const nPassCount = s_nThreadPassCount;
+
+                if ( id() & 1 ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( key_array::const_iterator it = s_arrKeys.cbegin(), itEnd = s_arrKeys.cend(); it != itEnd; ++it ) {
+                            func.m_cnt.nKeyExpected = *it;
+                            if ( rMap.erase( *it, std::ref(func)))
+                                ++m_nDeleteSuccess;
+                            else
+                                ++m_nDeleteFailed;
+                        }
+                    }
+                }
+                else {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
+                        for ( key_array::const_reverse_iterator it = s_arrKeys.crbegin(), itEnd = s_arrKeys.crend(); it != itEnd; ++it ) {
+                            func.m_cnt.nKeyExpected = *it;
+                            if ( rMap.erase( *it, std::ref(func)))
+                                ++m_nDeleteSuccess;
+                            else
+                                ++m_nDeleteFailed;
+                        }
+                    }
+                }
+
+                m_nValueSuccess = func.m_cnt.nSuccessItem;
+                m_nValueFailed = func.m_cnt.nFailedItem;
+            }
+        };
+
+    protected:
+
+        template <class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map> inserter;
+            typedef Deleter<Map>  deleter;
+            typedef Updater<Map>  updater;
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new inserter( pool, testMap ), s_nInsertThreadCount );
+            pool.add( new deleter( pool, testMap ), s_nDeleteThreadCount );
+            if ( s_nUpdateThreadCount )
+                pool.add( new updater( pool, testMap ), s_nUpdateThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsertThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDeleteThreadCount )
+                << std::make_pair( "update_thread_count", s_nUpdateThreadCount )
+                << std::make_pair( "pass_count", s_nThreadPassCount )
+                << std::make_pair( "map_size", s_nMapSize );
+
+            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 nInsFuncCalled = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case insert_thread:
+                    {
+                        inserter& t = static_cast<inserter&>( thr );
+                        nInsertSuccess += t.m_nInsertSuccess;
+                        nInsertFailed += t.m_nInsertFailed;
+                        nInsFuncCalled += t.m_nTestFunctorRef;
+                    }
+                    break;
+                case delete_thread:
+                    {
+                        deleter& t = static_cast<deleter&>(thr);
+                        nDeleteSuccess += t.m_nDeleteSuccess;
+                        nDeleteFailed += t.m_nDeleteFailed;
+                        nDelValueSuccess += t.m_nValueSuccess;
+                        nDelValueFailed += t.m_nValueFailed;
+                    }
+                    break;
+                case update_thread:
+                    {
+                        updater& t = static_cast<updater&>(thr);
+                        nUpdateCreated += t.m_nUpdateCreated;
+                        nUpdateModified += t.m_nUpdateExisted;
+                        nUpdateFailed += t.m_nUpdateFailed;
+                        nEnsFuncCreated += t.m_nFunctorCreated;
+                        nEnsFuncModified += t.m_nFunctorModified;
+                    }
+                    break;
+                default:
+                    assert( false );
+                }
+            }
+
+            propout()
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed",  nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed",  nDeleteFailed )
+                << std::make_pair( "update_success", nUpdateCreated + nUpdateModified )
+                << std::make_pair( "update_failed",  nUpdateFailed )
+                << std::make_pair( "update_functor_create", nEnsFuncCreated )
+                << std::make_pair( "update_functor_modify", nEnsFuncModified )
+                << std::make_pair( "finish_map_size", testMap.size());
+
+            EXPECT_EQ( nDelValueFailed, 0u );
+            EXPECT_EQ( nDelValueSuccess, nDeleteSuccess );
+            EXPECT_EQ( nUpdateFailed, 0u );
+            EXPECT_EQ( nUpdateCreated + nUpdateModified, nEnsFuncCreated + nEnsFuncModified );
+
+            // nInsFuncCalled is call count of insert functor
+            EXPECT_EQ( nInsFuncCalled, nInsertSuccess );
+
+            check_before_cleanup( testMap );
+
+            for ( size_t nItem = 0; nItem < s_nMapSize; ++nItem )
+                testMap.erase( nItem );
+
+            EXPECT_TRUE( testMap.empty());
+            EXPECT_EQ( testMap.size(), 0u );
+
+            additional_check( testMap );
+            print_stat( propout(), testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            Map testMap( *this );
+            do_test( testMap );
+        }
+
+        template <class Map>
+        void run_test2()
+        {
+            Map testMap( *this );
+            do_test( testMap );
+
+            if ( testMap.size() != 0 ) {
+                for ( auto it = testMap.begin(); it != testMap.end(); ++it ) {
+                    std::cout << "key=" << it->first << std::endl;
+                }
+            }
+        }
+    };
+
+    class Map_InsDel_func_LF: public Map_InsDel_func
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Set>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_InsDel_func::run_test<Set>();
+        }
+
+        template <class Set>
+        void run_test2()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_InsDel_func::run_test2<Set>();
+        }
+
+        static std::vector<size_t> get_load_factors();
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_bronsonavltree.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..6643b99
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_InsDel_func, run_test, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_cuckoo.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_cuckoo.cpp
new file mode 100644 (file)
index 0000000..e2c6ab4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_cuckoo.h"
+
+namespace map {
+
+//    CDSSTRESS_CuckooMap( Map_InsDel_func, run_test, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_ellentree.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_ellentree.cpp
new file mode 100644 (file)
index 0000000..b2047bc
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap( Map_InsDel_func, run_test, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_feldman_hashset.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_feldman_hashset.cpp
new file mode 100644 (file)
index 0000000..d5ed79c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    CDSSTRESS_FeldmanHashMap_fixed( Map_InsDel_func, run_test, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_michael.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_michael.cpp
new file mode 100644 (file)
index 0000000..a425fa3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    CDSSTRESS_MichaelMap( Map_InsDel_func_LF, run_test2, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_skip.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_skip.cpp
new file mode 100644 (file)
index 0000000..fe49cc9
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap( Map_InsDel_func, run_test, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_split.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_split.cpp
new file mode 100644 (file)
index 0000000..a4d6835
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap( Map_InsDel_func_LF, run_test, size_t, Map_InsDel_func::value_type )
+    CDSSTRESS_SplitListIterableMap( Map_InsDel_func_LF, run_test, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_striped.cpp b/test/stress/sequential/sequential-map/insdel_func/map_insdel_func_striped.cpp
new file mode 100644 (file)
index 0000000..4d5b283
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_func.h"
+#include "map_type_striped.h"
+
+namespace map {
+
+//    CDSSTRESS_StripedMap( Map_InsDel_func_LF, run_test, size_t, Map_InsDel_func::value_type )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/CMakeLists.txt b/test/stress/sequential/sequential-map/insdel_item_int/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2091f33
--- /dev/null
@@ -0,0 +1,24 @@
+set(PACKAGE_NAME stress-sequential-map-insdel-item-int)
+
+set(CDSSTRESS_MAP_INSDEL_ITEM_INT_SOURCES
+    ../../../main.cpp
+    map_insdel_item_int.cpp
+    map_insdel_item_int_bronsonavltree.cpp
+    map_insdel_item_int_cuckoo.cpp
+    map_insdel_item_int_ellentree.cpp
+    map_insdel_item_int_feldman_hashset.cpp
+    map_insdel_item_int_michael.cpp
+    map_insdel_item_int_skip.cpp
+    map_insdel_item_int_split.cpp
+    map_insdel_item_int_striped.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_INSDEL_ITEM_INT_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int.cpp
new file mode 100644 (file)
index 0000000..9dc75aa
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+
+namespace map {
+
+    size_t Map_InsDel_item_int::s_nMapSize = 10000;      // map size
+    size_t Map_InsDel_item_int::s_nInsertThreadCount = 4;  // count of insertion thread
+    size_t Map_InsDel_item_int::s_nDeleteThreadCount = 4;  // count of deletion thread
+    size_t Map_InsDel_item_int::s_nMaxLoadFactor = 8;      // maximum load factor
+
+    size_t Map_InsDel_item_int::s_nAttemptCount = 2000;      // count of SUCCESS insert/delete for each thread
+    size_t Map_InsDel_item_int::s_nGoalItem = 5000;
+
+    size_t Map_InsDel_item_int::s_nCuckooInitialSize = 1024;// initial size for CuckooSet
+    size_t Map_InsDel_item_int::s_nCuckooProbesetSize = 16; // CuckooSet probeset size (only for list-based probeset)
+    size_t Map_InsDel_item_int::s_nCuckooProbesetThreshold = 0; // CUckooSet probeset threshold (0 - use default)
+
+    size_t Map_InsDel_item_int::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_InsDel_item_int::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_InsDel_item_int::s_nLoadFactor = 1;
+
+    void Map_InsDel_item_int::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "map_insdel_item_int" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsertThreadCount = cfg.get_size_t( "InsertThreadCount", s_nInsertThreadCount );
+        if ( s_nInsertThreadCount == 0 )
+            s_nInsertThreadCount = 2;
+
+        s_nDeleteThreadCount = cfg.get_size_t( "DeleteThreadCount", s_nDeleteThreadCount );
+        if ( s_nDeleteThreadCount == 0 )
+            s_nDeleteThreadCount = 2;
+
+        s_nGoalItem = cfg.get_size_t( "GoalItem", s_nGoalItem );
+        if ( s_nGoalItem >= s_nMapSize )
+            s_nGoalItem = s_nMapSize / 2;
+
+        s_nAttemptCount = cfg.get_size_t( "AttemptCount", s_nAttemptCount );
+        if ( s_nAttemptCount == 0 )
+            s_nAttemptCount = 1000;
+
+        s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
+        if ( s_nCuckooInitialSize < 256 )
+            s_nCuckooInitialSize = 256;
+
+        s_nCuckooProbesetSize = cfg.get_size_t( "CuckooProbesetSize", s_nCuckooProbesetSize );
+        if ( s_nCuckooProbesetSize < 8 )
+            s_nCuckooProbesetSize = 8;
+
+        s_nCuckooProbesetThreshold = cfg.get_size_t( "CuckooProbesetThreshold", s_nCuckooProbesetThreshold );
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+    }
+
+    std::vector<size_t> Map_InsDel_item_int_LF::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_insdel_item_int" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDel_item_int_LF, ::testing::ValuesIn( Map_InsDel_item_int_LF::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDel_item_int_LF, ::testing::ValuesIn( Map_InsDel_item_int_LF::get_load_factors()));
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int.h b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int.h
new file mode 100644 (file)
index 0000000..26da803
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+
+namespace map {
+
+    class Map_InsDel_item_int: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nMapSize;           // map size
+        static size_t s_nInsertThreadCount; // count of insertion thread
+        static size_t s_nDeleteThreadCount; // count of deletion thread
+        static size_t s_nMaxLoadFactor;     // maximum load factor
+
+        static size_t s_nAttemptCount;      // count of SUCCESS insert/delete for each thread
+        static size_t s_nGoalItem;
+
+        static size_t s_nCuckooInitialSize;         // initial size for CuckooMap
+        static size_t s_nCuckooProbesetSize;        // CuckooMap probeset size (only for list-based probeset)
+        static size_t s_nCuckooProbesetThreshold;   // CuckooMap probeset threshold (o - use default)
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static void SetUpTestCase();
+        //static void TearDownTestCase();
+
+        typedef size_t  key_type;
+        typedef size_t  value_type;
+
+    protected:
+        enum {
+            insert_thread,
+            delete_thread
+        };
+
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            struct update_func
+            {
+                void operator()( bool bNew, std::pair<key_type const, value_type>& item ) const
+                {
+                    if ( bNew )
+                        item.second = item.first;
+                }
+
+                // for boost::container::flat_map
+                void operator()( bool bNew, std::pair<key_type, value_type>& item ) const
+                {
+                    if ( bNew )
+                        item.second = item.first;
+                }
+
+                // for BronsonAVLTreeMap
+                void operator()( bool bNew, key_type key, value_type& val ) const
+                {
+                    if ( bNew )
+                        val = key;
+                }
+
+                // for FeldmanHashMap
+                void operator()( std::pair<key_type const, value_type>& item, std::pair<key_type const, value_type>* pOld ) const
+                {
+                    if ( !pOld )
+                        item.second = item.first;
+                }
+            };
+
+        public:
+            size_t  m_nInsertSuccess = 0;
+            size_t  m_nInsertFailed = 0;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, insert_thread )
+                , m_Map( map )
+            {}
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                size_t const nGoalItem = s_nGoalItem;
+                size_t const nAttemptCount = s_nAttemptCount;
+
+                for ( size_t nAttempt = 0; nAttempt < nAttemptCount; ) {
+                    if ( nAttempt % 2  == 0 ) {
+                        if ( rMap.insert( nGoalItem, nGoalItem )) {
+                            ++m_nInsertSuccess;
+                            ++nAttempt;
+                        }
+                        else
+                            ++m_nInsertFailed;
+                    }
+                    else {
+                        std::pair<bool, bool> updateResult = rMap.update( nGoalItem, update_func(), true );
+                        if ( updateResult.second ) {
+                            ++m_nInsertSuccess;
+                            ++nAttempt;
+                        }
+                        else
+                            ++m_nInsertFailed;
+                    }
+                }
+            }
+        };
+
+        template <class Map>
+        class Deleter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+        public:
+            Deleter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, delete_thread )
+                , m_Map( map )
+            {}
+
+            Deleter( Deleter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Deleter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                size_t const nGoalItem = s_nGoalItem;
+                size_t const nAttemptCount = s_nAttemptCount;
+                for ( size_t nAttempt = 0; nAttempt < nAttemptCount; ) {
+                    if ( rMap.erase( nGoalItem )) {
+                        ++m_nDeleteSuccess;
+                        ++nAttempt;
+                    }
+                    else
+                        ++m_nDeleteFailed;
+                }
+            }
+        };
+
+    protected:
+
+        template <class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map>       inserter;
+            typedef Deleter<Map>        deleter;
+
+            // Fill the map
+            {
+                std::vector<key_type>   v;
+                v.reserve( s_nMapSize );
+                for ( size_t i = 0; i < s_nMapSize; ++i )
+                    v.push_back( i );
+                shuffle( v.begin(), v.end());
+                for ( auto i: v )
+                    EXPECT_TRUE( testMap.insert( i, i ));
+            }
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new inserter( pool, testMap ), s_nInsertThreadCount );
+            pool.add( new deleter( pool, testMap ), s_nDeleteThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsertThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDeleteThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "goal_item", s_nGoalItem )
+                << std::make_pair( "attempt_count", s_nAttemptCount );
+
+
+            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;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case insert_thread:
+                {
+                    inserter& t = static_cast<inserter&>(thr);
+                    EXPECT_EQ( t.m_nInsertSuccess, s_nAttemptCount ) << "thread=" << t.id();
+                    nInsertSuccess += t.m_nInsertSuccess;
+                    nInsertFailed += t.m_nInsertFailed;
+                }
+                break;
+                case delete_thread:
+                {
+                    deleter& t = static_cast<deleter&>(thr);
+                    EXPECT_EQ( t.m_nDeleteSuccess, s_nAttemptCount ) << "thread=" << t.id();
+                    nDeleteSuccess += t.m_nDeleteSuccess;
+                    nDeleteFailed += t.m_nDeleteFailed;
+                }
+                break;
+                default:
+                    assert( false );
+                }
+            }
+
+            EXPECT_EQ( nInsertSuccess, nDeleteSuccess );
+            EXPECT_TRUE( testMap.contains( s_nGoalItem ));
+            EXPECT_CONTAINER_SIZE( testMap, s_nMapSize );
+
+            propout()
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed );
+
+            // Check if the map contains all items
+            for ( size_t i = 0; i < s_nMapSize; ++i )
+                EXPECT_TRUE( testMap.contains( i )) << "key=" << i;
+
+            check_before_cleanup( testMap );
+
+            testMap.clear();
+            additional_check( testMap );
+            print_stat( propout(), testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            Map testMap( *this );
+            do_test<Map>( testMap );
+        }
+    };
+
+    class Map_InsDel_item_int_LF: public Map_InsDel_item_int
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Set>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_InsDel_item_int::run_test<Set>();
+        }
+
+        static std::vector<size_t> get_load_factors();
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_bronsonavltree.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..f4feb93
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_InsDel_item_int, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_cuckoo.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_cuckoo.cpp
new file mode 100644 (file)
index 0000000..2f7fbf4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_cuckoo.h"
+
+namespace map {
+
+//    CDSSTRESS_CuckooMap( Map_InsDel_item_int, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_ellentree.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_ellentree.cpp
new file mode 100644 (file)
index 0000000..66571e2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap( Map_InsDel_item_int, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_feldman_hashset.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_feldman_hashset.cpp
new file mode 100644 (file)
index 0000000..b07bbb5
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    CDSSTRESS_FeldmanHashMap_fixed( Map_InsDel_item_int, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_michael.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_michael.cpp
new file mode 100644 (file)
index 0000000..87ed423
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    CDSSTRESS_MichaelMap( Map_InsDel_item_int_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_skip.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_skip.cpp
new file mode 100644 (file)
index 0000000..f6a17a6
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap( Map_InsDel_item_int, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_split.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_split.cpp
new file mode 100644 (file)
index 0000000..5acacc9
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap( Map_InsDel_item_int_LF, run_test, size_t, size_t )
+    CDSSTRESS_SplitListIterableMap( Map_InsDel_item_int_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_striped.cpp b/test/stress/sequential/sequential-map/insdel_item_int/map_insdel_item_int_striped.cpp
new file mode 100644 (file)
index 0000000..54c7d3a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_item_int.h"
+#include "map_type_striped.h"
+
+namespace map {
+
+//    CDSSTRESS_StripedMap( Map_InsDel_item_int_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/CMakeLists.txt b/test/stress/sequential/sequential-map/insdel_string/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a2d7e26
--- /dev/null
@@ -0,0 +1,25 @@
+set(PACKAGE_NAME stress-sequential-map-insdel-string)
+
+set(CDSSTRESS_MAP_INSDEL_STRING_SOURCES
+    ../../../main.cpp
+    map_insdel_string.cpp
+    map_insdel_string_bronsonavltree.cpp
+    map_insdel_string_cuckoo.cpp
+    map_insdel_string_ellentree.cpp
+    map_insdel_string_feldman_hashset.cpp
+    map_insdel_string_michael.cpp
+    map_insdel_string_skip.cpp
+    map_insdel_string_split.cpp
+    map_insdel_string_std.cpp
+    map_insdel_string_striped.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_INSDEL_STRING_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string.cpp
new file mode 100644 (file)
index 0000000..e1a422e
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include <cds_test/hash_func.h>
+
+namespace map {
+
+    size_t Map_InsDel_string::s_nMapSize = 1000000;      // map size
+    size_t Map_InsDel_string::s_nInsertThreadCount = 4;  // count of insertion thread
+    size_t Map_InsDel_string::s_nDeleteThreadCount = 4;  // count of deletion thread
+    size_t Map_InsDel_string::s_nThreadPassCount = 4;    // pass count for each thread
+    size_t Map_InsDel_string::s_nMaxLoadFactor = 8;      // maximum load factor
+
+    size_t Map_InsDel_string::s_nCuckooInitialSize = 1024;// initial size for CuckooSet
+    size_t Map_InsDel_string::s_nCuckooProbesetSize = 16; // CuckooSet probeset size (only for list-based probeset)
+    size_t Map_InsDel_string::s_nCuckooProbesetThreshold = 0; // CuckooSet probeset threshold (0 - use default)
+
+    size_t Map_InsDel_string::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_InsDel_string::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_InsDel_string::s_nLoadFactor = 1;
+    std::vector<std::string> Map_InsDel_string::s_arrKeys;
+
+    void Map_InsDel_string::setup_test_case()
+    {
+        cds_test::config const& cfg = get_config( "map_insdel_string" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsertThreadCount = cfg.get_size_t( "InsertThreadCount", s_nInsertThreadCount );
+        if ( s_nInsertThreadCount == 0 )
+            s_nInsertThreadCount = 2;
+
+        s_nDeleteThreadCount = cfg.get_size_t( "DeleteThreadCount", s_nDeleteThreadCount );
+        if ( s_nDeleteThreadCount == 0 )
+            s_nDeleteThreadCount = 2;
+
+        s_nThreadPassCount = cfg.get_size_t( "ThreadPassCount", s_nThreadPassCount );
+        if ( s_nThreadPassCount == 0 )
+            s_nThreadPassCount = 4;
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
+        if ( s_nCuckooInitialSize < 256 )
+            s_nCuckooInitialSize = 256;
+
+        s_nCuckooProbesetSize = cfg.get_size_t( "CuckooProbesetSize", s_nCuckooProbesetSize );
+        if ( s_nCuckooProbesetSize < 8 )
+            s_nCuckooProbesetSize = 8;
+
+        s_nCuckooProbesetThreshold = cfg.get_size_t( "CuckooProbesetThreshold", s_nCuckooProbesetThreshold );
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+    }
+
+    void Map_InsDel_string::SetUpTestCase()
+    {
+        setup_test_case();
+
+        s_arrKeys.clear();
+        s_arrKeys.reserve( s_nMapSize );
+        std::vector<std::string> dict = load_dictionary();
+        for ( size_t i = 0; i < s_nMapSize; ++i )
+            s_arrKeys.push_back( std::move( dict.at(i)));
+    }
+
+    void Map_InsDel_string::TearDownTestCase()
+    {
+        s_arrKeys.clear();
+    }
+
+    std::vector<size_t> Map_InsDel_string::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_insdel_string" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+    template <typename Hash>
+    void Map_InsDel_string::fill_string_array()
+    {
+        typedef Hash hasher;
+        typedef typename hasher::result_type hash_type;
+
+        std::map<hash_type, size_t> mapHash;
+        s_arrKeys.clear();
+        std::vector<std::string> dict = load_dictionary();
+
+        size_t nSize = dict.size();
+        if ( nSize > s_nMapSize )
+            nSize = s_nMapSize;
+        s_arrKeys.reserve( nSize );
+
+        size_t nDiffHash = 0;
+        hasher h;
+        for ( size_t i = 0; i < dict.size(); ++i ) {
+            hash_type hash = h( dict.at( i ));
+            if ( mapHash.insert( std::make_pair( hash, i )).second ) {
+                if ( ++nDiffHash >= nSize )
+                    break;
+                s_arrKeys.push_back( std::move( dict.at( i )));
+            }
+        }
+        s_nMapSize = dict.size();
+    }
+
+    void Map_InsDel_string_stdhash::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<std::hash<std::string>>();
+    }
+
+#if CDS_BUILD_BITS == 64
+    void Map_InsDel_string_city32::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<cds_test::city32>();
+    }
+
+    void Map_InsDel_string_city64::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<cds_test::city64>();
+    }
+
+    void Map_InsDel_string_city128::SetUpTestCase()
+    {
+        setup_test_case();
+        fill_string_array<cds_test::city128>();
+    }
+
+#endif
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDel_string_LF, ::testing::ValuesIn( Map_InsDel_string::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDel_string_LF, ::testing::ValuesIn( Map_InsDel_string::get_load_factors()));
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string.h b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string.h
new file mode 100644 (file)
index 0000000..35cf825
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+
+namespace map {
+
+#define TEST_CASE(TAG, X)  void X();
+
+    class Map_InsDel_string: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nMapSize;           // map size
+        static size_t s_nInsertThreadCount; // count of insertion thread
+        static size_t s_nDeleteThreadCount; // count of deletion thread
+        static size_t s_nThreadPassCount;   // pass count for each thread
+        static size_t s_nMaxLoadFactor;     // maximum load factor
+
+        static size_t s_nCuckooInitialSize;         // initial size for CuckooMap
+        static size_t s_nCuckooProbesetSize;        // CuckooMap probeset size (only for list-based probeset)
+        static size_t s_nCuckooProbesetThreshold;   // CuckooMap probeset threshold (o - use default)
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static void SetUpTestCase();
+        static void TearDownTestCase();
+
+        static void setup_test_case();
+        static std::vector<size_t> get_load_factors();
+
+        typedef std::string key_type;
+        typedef size_t      value_type;
+
+        static std::vector<std::string> s_arrKeys;
+
+    protected:
+        enum {
+            insert_thread,
+            delete_thread
+        };
+
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+        public:
+            size_t  m_nInsertSuccess = 0;
+            size_t  m_nInsertFailed = 0;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, insert_thread )
+                , m_Map( map )
+            {}
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                if ( id() & 1 ) {
+                    for ( size_t nPass = 0; nPass < s_nThreadPassCount; ++nPass ) {
+                        for ( auto it = s_arrKeys.cbegin(), itEnd = s_arrKeys.cend(); it != itEnd; ++it ) {
+                            if ( rMap.insert( *it, 0 ))
+                                ++m_nInsertSuccess;
+                            else
+                                ++m_nInsertFailed;
+                        }
+                    }
+                }
+                else {
+                    for ( size_t nPass = 0; nPass < s_nThreadPassCount; ++nPass ) {
+                        for ( auto it = s_arrKeys.crbegin(), itEnd = s_arrKeys.crend(); it != itEnd; ++it ) {
+                            if ( rMap.insert( *it, 1 ))
+                                ++m_nInsertSuccess;
+                            else
+                                ++m_nInsertFailed;
+                        }
+                    }
+                }
+            }
+        };
+
+        template <class Map>
+        class Deleter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+        public:
+            Deleter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, delete_thread )
+                , m_Map( map )
+            {}
+
+            Deleter( Deleter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Deleter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                if ( id() & 1 ) {
+                    for ( size_t nPass = 0; nPass < s_nThreadPassCount; ++nPass ) {
+                        for ( auto it = s_arrKeys.cbegin(), itEnd = s_arrKeys.cend(); it != itEnd; ++it ) {
+                            if ( rMap.erase( *it ))
+                                ++m_nDeleteSuccess;
+                            else
+                                ++m_nDeleteFailed;
+                        }
+                    }
+                }
+                else {
+                    for ( size_t nPass = 0; nPass < s_nThreadPassCount; ++nPass ) {
+                        for ( auto it = s_arrKeys.crbegin(), itEnd = s_arrKeys.crend(); it != itEnd; ++it ) {
+                            if ( rMap.erase( *it ))
+                                ++m_nDeleteSuccess;
+                            else
+                                ++m_nDeleteFailed;
+                        }
+                    }
+                }
+            }
+        };
+
+    protected:
+        template <typename Hash>
+        static void fill_string_array();
+
+        template <class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map>       inserter;
+            typedef Deleter<Map>        deleter;
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new inserter( pool, testMap ), s_nInsertThreadCount );
+            pool.add( new deleter( pool, testMap ), s_nDeleteThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsertThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDeleteThreadCount )
+                << std::make_pair( "pass_count", s_nThreadPassCount )
+                << std::make_pair( "map_size", s_nMapSize );
+
+            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;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case insert_thread:
+                {
+                    inserter& t = static_cast<inserter&>(thr);
+                    nInsertSuccess += t.m_nInsertSuccess;
+                    nInsertFailed += t.m_nInsertFailed;
+                }
+                break;
+                case delete_thread:
+                {
+                    deleter& t = static_cast<deleter&>(thr);
+                    nDeleteSuccess += t.m_nDeleteSuccess;
+                    nDeleteFailed += t.m_nDeleteFailed;
+                }
+                break;
+                default:
+                    assert( false );
+                }
+            }
+
+            propout()
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "finish_map_size", testMap.size());
+
+            check_before_cleanup( testMap );
+
+            //testMap.clear();
+            for ( auto const& str: s_arrKeys )
+                testMap.erase( str );
+            EXPECT_TRUE( testMap.empty());
+            EXPECT_EQ( testMap.size(), 0u );
+
+            additional_check( testMap );
+            print_stat( propout(), testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            Map testMap( *this );
+            do_test( testMap );
+        }
+    };
+
+    class Map_InsDel_string_stdhash: public Map_InsDel_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_InsDel_string::run_test<Map>();
+        }
+    };
+
+#if CDS_BUILD_BITS == 64
+    class Map_InsDel_string_city32: public Map_InsDel_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_InsDel_string::run_test<Map>();
+        }
+    };
+
+    class Map_InsDel_string_city64: public Map_InsDel_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_InsDel_string::run_test<Map>();
+        }
+    };
+
+    class Map_InsDel_string_city128: public Map_InsDel_string
+    {
+    public:
+        static void SetUpTestCase();
+
+        template <class Map>
+        void run_test()
+        {
+            Map_InsDel_string::run_test<Map>();
+        }
+    };
+
+#endif // #if CDS_BUILD_BITS == 64
+
+    class Map_InsDel_string_LF: public Map_InsDel_string
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Map>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_InsDel_string::run_test<Map>();
+        }
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_bronsonavltree.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..f7391f1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_InsDel_string, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_cuckoo.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_cuckoo.cpp
new file mode 100644 (file)
index 0000000..6b9f41e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_cuckoo.h"
+
+namespace map {
+
+//    CDSSTRESS_CuckooMap( Map_InsDel_string, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_ellentree.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_ellentree.cpp
new file mode 100644 (file)
index 0000000..0946b66
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap( Map_InsDel_string, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_feldman_hashset.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_feldman_hashset.cpp
new file mode 100644 (file)
index 0000000..792c682
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    CDSSTRESS_FeldmanHashMap_stdhash( Map_InsDel_string_stdhash, run_test, std::string, size_t )
+#if CDS_BUILD_BITS == 64
+        CDSSTRESS_FeldmanHashMap_city64( Map_InsDel_string_city64, run_test, std::string, size_t )
+        CDSSTRESS_FeldmanHashMap_city128( Map_InsDel_string_city128, run_test, std::string, size_t )
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_michael.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_michael.cpp
new file mode 100644 (file)
index 0000000..014e69f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    CDSSTRESS_MichaelMap( Map_InsDel_string_LF, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_skip.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_skip.cpp
new file mode 100644 (file)
index 0000000..9f18927
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap( Map_InsDel_string, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_split.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_split.cpp
new file mode 100644 (file)
index 0000000..3c3a3e4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap( Map_InsDel_string_LF, run_test, std::string, size_t )
+    CDSSTRESS_SplitListIterableMap( Map_InsDel_string_LF, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_std.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_std.cpp
new file mode 100644 (file)
index 0000000..c9c94d1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_std.h"
+
+namespace map {
+
+//    CDSSTRESS_StdMap( Map_InsDel_string, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_striped.cpp b/test/stress/sequential/sequential-map/insdel_string/map_insdel_string_striped.cpp
new file mode 100644 (file)
index 0000000..182c020
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdel_string.h"
+#include "map_type_striped.h"
+
+namespace map {
+
+//    CDSSTRESS_StripedMap( Map_InsDel_string_LF, run_test, std::string, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/CMakeLists.txt b/test/stress/sequential/sequential-map/insdelfind/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8176078
--- /dev/null
@@ -0,0 +1,45 @@
+set(MAP_INSDELFIND_HP stress-sequential-map-insdelfind-hp)
+set(MAP_INSDELFIND_RCU stress-sequential-map-insdelfind-rcu)
+
+set(CDSSTRESS_MAP_INSDELFIND_HP_SOURCES
+    ../../../main.cpp
+    map_insdelfind.cpp
+    map_insdelfind_cuckoo.cpp
+    map_insdelfind_ellentree_hp.cpp
+    map_insdelfind_feldman_hashset_hp.cpp
+    map_insdelfind_michael_hp.cpp
+    map_insdelfind_skip_hp.cpp
+    map_insdelfind_split_hp.cpp
+    map_insdelfind_std.cpp
+    map_insdelfind_striped.cpp
+)
+
+set(CDSSTRESS_MAP_INSDELFIND_RCU_SOURCES
+    ../../../main.cpp
+    map_insdelfind.cpp
+    map_insdelfind_bronsonavltree.cpp
+    map_insdelfind_ellentree_rcu.cpp
+    map_insdelfind_feldman_hashset_rcu.cpp
+    map_insdelfind_michael_rcu.cpp
+    map_insdelfind_skip_rcu.cpp
+    map_insdelfind_split_rcu.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${MAP_INSDELFIND_HP} ${CDSSTRESS_MAP_INSDELFIND_HP_SOURCES})
+target_link_libraries(${MAP_INSDELFIND_HP} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+add_test(NAME ${MAP_INSDELFIND_HP} COMMAND ${MAP_INSDELFIND_HP} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
+
+add_executable(${MAP_INSDELFIND_RCU} ${CDSSTRESS_MAP_INSDELFIND_RCU_SOURCES})
+target_link_libraries(${MAP_INSDELFIND_RCU} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+add_test(NAME ${MAP_INSDELFIND_RCU} COMMAND ${MAP_INSDELFIND_RCU} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
+
+add_custom_target( stress-sequential-map-insdelfind
+    DEPENDS
+        stress-sequential-map-insdelfind-hp
+        stress-sequential-map-insdelfind-rcu
+)
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind.cpp
new file mode 100644 (file)
index 0000000..ea0c970
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+
+namespace map {
+
+    size_t Map_InsDelFind::s_nMapSize = 500000;
+    size_t Map_InsDelFind::s_nThreadCount = 8;
+    size_t Map_InsDelFind::s_nMaxLoadFactor = 8;
+    unsigned int Map_InsDelFind::s_nInsertPercentage = 5;
+    unsigned int Map_InsDelFind::s_nDeletePercentage = 5;
+    unsigned int Map_InsDelFind::s_nDuration = 30;
+
+
+    size_t Map_InsDelFind::s_nCuckooInitialSize = 1024;// initial size for CuckooSet
+    size_t Map_InsDelFind::s_nCuckooProbesetSize = 16; // CuckooSet probeset size (only for list-based probeset)
+    size_t Map_InsDelFind::s_nCuckooProbesetThreshold = 0; // CUckooSet probeset threshold (0 - use default)
+
+    size_t Map_InsDelFind::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_InsDelFind::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_InsDelFind::s_nLoadFactor = 1;
+    Map_InsDelFind::actions Map_InsDelFind::s_arrShuffle[Map_InsDelFind::c_nShuffleSize];
+
+    void Map_InsDelFind::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "map_insdelfind" );
+
+        s_nMapSize = cfg.get_size_t( "InitialMapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nThreadCount = cfg.get_size_t( "ThreadCount", s_nThreadCount );
+        if ( s_nThreadCount == 0 )
+            s_nThreadCount = std::min( 16u, std::thread::hardware_concurrency() * 2 );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nInsertPercentage = cfg.get_uint( "InsertPercentage", s_nInsertPercentage );
+        if ( s_nInsertPercentage >= 100 )
+            s_nInsertPercentage = 99;
+
+        s_nDeletePercentage = cfg.get_uint( "DeletePercentage", s_nDeletePercentage );
+        if ( s_nDeletePercentage >= 100 )
+            s_nDeletePercentage = 99;
+
+        if ( s_nInsertPercentage + s_nDeletePercentage > 100 ) {
+            unsigned int total = s_nInsertPercentage + s_nDeletePercentage;
+            s_nInsertPercentage = s_nInsertPercentage * 100 / total;
+            s_nDeletePercentage = s_nDeletePercentage * 100 / total;
+        }
+
+        s_nDuration = cfg.get_uint( "Duration", s_nDuration );
+        if ( s_nDuration < 5 )
+            s_nDuration = 5;
+
+        s_nCuckooInitialSize = cfg.get_size_t( "CuckooInitialSize", s_nCuckooInitialSize );
+        if ( s_nCuckooInitialSize < 256 )
+            s_nCuckooInitialSize = 256;
+
+        s_nCuckooProbesetSize = cfg.get_size_t( "CuckooProbesetSize", s_nCuckooProbesetSize );
+        if ( s_nCuckooProbesetSize < 8 )
+            s_nCuckooProbesetSize = 8;
+
+        s_nCuckooProbesetThreshold = cfg.get_size_t( "CuckooProbesetThreshold", s_nCuckooProbesetThreshold );
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+
+        actions * pFirst = s_arrShuffle;
+        actions * pLast = s_arrShuffle + s_nInsertPercentage;
+        std::fill( pFirst, pLast, do_insert );
+        pFirst = pLast;
+        pLast += s_nDeletePercentage;
+        std::fill( pFirst, pLast, do_delete );
+        pFirst = pLast;
+        pLast = s_arrShuffle + sizeof( s_arrShuffle ) / sizeof( s_arrShuffle[0] );
+        if ( pFirst < pLast )
+            std::fill( pFirst, pLast, do_find );
+        shuffle( s_arrShuffle, pLast );
+    }
+
+    std::vector<size_t> Map_InsDelFind_LF::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_insdelfind" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDelFind_LF, ::testing::ValuesIn( Map_InsDelFind_LF::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_InsDelFind_LF, ::testing::ValuesIn( Map_InsDelFind_LF::get_load_factors()));
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind.h b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind.h
new file mode 100644 (file)
index 0000000..dd909dc
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+
+namespace map {
+
+
+    class Map_InsDelFind: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nMapSize;           // initial map size
+        static size_t s_nThreadCount;       // thread count
+        static size_t s_nMaxLoadFactor;     // maximum load factor
+        static unsigned int s_nInsertPercentage;
+        static unsigned int s_nDeletePercentage;
+        static unsigned int s_nDuration;    // test duration, seconds
+
+        static size_t s_nCuckooInitialSize;         // initial size for CuckooMap
+        static size_t s_nCuckooProbesetSize;        // CuckooMap probeset size (only for list-based probeset)
+        static size_t s_nCuckooProbesetThreshold;   // CuckooMap probeset threshold (o - use default)
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static void SetUpTestCase();
+        //static void TearDownTestCase();
+
+    public:
+        enum actions
+        {
+            do_find,
+            do_insert,
+            do_delete
+        };
+        static const unsigned int c_nShuffleSize = 100;
+        static actions s_arrShuffle[c_nShuffleSize];
+
+    protected:
+        typedef size_t  key_type;
+        typedef size_t  value_type;
+
+        template <class Map>
+        class Worker: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+        public:
+            size_t  m_nInsertSuccess = 0;
+            size_t  m_nInsertFailed = 0;
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+            size_t  m_nFindSuccess = 0;
+            size_t  m_nFindFailed = 0;
+
+        public:
+            Worker( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool )
+                , m_Map( map )
+            {}
+
+            Worker( Worker& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Worker( *this );
+            }
+
+            typedef std::pair< key_type const, value_type > map_value_type;
+
+            struct update_functor {
+                template <typename Q>
+                void operator()( bool /*bNew*/, map_value_type& /*cur*/, Q const& /*val*/ ) const
+                {}
+
+                // FeldmanHashMap
+                void operator()( map_value_type& /*cur*/, map_value_type* /*old*/) const
+                {}
+
+                // MichaelMap
+                void operator()( bool /*bNew*/, map_value_type& /*cur*/ ) const
+                {}
+
+                // BronsonAVLTreeMap
+                void operator()( bool /*bNew*/, key_type /*key*/, value_type& /*val*/ ) const
+                {}
+            };
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                unsigned int i = 0;
+                size_t const nNormalize = size_t(-1) / ( s_nMapSize * 2 );
+
+                size_t nRand = 0;
+                while ( !time_elapsed()) {
+                    nRand = cds::bitop::RandXorShift( nRand );
+                    size_t n = nRand / nNormalize;
+                    switch ( s_arrShuffle[i] ) {
+                    case do_find:
+                        if ( rMap.contains( n ))
+                            ++m_nFindSuccess;
+                        else
+                            ++m_nFindFailed;
+                        break;
+                    case do_insert:
+                        if ( n % 2 ) {
+                            if ( rMap.insert( n, n ))
+                                ++m_nInsertSuccess;
+                            else
+                                ++m_nInsertFailed;
+                        }
+                        else {
+                            if ( rMap.update( n, update_functor(), true ).first )
+                                ++m_nInsertSuccess;
+                            else
+                                ++m_nInsertFailed;
+                        }
+                        break;
+                    case do_delete:
+                        if ( rMap.erase( n ))
+                            ++m_nDeleteSuccess;
+                        else
+                            ++m_nDeleteFailed;
+                        break;
+                    }
+
+                    if ( ++i >= c_nShuffleSize )
+                        i = 0;
+                }
+            }
+        };
+
+    protected:
+        template <class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Worker<Map> worker;
+
+            // fill map - only odd number
+            {
+                std::vector<size_t> arr;
+                arr.reserve( s_nMapSize );
+                for ( size_t i = 0; i < s_nMapSize; ++i )
+                    arr.push_back( i * 2 + 1);
+                shuffle( arr.begin(), arr.end());
+                for ( size_t i = 0; i < s_nMapSize; ++i )
+                    testMap.insert( arr[i], arr[i] );
+            }
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new worker( pool, testMap ), s_nThreadCount );
+
+            propout() << std::make_pair( "thread_count", s_nThreadCount )
+                << std::make_pair( "insert_percentage", s_nInsertPercentage )
+                << std::make_pair( "delete_percentage", s_nDeletePercentage )
+                << std::make_pair( "map_size", s_nMapSize );
+
+            std::chrono::milliseconds duration = pool.run( std::chrono::seconds( s_nDuration ));
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+            size_t nFindSuccess = 0;
+            size_t nFindFailed = 0;
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                worker& thr = static_cast<worker&>( pool.get( i ));
+
+                nInsertSuccess += thr.m_nInsertSuccess;
+                nInsertFailed += thr.m_nInsertFailed;
+                nDeleteSuccess += thr.m_nDeleteSuccess;
+                nDeleteFailed += thr.m_nDeleteFailed;
+                nFindSuccess += thr.m_nFindSuccess;
+                nFindFailed += thr.m_nFindFailed;
+            }
+
+            propout()
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "find_success", nFindSuccess )
+                << std::make_pair( "find_failed", nFindFailed )
+                << std::make_pair( "finish_map_size", testMap.size());
+
+            {
+                ASSERT_TRUE( std::chrono::duration_cast<std::chrono::seconds>(duration).count() > 0 );
+                size_t nTotalOps = nInsertSuccess + nInsertFailed + nDeleteSuccess + nDeleteFailed + nFindSuccess + nFindFailed;
+                propout() << std::make_pair( "avg_speed", nTotalOps / std::chrono::duration_cast<std::chrono::seconds>( duration ).count());
+            }
+
+            check_before_cleanup( testMap );
+
+            testMap.clear();
+            EXPECT_TRUE( testMap.empty());
+
+            additional_check( testMap );
+            print_stat( propout(), testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            Map testMap( *this );
+            do_test( testMap );
+        }
+    };
+
+    class Map_InsDelFind_LF: public Map_InsDelFind
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Map>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_InsDelFind::run_test<Map>();
+        }
+
+        static std::vector<size_t> get_load_factors();
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_bronsonavltree.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..410e944
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_cuckoo.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_cuckoo.cpp
new file mode 100644 (file)
index 0000000..ca7e84f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_cuckoo.h"
+
+namespace map {
+
+//    CDSSTRESS_CuckooMap( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_ellentree_hp.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_ellentree_hp.cpp
new file mode 100644 (file)
index 0000000..d4c07ce
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap_HP( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_ellentree_rcu.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_ellentree_rcu.cpp
new file mode 100644 (file)
index 0000000..844c28d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap_RCU( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_feldman_hashset_hp.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_feldman_hashset_hp.cpp
new file mode 100644 (file)
index 0000000..b097858
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    CDSSTRESS_FeldmanHashMap_fixed_HP( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_feldman_hashset_rcu.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_feldman_hashset_rcu.cpp
new file mode 100644 (file)
index 0000000..67c8821
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    CDSSTRESS_FeldmanHashMap_fixed_RCU( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_michael_hp.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_michael_hp.cpp
new file mode 100644 (file)
index 0000000..afa4106
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    CDSSTRESS_MichaelMap_HP( Map_InsDelFind_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_michael_rcu.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_michael_rcu.cpp
new file mode 100644 (file)
index 0000000..3d44177
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    CDSSTRESS_MichaelMap_RCU( Map_InsDelFind_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_skip_hp.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_skip_hp.cpp
new file mode 100644 (file)
index 0000000..cbc76e3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap_HP( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_skip_rcu.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_skip_rcu.cpp
new file mode 100644 (file)
index 0000000..f70c5ee
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap_RCU( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_split_hp.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_split_hp.cpp
new file mode 100644 (file)
index 0000000..ece864c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap_HP( Map_InsDelFind_LF, run_test, size_t, size_t )
+    CDSSTRESS_SplitListIterableMap( Map_InsDelFind_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_split_rcu.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_split_rcu.cpp
new file mode 100644 (file)
index 0000000..a090fad
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_split_list.h"
+
+namespace map {
+
+    CDSSTRESS_SplitListMap_RCU( Map_InsDelFind_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_std.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_std.cpp
new file mode 100644 (file)
index 0000000..5d09f15
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_std.h"
+
+namespace map {
+
+//    CDSSTRESS_StdMap( Map_InsDelFind, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_striped.cpp b/test/stress/sequential/sequential-map/insdelfind/map_insdelfind_striped.cpp
new file mode 100644 (file)
index 0000000..96458ac
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_insdelfind.h"
+#include "map_type_striped.h"
+
+namespace map {
+
+//    CDSSTRESS_StripedMap( Map_InsDelFind_LF, run_test, size_t, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/iter_erase/CMakeLists.txt b/test/stress/sequential/sequential-map/iter_erase/CMakeLists.txt
new file mode 100644 (file)
index 0000000..42358af
--- /dev/null
@@ -0,0 +1,19 @@
+set(PACKAGE_NAME stress-sequential-map-iter-erase)
+
+set(CDSSTRESS_MAP_ITER_ERASE_SOURCES
+    ../../../main.cpp
+    map_iter_erase.cpp
+    map_iter_erase_feldman_hashmap.cpp
+    map_iter_erase_michael.cpp
+    map_iter_erase_split.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_ITER_ERASE_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/iter_erase/map_iter_erase.cpp b/test/stress/sequential/sequential-map/iter_erase/map_iter_erase.cpp
new file mode 100644 (file)
index 0000000..ac04e53
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+
+namespace map {
+
+    size_t  Map_Iter_Del3::s_nMapSize = 5000;
+    size_t  Map_Iter_Del3::s_nInsThreadCount = 4;
+    size_t  Map_Iter_Del3::s_nDelThreadCount = 4;
+    size_t  Map_Iter_Del3::s_nExtractThreadCount = 4;
+    size_t  Map_Iter_Del3::s_nFindThreadCount = 2;
+    size_t  Map_Iter_Del3::s_nMaxLoadFactor = 4;
+    size_t  Map_Iter_Del3::s_nInsertPassCount = 1000;
+
+    size_t Map_Iter_Del3::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_Iter_Del3::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_Iter_Del3::s_nLoadFactor = 1;
+    std::vector<size_t> Map_Iter_Del3::m_arrElements;
+
+    void Map_Iter_Del3::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "map_iter_erase" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsThreadCount = cfg.get_size_t( "InsThreadCount", s_nInsThreadCount );
+        if ( s_nInsThreadCount == 0 )
+            s_nInsThreadCount = 1;
+
+        s_nDelThreadCount = cfg.get_size_t( "DelThreadCount", s_nDelThreadCount );
+        s_nExtractThreadCount = cfg.get_size_t( "ExtractThreadCount", s_nExtractThreadCount );
+        s_nFindThreadCount = cfg.get_size_t( "FindThreadCount", s_nFindThreadCount );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nInsertPassCount = cfg.get_size_t( "PassCount", s_nInsertPassCount );
+        if ( s_nInsertPassCount == 0 )
+            s_nInsertPassCount = 1000;
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+
+        m_arrElements.resize( s_nMapSize );
+        for ( size_t i = 0; i < s_nMapSize; ++i )
+            m_arrElements[i] = i;;
+        shuffle( m_arrElements.begin(), m_arrElements.end());
+    }
+
+    void Map_Iter_Del3::TearDownTestCase()
+    {
+        m_arrElements.clear();
+    }
+
+    std::vector<size_t> Map_Iter_Del3_LF::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_iter_erase" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG
+    static std::string get_test_parameter_name( testing::TestParamInfo<size_t> const& p )
+    {
+        return std::to_string( p.param );
+    }
+    INSTANTIATE_TEST_CASE_P( a, Map_Iter_Del3_LF, ::testing::ValuesIn( Map_Iter_Del3_LF::get_load_factors()), get_test_parameter_name );
+#else
+    INSTANTIATE_TEST_CASE_P( a, Map_Iter_Del3_LF, ::testing::ValuesIn( Map_Iter_Del3_LF::get_load_factors()));
+#endif
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/iter_erase/map_iter_erase.h b/test/stress/sequential/sequential-map/iter_erase/map_iter_erase.h
new file mode 100644 (file)
index 0000000..cceb358
--- /dev/null
@@ -0,0 +1,871 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+#include <cds/os/topology.h>
+
+namespace map {
+
+    namespace {
+        struct key_thread
+        {
+            uint32_t  nKey;
+            uint16_t  nThread;
+
+            key_thread( size_t key, size_t threadNo )
+                : nKey( static_cast<uint32_t>(key))
+                , nThread( static_cast<uint16_t>(threadNo))
+            {}
+
+            key_thread()
+                : nKey()
+                , nThread()
+            {}
+        };
+
+        static_assert(sizeof( key_thread ) % 8 == 0, "Key size mismatch!!!");
+    } // namespace
+
+    template <>
+    struct cmp<key_thread> {
+        int operator ()(key_thread const& k1, key_thread const& k2) const
+        {
+            if ( k1.nKey < k2.nKey )
+                return -1;
+            if ( k1.nKey > k2.nKey )
+                return 1;
+            if ( k1.nThread < k2.nThread )
+                return -1;
+            if ( k1.nThread > k2.nThread )
+                return 1;
+            return 0;
+        }
+        int operator ()(key_thread const& k1, size_t k2) const
+        {
+            if ( k1.nKey < k2 )
+                return -1;
+            if ( k1.nKey > k2 )
+                return 1;
+            return 0;
+        }
+        int operator ()(size_t k1, key_thread const& k2) const
+        {
+            if ( k1 < k2.nKey )
+                return -1;
+            if ( k1 > k2.nKey )
+                return 1;
+            return 0;
+        }
+    };
+
+    template <>
+    struct less<key_thread>
+    {
+        bool operator()( key_thread const& k1, key_thread const& k2 ) const
+        {
+            if ( k1.nKey <= k2.nKey )
+                return k1.nKey < k2.nKey || k1.nThread < k2.nThread;
+            return false;
+        }
+    };
+
+    template <>
+    struct hash<key_thread>
+    {
+        typedef size_t             result_type;
+        typedef key_thread    argument_type;
+
+        size_t operator()( key_thread const& k ) const
+        {
+            return std::hash<size_t>()(k.nKey);
+        }
+        size_t operator()( size_t k ) const
+        {
+            return std::hash<size_t>()(k);
+        }
+    };
+
+    class Map_Iter_Del3: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nInsThreadCount;      // insert thread count
+        static size_t s_nDelThreadCount;      // delete thread count
+        static size_t s_nExtractThreadCount;  // extract thread count
+        static size_t s_nMapSize;             // max map size
+        static size_t s_nMaxLoadFactor;       // maximum load factor
+        static size_t s_nInsertPassCount;
+        static size_t s_nFindThreadCount;     // find thread count
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static std::vector<size_t> m_arrElements;
+
+        static void SetUpTestCase();
+        static void TearDownTestCase();
+
+        template <typename Pred>
+        static void prepare_array( std::vector<size_t>& arr, Pred pred )
+        {
+            arr.reserve( m_arrElements.size());
+            for ( auto el : m_arrElements ) {
+                if ( pred( el ))
+                    arr.push_back( el );
+            }
+            arr.resize( arr.size());
+            shuffle( arr.begin(), arr.end());
+        }
+
+    protected:
+        typedef key_thread  key_type;
+        typedef size_t      value_type;
+        typedef std::pair<key_type const, value_type> pair_type;
+
+        atomics::atomic<size_t> m_nInsThreadCount;
+
+        enum {
+            inserter_thread,
+            deleter_thread,
+            extractor_thread,
+            find_thread,
+        };
+
+        // Inserts keys from [0..N)
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            struct update_func
+            {
+                template <typename Q>
+                void operator()( bool /*bNew*/, Q const& ) const
+                {}
+
+                template <typename Q, typename V>
+                void operator()( bool /*bNew*/, Q const&, V& ) const
+                {}
+
+                // FeldmanHashMap
+                template <typename Q>
+                void operator()( Q&, Q*) const
+                {}
+            };
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t ) -> bool { return true; } );
+                for ( size_t i = 0; i < m_arr.size(); ++i ) {
+                    if ( m_Map.insert( key_type( m_arr[i], id())))
+                        ++m_nInsertInitSuccess;
+                    else
+                        ++m_nInsertInitFailed;
+                }
+            }
+
+        public:
+            size_t m_nInsertSuccess = 0;
+            size_t m_nInsertFailed = 0;
+            size_t m_nInsertInitSuccess = 0;
+            size_t m_nInsertInitFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, inserter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+
+                update_func f;
+
+                for ( size_t nPass = 0; nPass < s_nInsertPassCount; ++nPass ) {
+                    if ( nPass & 1 ) {
+                        // insert pass
+                        for ( auto el : m_arr ) {
+                            if ( el & 3 ) {
+                                if ( rMap.insert( key_type( el, id())))
+                                    ++m_nInsertSuccess;
+                                else
+                                    ++m_nInsertFailed;
+                            }
+                        }
+                    }
+                    else {
+                        // update pass
+                        for ( auto el : m_arr ) {
+                            if ( el & 3 ) {
+                                bool success;
+                                bool inserted;
+                                std::tie( success, inserted ) = rMap.update( key_type( el, id()), f );
+                                if ( success && inserted )
+                                    ++m_nInsertSuccess;
+                                else
+                                    ++m_nInsertFailed;
+                            }
+                        }
+                    }
+                }
+
+                fixture.m_nInsThreadCount.fetch_sub( 1, atomics::memory_order_release );
+                m_arr.resize( 0 );
+            }
+        };
+
+        struct key_equal {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey == k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 == k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey == k2;
+            }
+        };
+
+        struct key_less {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey < k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 < k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey < k2;
+            }
+
+            typedef key_equal equal_to;
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class Map, typename Iterator>
+        class Deleter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Deleter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, deleter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Deleter( Deleter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Deleter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+
+                do {
+                    auto itEnd = rMap.template get_end<Iterator>();
+                    for ( auto it = rMap.template get_begin<Iterator>(); it != itEnd; ++it ) {
+                        if ( it->first.nKey & 3 ) {
+                            if ( rMap.erase_at( it ))
+                                ++m_nDeleteSuccess;
+                            else
+                                ++m_nDeleteFailed;
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+            }
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class GC, class Map >
+        class Extractor: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                typename Map::guarded_ptr gp;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    if ( id() & 1 ) {
+                        for ( auto el : m_arr ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                gp = rMap.extract( key_type( el, k ));
+                                if ( gp )
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                                gp.release();
+                            }
+                        }
+                    }
+                    else {
+                        for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                            for ( auto el: m_arr ) {
+                                gp = rMap.extract( key_type( el, k ));
+                                if ( gp )
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                                gp.release();
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                m_arr.resize( 0 );
+            }
+        };
+
+        template <class RCU, class Map >
+        class Extractor< cds::urcu::gc<RCU>, Map > : public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) -> bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+
+                typename Map::exempt_ptr xp;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    if ( id() & 1 ) {
+                        for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                            for ( auto el: m_arr ) {
+                                if ( Map::c_bExtractLockExternal ) {
+                                    typename Map::rcu_lock l;
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                else {
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                xp.release();
+                            }
+                        }
+                    }
+                    else {
+                        for ( auto el : m_arr ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( Map::c_bExtractLockExternal ) {
+                                    typename Map::rcu_lock l;
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                else {
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                xp.release();
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                m_arr.resize( 0 );
+            }
+        };
+
+        // Finds keys
+        template <class Map>
+        class Observer: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&                m_Map;
+
+        public:
+            size_t m_nFindEvenSuccess = 0;
+            size_t m_nFindEvenFailed  = 0;
+            size_t m_nFindOddSuccess  = 0;
+            size_t m_nFindOddFailed   = 0;
+
+        public:
+            Observer( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, find_thread )
+                , m_Map( map )
+            {}
+
+            Observer( Observer& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Observer( *this );
+            }
+
+            virtual void test()
+            {
+                Map& map = m_Map;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+                std::vector<size_t> const& arr = m_arrElements;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    for ( size_t key : arr ) {
+                        if ( key & 3 ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( map.contains( key_thread( key, k )))
+                                    ++m_nFindOddSuccess;
+                                else
+                                    ++m_nFindOddFailed;
+                            }
+                        }
+                        else {
+                            // even keys MUST be in the map
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( map.contains( key_thread( key, k )))
+                                    ++m_nFindEvenSuccess;
+                                else
+                                    ++m_nFindEvenFailed;
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+            }
+        };
+
+    protected:
+        template <typename Iterator, class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map, Iterator>  delete_thread;
+            typedef Observer<Map> observer_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            pool.add( new delete_thread( pool, testMap ), s_nDelThreadCount ? s_nDelThreadCount : cds::OS::topology::processor_count());
+            if ( s_nFindThreadCount )
+                pool.add( new observer_thread( pool, testMap ), s_nFindThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
+                << std::make_pair( "find_thread_count", s_nFindThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nInsertPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertInitFailed = 0;
+            size_t nInsertInitSuccess = 0;
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+
+            size_t nFindEvenSuccess = 0;
+            size_t nFindEvenFailed = 0;
+            size_t nFindOddSuccess = 0;
+            size_t nFindOddFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                    {
+                        insert_thread& inserter = static_cast<insert_thread&>( thr );
+                        nInsertSuccess += inserter.m_nInsertSuccess;
+                        nInsertFailed += inserter.m_nInsertFailed;
+                        nInsertInitSuccess += inserter.m_nInsertInitSuccess;
+                        nInsertInitFailed += inserter.m_nInsertInitFailed;
+                    }
+                    break;
+                case deleter_thread:
+                    {
+                        delete_thread& deleter = static_cast<delete_thread&>( thr );
+                        nDeleteSuccess += deleter.m_nDeleteSuccess;
+                        nDeleteFailed += deleter.m_nDeleteFailed;
+                    }
+                    break;
+                case find_thread:
+                    {
+                        observer_thread& observer = static_cast<observer_thread&>( thr );
+                        nFindEvenSuccess = observer.m_nFindEvenSuccess;
+                        nFindEvenFailed = observer.m_nFindEvenFailed;
+                        nFindOddSuccess = observer.m_nFindOddSuccess;
+                        nFindOddFailed = observer.m_nFindOddFailed;
+                    }
+                    break;
+                }
+            }
+
+            size_t const nInitialOddKeys = ( s_nMapSize * s_nInsThreadCount ) * 3 / 4;
+
+            EXPECT_EQ( nInsertInitFailed, 0u );
+            EXPECT_EQ( nInsertInitSuccess, s_nMapSize * s_nInsThreadCount );
+            EXPECT_EQ( nFindEvenFailed, 0u );
+            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess );
+            EXPECT_LE( nInsertSuccess, nDeleteSuccess );
+
+            propout()
+                << std::make_pair( "insert_init_success", nInsertInitSuccess )
+                << std::make_pair( "insert_init_failed", nInsertInitFailed )
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "find_even_success", nFindEvenSuccess )
+                << std::make_pair( "find_even_failed", nFindEvenFailed )
+                << std::make_pair( "find_odd_success", nFindOddSuccess )
+                << std::make_pair( "find_odd_failed", nFindOddFailed );
+
+            analyze( testMap );
+        }
+
+        template <typename Iterator, class Map>
+        void do_test_extract( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map, Iterator> delete_thread;
+            typedef Extractor< typename Map::gc, Map > extract_thread;
+            typedef Observer<Map> observer_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            if ( s_nDelThreadCount )
+                pool.add( new delete_thread( pool, testMap ), s_nDelThreadCount );
+            if ( s_nExtractThreadCount )
+                pool.add( new extract_thread( pool, testMap ), s_nExtractThreadCount );
+            if ( s_nFindThreadCount )
+                pool.add( new observer_thread( pool, testMap ), s_nFindThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
+                << std::make_pair( "extract_thread_count", s_nExtractThreadCount )
+                << std::make_pair( "find_thread_count", s_nFindThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nInsertPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertInitFailed = 0;
+            size_t nInsertInitSuccess = 0;
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+            size_t nExtractSuccess = 0;
+            size_t nExtractFailed = 0;
+
+            size_t nFindEvenSuccess = 0;
+            size_t nFindEvenFailed = 0;
+            size_t nFindOddSuccess = 0;
+            size_t nFindOddFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                {
+                    insert_thread& inserter = static_cast<insert_thread&>(thr);
+                    nInsertSuccess += inserter.m_nInsertSuccess;
+                    nInsertFailed += inserter.m_nInsertFailed;
+                    nInsertInitSuccess += inserter.m_nInsertInitSuccess;
+                    nInsertInitFailed += inserter.m_nInsertInitFailed;
+                }
+                break;
+                case deleter_thread:
+                {
+                    delete_thread& deleter = static_cast<delete_thread&>(thr);
+                    nDeleteSuccess += deleter.m_nDeleteSuccess;
+                    nDeleteFailed += deleter.m_nDeleteFailed;
+                }
+                break;
+                case extractor_thread:
+                {
+                    extract_thread& extractor = static_cast<extract_thread&>(thr);
+                    nExtractSuccess += extractor.m_nDeleteSuccess;
+                    nExtractFailed += extractor.m_nDeleteFailed;
+                }
+                break;
+                case find_thread:
+                {
+                    observer_thread& observer = static_cast<observer_thread&>( thr );
+                    nFindEvenSuccess = observer.m_nFindEvenSuccess;
+                    nFindEvenFailed = observer.m_nFindEvenFailed;
+                    nFindOddSuccess = observer.m_nFindOddSuccess;
+                    nFindOddFailed = observer.m_nFindOddFailed;
+                }
+                break;
+                default:
+                    assert( false );
+                }
+            }
+
+            size_t const nInitialOddKeys = ( s_nMapSize * s_nInsThreadCount ) * 3 / 4;
+
+            EXPECT_EQ( nInsertInitFailed, 0u );
+            EXPECT_EQ( nInsertInitSuccess, s_nMapSize * s_nInsThreadCount );
+            EXPECT_EQ( nFindEvenFailed, 0u );
+            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess + nExtractSuccess );
+            EXPECT_LE( nInsertSuccess, nDeleteSuccess + nExtractSuccess );
+
+            propout()
+                << std::make_pair( "insert_init_success", nInsertInitSuccess )
+                << std::make_pair( "insert_init_failed", nInsertInitFailed )
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "extract_success", nExtractSuccess )
+                << std::make_pair( "extract_failed", nExtractFailed )
+                << std::make_pair( "find_even_success", nFindEvenSuccess )
+                << std::make_pair( "find_even_failed", nFindEvenFailed )
+                << std::make_pair( "find_odd_success", nFindOddSuccess )
+                << std::make_pair( "find_odd_failed", nFindOddFailed );
+
+            analyze( testMap );
+        }
+
+        template <class Map>
+        void analyze( Map& testMap )
+        {
+            // All even keys must be in the map
+            {
+                for ( size_t n = 0; n < s_nMapSize; n +=4 ) {
+                    for ( size_t i = 0; i < s_nInsThreadCount; ++i ) {
+                        EXPECT_TRUE( testMap.contains( key_type( n, i ))) << "key=" << n << "/" << i;
+                    }
+                }
+            }
+
+            print_stat( propout(), testMap );
+
+            check_before_cleanup( testMap );
+            testMap.clear();
+            EXPECT_TRUE( testMap.empty()) << "map.size=" << testMap.size();
+
+            additional_check( testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map, typename Iterator=typename Map::iterator>
+        void run_test_extract()
+        {
+            static_assert( Map::c_bExtractSupported, "Map class must support extract() method" );
+
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test_extract<Iterator>( testMap );
+        }
+
+        template <class Map, typename Iterator=typename Map::iterator>
+        void run_test()
+        {
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test<Iterator>( testMap );
+        }
+
+        template <class Map>
+        void run_feldman();
+    };
+
+    class Map_Iter_Del3_reverse: public Map_Iter_Del3
+    {
+    public:
+        template <class Map>
+        void run_feldman();
+    };
+
+
+    class Map_Iter_Del3_LF: public Map_Iter_Del3
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Map>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_Iter_Del3::run_test<Map>();
+        }
+
+        template <class Map>
+        void run_test_extract()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_Iter_Del3::run_test_extract<Map>();
+        }
+
+        static std::vector<size_t> get_load_factors();
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/iter_erase/map_iter_erase_feldman_hashmap.cpp b/test/stress/sequential/sequential-map/iter_erase/map_iter_erase_feldman_hashmap.cpp
new file mode 100644 (file)
index 0000000..23522ca
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    template <class Map>
+    void Map_Iter_Del3::run_feldman()
+    {
+        typedef typename Map::traits original_traits;
+        struct traits: public original_traits {
+            enum { hash_size = sizeof( uint32_t ) + sizeof( uint16_t ) };
+        };
+        typedef typename Map::template rebind_traits< traits >::result map_type;
+
+        run_test_extract<map_type>();
+    }
+
+    template <class Map>
+    void Map_Iter_Del3_reverse::run_feldman()
+    {
+        typedef typename Map::traits original_traits;
+        struct traits: public original_traits {
+            enum { hash_size = sizeof( uint32_t ) + sizeof( uint16_t ) };
+        };
+        typedef typename Map::template rebind_traits< traits >::result map_type;
+
+        run_test_extract<map_type, typename map_type::reverse_iterator>();
+    }
+
+    CDSSTRESS_FeldmanHashMap_fixed_HP( Map_Iter_Del3, run_feldman, key_thread, size_t )
+    CDSSTRESS_FeldmanHashMap_fixed_HP( Map_Iter_Del3_reverse, run_feldman, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/iter_erase/map_iter_erase_michael.cpp b/test/stress/sequential/sequential-map/iter_erase/map_iter_erase_michael.cpp
new file mode 100644 (file)
index 0000000..66b2147
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+#include "map_type_michael.h"
+
+namespace map {
+
+    // Test is too long
+    // CDSSTRESS_MichaelMap_Iterable( Map_Iter_Del3_LF, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/iter_erase/map_iter_erase_split.cpp b/test/stress/sequential/sequential-map/iter_erase/map_iter_erase_split.cpp
new file mode 100644 (file)
index 0000000..840be70
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+#include "map_type_split_list.h"
+
+namespace map {
+    // Too long
+    //CDSSTRESS_SplitListIterableMap( Map_Iter_Del3_LF, run_test_extract, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/map_type.h b/test/stress/sequential/sequential-map/map_type.h
new file mode 100644 (file)
index 0000000..dae3f81
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_H
+#define CDSUNIT_MAP_TYPE_H
+
+#include <cds/urcu/general_instant.h>
+#include <cds/urcu/general_buffered.h>
+#include <cds/urcu/general_threaded.h>
+#include <cds/urcu/signal_buffered.h>
+
+#include <cds/sync/spinlock.h>
+#include <cds/opt/hash.h>
+#include <boost/functional/hash/hash.hpp>
+
+#include <cds_test/stress_test.h>
+#include <cds_test/check_size.h>
+
+namespace map {
+    namespace cc = cds::container;
+    namespace co = cds::opt;
+
+    typedef cds::urcu::gc< cds::urcu::general_instant_stripped >   rcu_gpi;
+    typedef cds::urcu::gc< cds::urcu::general_buffered_stripped >  rcu_gpb;
+    typedef cds::urcu::gc< cds::urcu::general_threaded_stripped >  rcu_gpt;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+    typedef cds::urcu::gc< cds::urcu::signal_buffered_stripped >  rcu_shb;
+#endif
+
+    template <typename Key>
+    struct less;
+
+    template <typename Key>
+    struct cmp {
+        int operator ()(Key const& k1, Key const& k2) const
+        {
+            if ( less<Key>( k1, k2 ))
+                return -1;
+            return less<Key>( k2, k1 ) ? 1 : 0;
+        }
+    };
+
+    template <typename Key>
+    struct hash;
+
+#define CDSUNIT_INT_COMPARE(t)  template <> struct cmp<t> { int operator()( t k1, t k2 ) const { return (int)(k1 - k2); } }
+    CDSUNIT_INT_COMPARE(char);
+    CDSUNIT_INT_COMPARE(unsigned char);
+    CDSUNIT_INT_COMPARE(int);
+    CDSUNIT_INT_COMPARE(unsigned int);
+    CDSUNIT_INT_COMPARE(long);
+    CDSUNIT_INT_COMPARE(unsigned long);
+    CDSUNIT_INT_COMPARE(long long);
+    CDSUNIT_INT_COMPARE(unsigned long long);
+#undef CDSUNIT_INT_COMPARE
+
+#define CDSUNIT_INT_LESS(t)  template <> struct less<t> { bool operator()( t k1, t k2 ) const { return k1 < k2; } }
+    CDSUNIT_INT_LESS( char );
+    CDSUNIT_INT_LESS( unsigned char );
+    CDSUNIT_INT_LESS( int );
+    CDSUNIT_INT_LESS( unsigned int );
+    CDSUNIT_INT_LESS( long );
+    CDSUNIT_INT_LESS( unsigned long );
+    CDSUNIT_INT_LESS( long long );
+    CDSUNIT_INT_LESS( unsigned long long );
+#undef CDSUNIT_INT_LESS
+
+    template <>
+    struct cmp<std::string>
+    {
+        int operator()(std::string const& s1, std::string const& s2)
+        {
+            return s1.compare( s2 );
+        }
+        int operator()(std::string const& s1, char const * s2)
+        {
+            return s1.compare( s2 );
+        }
+        int operator()(char const * s1, std::string const& s2)
+        {
+            return -s2.compare( s1 );
+        }
+    };
+
+    template <>
+    struct less<std::string>
+    {
+        bool operator ()( std::string const& k1, std::string const& k2 ) const
+        {
+            return cmp<std::string>()(k1, k2) < 0;
+        }
+        bool operator ()( std::string const& k1, char const* k2 ) const
+        {
+            return cmp<std::string>()(k1, k2) < 0;
+        }
+        bool operator ()( char const* k1, std::string const& k2 ) const
+        {
+            return cmp<std::string>()(k1, k2) < 0;
+        }
+    };
+
+    template <typename T>
+    struct hash
+    {
+        typedef size_t result_type;
+        typedef T      argument_type;
+
+        size_t operator()( T const& k ) const
+        {
+            return std::hash<size_t>()(k.nKey);
+        }
+
+        size_t operator()( size_t k ) const
+        {
+            return std::hash<size_t>()(k);
+        }
+    };
+
+    template <>
+    struct hash<size_t>
+    {
+        typedef size_t result_type;
+        typedef size_t argument_type;
+
+        size_t operator()( size_t k ) const
+        {
+            return std::hash<size_t>()(k);
+        }
+    };
+
+    template <>
+    struct hash<std::string>
+    {
+        typedef size_t result_type;
+        typedef std::string argument_type;
+
+        size_t operator()( std::string const& k ) const
+        {
+            return std::hash<std::string>()(k);
+        }
+    };
+
+    // forward
+    template <typename ImplSelector, typename Key, typename Value>
+    struct map_type;
+
+    template <typename Key, typename Value>
+    struct map_type_base
+    {
+        typedef map::hash<Key>    key_hash;
+        typedef map::less<Key>    key_less;
+        typedef cmp<Key>          key_compare;
+
+        struct equal_to {
+            bool operator()( Key const& k1, Key const& k2 ) const
+            {
+                return key_compare()( k1, k2 ) == 0;
+            }
+        };
+
+        struct hash2: public key_hash
+        {
+            size_t operator()( Key const& k ) const
+            {
+                size_t h = key_hash::operator ()( k );
+                size_t seed = ~h;
+                seed ^= h + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+                return seed;
+            }
+            template <typename Q>
+            size_t operator()( Q const& k ) const
+            {
+                size_t h = key_hash::operator ()( k );
+                size_t seed = ~h;
+                seed ^= h + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+                return seed;
+            }
+        };
+    };
+
+    struct empty_stat {};
+    static inline cds_test::property_stream& operator <<( cds_test::property_stream& o, empty_stat const& )
+    {
+        return o;
+    }
+
+    template <typename Map>
+    static inline void print_stat( cds_test::property_stream& o, Map const& m )
+    {
+        o << m.statistics();
+    }
+
+
+    template <typename Map>
+    static inline void check_before_cleanup( Map& /*m*/ )
+    {}
+
+    template <typename Map>
+    static inline void additional_cleanup( Map& /*m*/ )
+    {}
+
+    template <typename Map>
+    static inline void additional_check( Map& /*m*/ )
+    {}
+
+} // namespace map
+
+#endif // ifndef CDSUNIT_MAP_TYPE_H
diff --git a/test/stress/sequential/sequential-map/map_type_bronson_avltree.h b/test/stress/sequential/sequential-map/map_type_bronson_avltree.h
new file mode 100644 (file)
index 0000000..87f7cd9
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_BRONSON_AVLTREE_H
+#define CDSUNIT_MAP_TYPE_BRONSON_AVLTREE_H
+
+#include "map_type.h"
+
+#include <cds/memory/vyukov_queue_pool.h>
+#include <cds/sync/pool_monitor.h>
+#include <cds/container/bronson_avltree_map_rcu.h>
+
+#include <cds_test/stat_bronson_avltree_out.h>
+#include <cds_test/stat_sync_monitor_out.h>
+
+namespace map {
+
+    template <class GC, typename Key, typename T, typename Traits = cc::bronson_avltree::traits >
+    class BronsonAVLTreeMap : public cc::BronsonAVLTreeMap< GC, Key, T, Traits >
+    {
+        typedef cc::BronsonAVLTreeMap< GC, Key, T, Traits > base_class;
+    public:
+        template <typename Config>
+        BronsonAVLTreeMap( Config const& /*cfg*/ )
+            : base_class()
+        {}
+
+        std::pair<Key, bool> extract_min_key()
+        {
+            Key key;
+            typename base_class::exempt_ptr xp = base_class::extract_min( [&key]( Key const& k ) { key = k; } );
+            if ( xp )
+                return std::make_pair( key, true );
+            return std::make_pair( key, false );
+        }
+
+        std::pair<Key, bool> extract_max_key()
+        {
+            Key key;
+            typename base_class::exempt_ptr xp = base_class::extract_max( [&key]( Key const& k ) { key = k; } );
+            if ( xp )
+                return std::make_pair( key, true );
+            return std::make_pair( key, false );
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = true;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    struct tag_BronsonAVLTreeMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_BronsonAVLTreeMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value >      base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+
+        typedef cds::memory::vyukov_queue_pool< std::mutex >         BronsonAVLTreeMap_simple_pool;
+        typedef cds::memory::lazy_vyukov_queue_pool< std::mutex >    BronsonAVLTreeMap_lazy_pool;
+        typedef cds::memory::bounded_vyukov_queue_pool< std::mutex > BronsonAVLTreeMap_bounded_pool;
+
+        struct BronsonAVLTreeMap_less: public
+            cc::bronson_avltree::make_traits<
+                co::less< less >
+                ,cc::bronson_avltree::relaxed_insert< false >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less > BronsonAVLTreeMap_rcu_gpi_less;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_less > BronsonAVLTreeMap_rcu_gpb_less;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_less > BronsonAVLTreeMap_rcu_gpt_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_less > BronsonAVLTreeMap_rcu_shb_less;
+#endif
+        struct BronsonAVLTreeMap_cmp_stat: public
+            cc::bronson_avltree::make_traits<
+                co::compare< compare >
+                ,cc::bronson_avltree::relaxed_insert< false >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,co::stat< cc::bronson_avltree::stat<>>
+            >::type
+        {};
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_cmp_stat > BronsonAVLTreeMap_rcu_gpi_cmp_stat;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_cmp_stat > BronsonAVLTreeMap_rcu_gpb_cmp_stat;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_cmp_stat > BronsonAVLTreeMap_rcu_gpt_cmp_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_cmp_stat > BronsonAVLTreeMap_rcu_shb_cmp_stat;
+#endif
+
+        struct BronsonAVLTreeMap_less_pool_simple: public BronsonAVLTreeMap_less
+        {
+            typedef cds::sync::pool_monitor<BronsonAVLTreeMap_simple_pool> sync_monitor;
+        };
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less_pool_simple > BronsonAVLTreeMap_rcu_gpi_less_pool_simple;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_less_pool_simple > BronsonAVLTreeMap_rcu_gpb_less_pool_simple;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_less_pool_simple > BronsonAVLTreeMap_rcu_gpt_less_pool_simple;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_less_pool_simple > BronsonAVLTreeMap_rcu_shb_less_pool_simple;
+#endif
+        struct BronsonAVLTreeMap_less_pool_simple_stat : public BronsonAVLTreeMap_less
+        {
+            typedef cc::bronson_avltree::stat<> stat;
+            typedef cds::sync::pool_monitor<BronsonAVLTreeMap_simple_pool, cds::opt::none, true > sync_monitor;
+        };
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less_pool_simple_stat > BronsonAVLTreeMap_rcu_gpi_less_pool_simple_stat;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_less_pool_simple_stat > BronsonAVLTreeMap_rcu_gpb_less_pool_simple_stat;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_less_pool_simple_stat > BronsonAVLTreeMap_rcu_gpt_less_pool_simple_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_less_pool_simple_stat > BronsonAVLTreeMap_rcu_shb_less_pool_simple_stat;
+#endif
+        struct BronsonAVLTreeMap_less_pool_lazy: public BronsonAVLTreeMap_less
+        {
+            typedef cds::sync::pool_monitor<BronsonAVLTreeMap_lazy_pool> sync_monitor;
+            static CDS_CONSTEXPR bool const relaxed_insert = false; // relaxed insert can lead to test assert triggering
+        };
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less_pool_lazy > BronsonAVLTreeMap_rcu_gpi_less_pool_lazy;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_less_pool_lazy > BronsonAVLTreeMap_rcu_gpb_less_pool_lazy;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_less_pool_lazy > BronsonAVLTreeMap_rcu_gpt_less_pool_lazy;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_less_pool_lazy > BronsonAVLTreeMap_rcu_shb_less_pool_lazy;
+#endif
+        struct BronsonAVLTreeMap_less_pool_lazy_stat : public BronsonAVLTreeMap_less
+        {
+            typedef cc::bronson_avltree::stat<> stat;
+            typedef cds::sync::pool_monitor<BronsonAVLTreeMap_lazy_pool, cds::opt::none, true > sync_monitor;
+            static CDS_CONSTEXPR bool const relaxed_insert = false; // relaxed insert can lead to test assert triggering
+        };
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less_pool_lazy_stat > BronsonAVLTreeMap_rcu_gpi_less_pool_lazy_stat;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_less_pool_lazy_stat > BronsonAVLTreeMap_rcu_gpb_less_pool_lazy_stat;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_less_pool_lazy_stat > BronsonAVLTreeMap_rcu_gpt_less_pool_lazy_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_less_pool_lazy_stat > BronsonAVLTreeMap_rcu_shb_less_pool_lazy_stat;
+#endif
+        struct BronsonAVLTreeMap_less_pool_bounded: public BronsonAVLTreeMap_less
+        {
+            typedef cds::sync::pool_monitor<BronsonAVLTreeMap_bounded_pool> sync_monitor;
+            static CDS_CONSTEXPR bool const relaxed_insert = false; // relaxed insert can lead to test assert triggering
+        };
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less_pool_bounded > BronsonAVLTreeMap_rcu_gpi_less_pool_bounded;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_less_pool_bounded > BronsonAVLTreeMap_rcu_gpb_less_pool_bounded;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_less_pool_bounded > BronsonAVLTreeMap_rcu_gpt_less_pool_bounded;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_less_pool_bounded > BronsonAVLTreeMap_rcu_shb_less_pool_bounded;
+#endif
+        struct BronsonAVLTreeMap_less_pool_bounded_stat : public BronsonAVLTreeMap_less
+        {
+            typedef cc::bronson_avltree::stat<> stat;
+            typedef cds::sync::pool_monitor<BronsonAVLTreeMap_bounded_pool, cds::opt::none, true > sync_monitor;
+            static CDS_CONSTEXPR bool const relaxed_insert = false; // relaxed insert can lead to test assert triggering
+        };
+        typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less_pool_bounded_stat > BronsonAVLTreeMap_rcu_gpi_less_pool_bounded_stat;
+        typedef BronsonAVLTreeMap< rcu_gpb, Key, Value, BronsonAVLTreeMap_less_pool_bounded_stat > BronsonAVLTreeMap_rcu_gpb_less_pool_bounded_stat;
+        typedef BronsonAVLTreeMap< rcu_gpt, Key, Value, BronsonAVLTreeMap_less_pool_bounded_stat > BronsonAVLTreeMap_rcu_gpt_less_pool_bounded_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef BronsonAVLTreeMap< rcu_shb, Key, Value, BronsonAVLTreeMap_less_pool_bounded_stat > BronsonAVLTreeMap_rcu_shb_less_pool_bounded_stat;
+#endif
+    };
+
+    template <typename GC, typename Key, typename T, typename Traits>
+    static inline void print_stat( cds_test::property_stream& o, BronsonAVLTreeMap<GC, Key, T, Traits> const& m )
+    {
+        o << m.statistics()
+          << m.monitor().statistics();
+    }
+
+    template <typename GC, typename Key, typename T, typename Traits>
+    static inline void check_before_cleanup( BronsonAVLTreeMap<GC, Key, T, Traits>& m )
+    {
+        bool check_consistency_result = m.check_consistency([]( size_t nLevel, size_t hLeft, size_t hRight )
+            {
+                EXPECT_TRUE( false ) << "Tree violation on level=" << nLevel << ": hLeft=" << hLeft << ", hRight=" << hRight;
+            });
+        EXPECT_TRUE( check_consistency_result ) << "Internal tree structure violation";
+    }
+
+
+#define CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, bronson_map_type, key_type, value_type ) \
+    TEST_F( fixture, bronson_map_type ) \
+    { \
+        typedef map::map_type< tag_BronsonAVLTreeMap, key_type, value_type >::bronson_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+#   define CDSSTRESS_BronsonAVLTreeMap_SHRCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_shb_less,                   key_type, value_type ) \
+        CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_shb_less_pool_simple,       key_type, value_type ) \
+        CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_shb_less_pool_lazy,         key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_BronsonAVLTreeMap_SHRCU( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 0
+#   define CDSSTRESS_BronsonAVLTreeMap_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_gpi_less_pool_simple,       key_type, value_type ) \
+        CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_gpi_less_pool_lazy,         key_type, value_type ) \
+        CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_gpb_less_pool_lazy,         key_type, value_type ) \
+        CDSSTRESS_BronsonAVLTreeMap_SHRCU( fixture, test_case, key_type, value_type )
+
+#else
+#   define CDSSTRESS_BronsonAVLTreeMap_1( fixture, test_case, key_type, value_type )
+#endif
+
+#define CDSSTRESS_BronsonAVLTreeMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_gpi_less,                   key_type, value_type ) \
+    CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_gpb_less,                   key_type, value_type ) \
+    CDSSTRESS_BronsonAVLTreeMap_case( fixture, test_case, BronsonAVLTreeMap_rcu_gpb_less_pool_simple,       key_type, value_type ) \
+    CDSSTRESS_BronsonAVLTreeMap_1( fixture, test_case, key_type, value_type ) \
+
+}   // namespace map
+
+#endif // ifndef CDSUNIT_MAP_TYPE_BRONSON_AVLTREE_H
diff --git a/test/stress/sequential/sequential-map/map_type_cuckoo.h b/test/stress/sequential/sequential-map/map_type_cuckoo.h
new file mode 100644 (file)
index 0000000..2ef8892
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_CUCKOO_H
+#define CDSUNIT_MAP_TYPE_CUCKOO_H
+
+#include "map_type.h"
+#include <cds/container/cuckoo_map.h>
+#include <cds_test/stat_cuckoo_out.h>
+#include <cds_test/hash_func.h>
+
+namespace map {
+
+    template <typename K, typename V, typename Traits>
+    class CuckooMap: public cc::CuckooMap< K, V, Traits >
+    {
+    public:
+        typedef cc::CuckooMap< K, V, Traits > base_class;
+
+    public:
+        template <typename Config>
+        CuckooMap( Config const& cfg )
+            : base_class(
+                cfg.s_nCuckooInitialSize,
+                static_cast<unsigned int>( cfg.s_nCuckooProbesetSize ),
+                static_cast<unsigned int>( cfg.s_nCuckooProbesetThreshold )
+            )
+        {}
+
+        template <typename Q, typename Pred>
+        bool erase_with( Q const& key, Pred /*pred*/ )
+        {
+            return base_class::erase_with( key, typename std::conditional< base_class::c_isSorted, Pred, typename Pred::equal_to>::type());
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = false;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    struct tag_CuckooMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_CuckooMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value > base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+        typedef typename base_class::equal_to    equal_to;
+        typedef typename base_class::key_hash    hash;
+        typedef typename base_class::hash2       hash2;
+
+        template <typename Traits>
+        struct traits_CuckooStripedMap: public Traits
+        {
+            typedef cc::cuckoo::striping<> mutex_policy;
+        };
+        template <typename Traits>
+        struct traits_CuckooRefinableMap : public Traits
+        {
+            typedef cc::cuckoo::refinable<> mutex_policy;
+        };
+
+        struct traits_CuckooMap_list_unord :
+            public cc::cuckoo::make_traits <
+                cc::cuckoo::probeset_type< cc::cuckoo::list >
+                , co::equal_to< equal_to >
+                , co::hash< std::tuple< hash, hash2 > >
+            > ::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_unord>> CuckooStripedMap_list_unord;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_unord>> CuckooRefinableMap_list_unord;
+
+        struct traits_CuckooMap_list_unord_stat : public traits_CuckooMap_list_unord
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_unord_stat>> CuckooStripedMap_list_unord_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_unord_stat>> CuckooRefinableMap_list_unord_stat;
+
+        struct traits_CuckooMap_list_unord_storehash : public traits_CuckooMap_list_unord
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_unord_storehash>> CuckooStripedMap_list_unord_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_unord_storehash>> CuckooRefinableMap_list_unord_storehash;
+
+        struct traits_CuckooMap_list_ord :
+            public cc::cuckoo::make_traits <
+                cc::cuckoo::probeset_type< cc::cuckoo::list >
+                , co::compare< compare >
+                , co::hash< std::tuple< hash, hash2 > >
+            >::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_ord>> CuckooStripedMap_list_ord;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_ord>> CuckooRefinableMap_list_ord;
+
+        struct traits_CuckooMap_list_ord_stat : public traits_CuckooMap_list_ord
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_ord_stat>> CuckooStripedMap_list_ord_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_ord_stat>> CuckooRefinableMap_list_ord_stat;
+
+        struct traits_CuckooMap_list_ord_storehash : public traits_CuckooMap_list_ord
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_ord_storehash>> CuckooStripedMap_list_ord_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_ord_storehash>> CuckooRefinableMap_list_ord_storehash;
+
+        struct traits_CuckooMap_vector_unord :
+            public cc::cuckoo::make_traits <
+                cc::cuckoo::probeset_type< cc::cuckoo::vector<4> >
+                , co::equal_to< equal_to >
+                , co::hash< std::tuple< hash, hash2 > >
+            >::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_unord>> CuckooStripedMap_vector_unord;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_unord>> CuckooRefinableMap_vector_unord;
+
+        struct traits_CuckooMap_vector_unord_stat : public traits_CuckooMap_vector_unord
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_unord_stat>> CuckooStripedMap_vector_unord_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_unord_stat>> CuckooRefinableMap_vector_unord_stat;
+
+        struct traits_CuckooMap_vector_unord_storehash : public traits_CuckooMap_vector_unord
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_unord_storehash>> CuckooStripedMap_vector_unord_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_unord_storehash>> CuckooRefinableMap_vector_unord_storehash;
+
+        struct traits_CuckooMap_vector_ord :
+            public cc::cuckoo::make_traits <
+                cc::cuckoo::probeset_type< cc::cuckoo::vector<4> >
+                , co::compare< compare >
+                , co::hash< std::tuple< hash, hash2 > >
+            >::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_ord>> CuckooStripedMap_vector_ord;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_ord>> CuckooRefinableMap_vector_ord;
+
+        struct traits_CuckooMap_vector_ord_stat : public traits_CuckooMap_vector_ord
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_ord_stat>> CuckooStripedMap_vector_ord_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_ord_stat>> CuckooRefinableMap_vector_ord_stat;
+
+        struct traits_CuckooMap_vector_ord_storehash : public traits_CuckooMap_vector_ord
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_ord_storehash>> CuckooStripedMap_vector_ord_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_ord_storehash>> CuckooRefinableMap_vector_ord_storehash;
+
+#if CDS_BUILD_BITS == 64
+
+        struct traits_CuckooMap_list_unord_city64:
+            public cc::cuckoo::make_traits <
+                cc::cuckoo::probeset_type< cc::cuckoo::list >
+                , co::equal_to< equal_to >
+                , co::hash< std::tuple< cds_test::city64, hash2 > >
+            > ::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_unord_city64>> CuckooStripedMap_list_unord_city64;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_unord_city64>> CuckooRefinableMap_list_unord_city64;
+
+        struct traits_CuckooMap_list_unord_city64_stat: public traits_CuckooMap_list_unord_city64
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_unord_city64_stat>> CuckooStripedMap_list_unord_city64_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_unord_city64_stat>> CuckooRefinableMap_list_unord_city64_stat;
+
+        struct traits_CuckooMap_list_unord_city64_storehash: public traits_CuckooMap_list_unord_city64
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_unord_city64_storehash>> CuckooStripedMap_list_unord_city64_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_unord_city64_storehash>> CuckooRefinableMap_list_unord_city64_storehash;
+
+        struct traits_CuckooMap_list_ord_city64:
+            public cc::cuckoo::make_traits <
+            cc::cuckoo::probeset_type< cc::cuckoo::list >
+            , co::compare< compare >
+            , co::hash< std::tuple< cds_test::city64, hash2 > >
+            >::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_ord_city64>> CuckooStripedMap_list_ord_city64;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_ord_city64>> CuckooRefinableMap_list_ord_city64;
+
+        struct traits_CuckooMap_list_ord_city64_stat: public traits_CuckooMap_list_ord_city64
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_ord_city64_stat>> CuckooStripedMap_list_ord_city64_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_ord_city64_stat>> CuckooRefinableMap_list_ord_city64_stat;
+
+        struct traits_CuckooMap_list_ord_city64_storehash: public traits_CuckooMap_list_ord_city64
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_list_ord_city64_storehash>> CuckooStripedMap_list_ord_city64_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_list_ord_city64_storehash>> CuckooRefinableMap_list_ord_city64_storehash;
+
+        struct traits_CuckooMap_vector_unord_city64:
+            public cc::cuckoo::make_traits <
+            cc::cuckoo::probeset_type< cc::cuckoo::vector<4> >
+            , co::equal_to< equal_to >
+            , co::hash< std::tuple< cds_test::city64, hash2 > >
+            >::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_unord_city64>> CuckooStripedMap_vector_unord_city64;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_unord_city64>> CuckooRefinableMap_vector_unord_city64;
+
+        struct traits_CuckooMap_vector_unord_city64_stat: public traits_CuckooMap_vector_unord_city64
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_unord_city64_stat>> CuckooStripedMap_vector_unord_city64_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_unord_city64_stat>> CuckooRefinableMap_vector_unord_city64_stat;
+
+        struct traits_CuckooMap_vector_unord_city64_storehash: public traits_CuckooMap_vector_unord_city64
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_unord_city64_storehash>> CuckooStripedMap_vector_unord_city64_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_unord_city64_storehash>> CuckooRefinableMap_vector_unord_city64_storehash;
+
+        struct traits_CuckooMap_vector_ord_city64:
+            public cc::cuckoo::make_traits <
+            cc::cuckoo::probeset_type< cc::cuckoo::vector<4> >
+            , co::compare< compare >
+            , co::hash< std::tuple< cds_test::city64, hash2 > >
+            >::type
+        {};
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_ord_city64>> CuckooStripedMap_vector_ord_city64;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_ord_city64>> CuckooRefinableMap_vector_ord_city64;
+
+        struct traits_CuckooMap_vector_ord_city64_stat: public traits_CuckooMap_vector_ord_city64
+        {
+            typedef cc::cuckoo::stat stat;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_ord_city64_stat>> CuckooStripedMap_vector_ord_city64_stat;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_ord_city64_stat>> CuckooRefinableMap_vector_ord_city64_stat;
+
+        struct traits_CuckooMap_vector_ord_city64_storehash: public traits_CuckooMap_vector_ord_city64
+        {
+            static CDS_CONSTEXPR const bool store_hash = true;
+        };
+        typedef CuckooMap< Key, Value, traits_CuckooStripedMap<traits_CuckooMap_vector_ord_city64_storehash>> CuckooStripedMap_vector_ord_city64_storehash;
+        typedef CuckooMap< Key, Value, traits_CuckooRefinableMap<traits_CuckooMap_vector_ord_city64_storehash>> CuckooRefinableMap_vector_ord_city64_storehash;
+#endif // CDS_BUILD_BITS == 64
+    };
+
+    template <typename Key, typename T, typename Traits >
+    static inline void print_stat( cds_test::property_stream& o, cc::CuckooMap< Key, T, Traits > const& s )
+    {
+        o << s.statistics() << s.mutex_policy_statistics();
+    }
+
+    template <typename Key, typename V, typename Traits>
+    static inline void print_stat( cds_test::property_stream& o, CuckooMap< Key, V, Traits > const& s )
+    {
+        typedef CuckooMap< Key, V, Traits > map_type;
+        print_stat( o, static_cast<typename map_type::base_class const&>(s));
+    }
+
+}   // namespace map
+
+
+#define CDSSTRESS_CuckooMap_case( fixture, test_case, cuckoo_map_type, key_type, value_type ) \
+    TEST_F( fixture, cuckoo_map_type ) \
+    { \
+        typedef map::map_type< tag_CuckooMap, key_type, value_type >::cuckoo_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#define CDSSTRESS_CuckooMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_unord,              key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_unord,            key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_unord_stat,         key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_unord_stat,       key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_unord_storehash,    key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_unord_storehash,  key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_ord,                key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_ord,              key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_ord_stat,           key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_ord_stat,         key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_ord_storehash,      key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_ord_storehash,    key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_unord,            key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_unord,          key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_unord_stat,       key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_unord_stat,     key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_unord_storehash,  key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_unord_storehash, key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_ord,              key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_ord,            key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_ord_stat,         key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_ord_stat,       key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_ord_storehash,    key_type, value_type ) \
+    CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_ord_storehash,  key_type, value_type )
+
+#if CDS_BUILD_BITS == 64
+#   define CDSSTRESS_CuckooMap_city64( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_unord_city64,              key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_unord_city64,            key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_unord_city64_stat,         key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_unord_city64_stat,       key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_unord_city64_storehash,    key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_unord_city64_storehash,  key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_ord_city64,                key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_ord_city64,              key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_ord_city64_stat,           key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_ord_city64_stat,         key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_list_ord_city64_storehash,      key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_list_ord_city64_storehash,    key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_unord_city64,            key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_unord_city64,          key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_unord_city64_stat,       key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_unord_city64_stat,     key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_unord_city64_storehash,  key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_unord_city64_storehash, key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_ord_city64,              key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_ord_city64,            key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_ord_city64_stat,         key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_ord_city64_stat,       key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooStripedMap_vector_ord_city64_storehash,    key_type, value_type ) \
+        CDSSTRESS_CuckooMap_case( fixture, test_case, CuckooRefinableMap_vector_ord_city64_storehash,  key_type, value_type )
+#endif
+#endif // ifndef CDSUNIT_MAP_TYPE_CUCKOO_H
diff --git a/test/stress/sequential/sequential-map/map_type_ellen_bintree.h b/test/stress/sequential/sequential-map/map_type_ellen_bintree.h
new file mode 100644 (file)
index 0000000..cfb534e
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_ELLEN_BINTREE_H
+#define CDSUNIT_MAP_TYPE_ELLEN_BINTREE_H
+
+#include "map_type.h"
+
+#include <cds/container/ellen_bintree_map_rcu.h>
+#include <cds/container/ellen_bintree_map_hp.h>
+#include <cds/container/ellen_bintree_map_dhp.h>
+
+#include <cds_test/stat_ellenbintree_out.h>
+#include "framework/ellen_bintree_update_desc_pool.h"
+
+namespace map {
+
+    template <class GC, typename Key, typename T, typename Traits = cc::ellen_bintree::traits >
+    class EllenBinTreeMap : public cc::EllenBinTreeMap< GC, Key, T, Traits >
+    {
+        typedef cc::EllenBinTreeMap< GC, Key, T, Traits > base_class;
+    public:
+        template <typename Config>
+        EllenBinTreeMap( Config const& /*cfg*/)
+            : base_class()
+        {}
+
+        std::pair<Key, bool> extract_min_key()
+        {
+            auto xp = base_class::extract_min();
+            if ( xp )
+                return std::make_pair( xp->first, true );
+            return std::make_pair( Key(), false );
+        }
+
+        std::pair<Key, bool> extract_max_key()
+        {
+            auto xp = base_class::extract_max();
+            if ( xp )
+                return std::make_pair( xp->first, true );
+            return std::make_pair( Key(), false );
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = true;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    struct tag_EllenBinTreeMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_EllenBinTreeMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value >      base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+
+        struct ellen_bintree_props {
+            struct hp_gc {
+                typedef cc::ellen_bintree::map_node<cds::gc::HP, Key, Value>        leaf_node;
+                typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
+                typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
+            };
+            struct dhp_gc {
+                typedef cc::ellen_bintree::map_node<cds::gc::DHP, Key, Value>       leaf_node;
+                typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
+                typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
+            };
+            struct gpi {
+                typedef cc::ellen_bintree::map_node<rcu_gpi, Key, Value>            leaf_node;
+                typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
+                typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
+            };
+            struct gpb {
+                typedef cc::ellen_bintree::map_node<rcu_gpb, Key, Value>            leaf_node;
+                typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
+                typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
+            };
+            struct gpt {
+                typedef cc::ellen_bintree::map_node<rcu_gpt, Key, Value>            leaf_node;
+                typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
+                typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
+            };
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+            struct shb {
+                typedef cc::ellen_bintree::map_node<rcu_shb, Key, Value>            leaf_node;
+                typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
+                typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
+            };
+#endif
+        };
+
+        struct traits_EllenBinTreeMap: public cc::ellen_bintree::make_set_traits<
+                co::less< less >
+                ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        struct traits_EllenBinTreeMap_hp : traits_EllenBinTreeMap {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_hp > EllenBinTreeMap_hp;
+
+        struct traits_EllenBinTreeMap_dhp : traits_EllenBinTreeMap {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< cds::gc::DHP, Key, Value, traits_EllenBinTreeMap_dhp > EllenBinTreeMap_dhp;
+
+        struct traits_EllenBinTreeMap_gpi : traits_EllenBinTreeMap {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpi::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_gpi, Key, Value, traits_EllenBinTreeMap_gpi > EllenBinTreeMap_rcu_gpi;
+
+        struct traits_EllenBinTreeMap_gpb : traits_EllenBinTreeMap {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_gpb, Key, Value, traits_EllenBinTreeMap_gpb > EllenBinTreeMap_rcu_gpb;
+
+        struct traits_EllenBinTreeMap_gpt : traits_EllenBinTreeMap {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpt::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_gpt, Key, Value, traits_EllenBinTreeMap_gpt > EllenBinTreeMap_rcu_gpt;
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        struct traits_EllenBinTreeMap_shb : traits_EllenBinTreeMap {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::shb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_shb, Key, Value, traits_EllenBinTreeMap_shb > EllenBinTreeMap_rcu_shb;
+#endif
+
+        struct traits_EllenBinTreeMap_yield : public traits_EllenBinTreeMap
+        {
+            typedef cds::backoff::yield back_off;
+        };
+        struct traits_EllenBinTreeMap_hp_yield : traits_EllenBinTreeMap_yield {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_hp_yield > EllenBinTreeMap_hp_yield;
+
+        struct traits_EllenBinTreeMap_dhp_yield : traits_EllenBinTreeMap_yield {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< cds::gc::DHP, Key, Value, traits_EllenBinTreeMap_dhp_yield > EllenBinTreeMap_dhp_yield;
+
+        struct traits_EllenBinTreeMap_gpb_yield : traits_EllenBinTreeMap_yield {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_gpb, Key, Value, traits_EllenBinTreeMap_gpb_yield > EllenBinTreeMap_rcu_gpb_yield;
+
+
+        struct traits_EllenBinTreeMap_stat: public cc::ellen_bintree::make_set_traits<
+                co::less< less >
+                ,cc::ellen_bintree::update_desc_allocator<
+                    cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor >
+                >
+                ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
+                ,co::stat< cc::ellen_bintree::stat<> >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+
+        struct traits_EllenBinTreeMap_stat_hp : public traits_EllenBinTreeMap_stat
+        {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_stat_hp > EllenBinTreeMap_hp_stat;
+
+        struct traits_EllenBinTreeMap_stat_dhp : public traits_EllenBinTreeMap_stat
+        {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_stat_dhp > EllenBinTreeMap_dhp_stat;
+
+        struct traits_EllenBinTreeMap_stat_gpi : public traits_EllenBinTreeMap_stat
+        {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpi::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_gpi, Key, Value, traits_EllenBinTreeMap_stat_gpi > EllenBinTreeMap_rcu_gpi_stat;
+
+        struct traits_EllenBinTreeMap_stat_gpb : public traits_EllenBinTreeMap_stat
+        {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_gpb, Key, Value, traits_EllenBinTreeMap_stat_gpb > EllenBinTreeMap_rcu_gpb_stat;
+
+        struct traits_EllenBinTreeMap_stat_gpt : public traits_EllenBinTreeMap_stat
+        {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpt::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_gpt, Key, Value, traits_EllenBinTreeMap_stat_gpt > EllenBinTreeMap_rcu_gpt_stat;
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        struct traits_EllenBinTreeMap_stat_shb : public traits_EllenBinTreeMap_stat
+        {
+            typedef cds::memory::pool_allocator< typename ellen_bintree_props::shb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
+        };
+        typedef EllenBinTreeMap< rcu_shb, Key, Value, traits_EllenBinTreeMap_stat_shb > EllenBinTreeMap_rcu_shb_stat;
+#endif
+    };
+
+    template <typename GC, typename Key, typename T, typename Traits>
+    static inline void print_stat( cds_test::property_stream& o, EllenBinTreeMap<GC, Key, T, Traits> const& s )
+    {
+        o << s.statistics();
+    }
+    template <typename GC, typename Key, typename T, typename Traits>
+    static inline void additional_cleanup( EllenBinTreeMap<GC, Key, T, Traits>& /*s*/ )
+    {
+        ellen_bintree_pool::internal_node_counter::reset();
+    }
+    namespace ellen_bintree_check {
+        static inline void check_stat( cds::intrusive::ellen_bintree::empty_stat const& /*s*/ )
+        {
+            // This check is not valid for thread-based RCU
+            /*
+            CPPUNIT_CHECK_CURRENT_EX( ellen_bintree_pool::internal_node_counter::m_nAlloc.get() == ellen_bintree_pool::internal_node_counter::m_nFree.get(),
+                "m_nAlloc=" << ellen_bintree_pool::internal_node_counter::m_nAlloc.get()
+                << ", m_nFree=" << ellen_bintree_pool::internal_node_counter::m_nFree.get()
+                );
+            */
+        }
+
+        static inline void check_stat( cds::intrusive::ellen_bintree::stat<> const& stat )
+        {
+            EXPECT_EQ( stat.m_nInternalNodeCreated, stat.m_nInternalNodeDeleted );
+            EXPECT_EQ( stat.m_nUpdateDescCreated, stat.m_nUpdateDescDeleted );
+            EXPECT_EQ( ellen_bintree_pool::internal_node_counter::m_nAlloc.get(), stat.m_nInternalNodeCreated );
+        }
+    }   // namespace ellen_bintree_check
+    template <typename GC, typename Key, typename T, typename Traits>
+    static inline void additional_check( EllenBinTreeMap<GC, Key, T, Traits>& m )
+    {
+        GC::force_dispose();
+        ellen_bintree_check::check_stat( m.statistics());
+    }
+
+    template <typename GC, typename Key, typename T, typename Traits>
+    static inline void check_before_cleanup( EllenBinTreeMap<GC, Key, T, Traits>& m )
+    {
+        EXPECT_TRUE( m.check_consistency());
+    }
+}   // namespace map
+
+
+#define CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, ellen_map_type, key_type, value_type ) \
+    TEST_F( fixture, ellen_map_type ) \
+    { \
+        typedef map::map_type< tag_EllenBinTreeMap, key_type, value_type >::ellen_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+#   define CDSSTRESS_EllenBinTreeMap_SHRCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_rcu_shb,        key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_EllenBinTreeMap_SHRCU( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 0
+#   define CDSSTRESS_EllenBinTreeMap_HP_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_hp_yield,       key_type, value_type ) \
+        CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_dhp_yield,      key_type, value_type ) \
+
+
+#   define CDSSTRESS_EllenBinTreeMap_RCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_rcu_gpi,        key_type, value_type ) \
+        CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_rcu_gpb_yield,  key_type, value_type ) \
+        CDSSTRESS_EllenBinTreeMap_SHRCU( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_EllenBinTreeMap_HP_1( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_EllenBinTreeMap_RCU_1( fixture, test_case, key_type, value_type )
+#endif
+
+#define CDSSTRESS_EllenBinTreeMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_hp,             key_type, value_type ) \
+    CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_dhp,            key_type, value_type ) \
+    CDSSTRESS_EllenBinTreeMap_HP_1( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_EllenBinTreeMap_RCU( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_EllenBinTreeMap_case( fixture, test_case, EllenBinTreeMap_rcu_gpb,        key_type, value_type ) \
+    CDSSTRESS_EllenBinTreeMap_RCU_1( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_EllenBinTreeMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_EllenBinTreeMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_EllenBinTreeMap_RCU( fixture, test_case, key_type, value_type ) \
+
+#endif // ifndef CDSUNIT_MAP_TYPE_ELLEN_BINTREE_H
diff --git a/test/stress/sequential/sequential-map/map_type_feldman_hashmap.h b/test/stress/sequential/sequential-map/map_type_feldman_hashmap.h
new file mode 100644 (file)
index 0000000..0d1a862
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_FELDMAN_HASHMAP_H
+#define CDSUNIT_MAP_TYPE_FELDMAN_HASHMAP_H
+
+#include "map_type.h"
+
+#include <cds/container/feldman_hashmap_hp.h>
+#include <cds/container/feldman_hashmap_dhp.h>
+#include <cds/container/feldman_hashmap_rcu.h>
+
+#include <cds_test/stat_feldman_hashset_out.h>
+#include <cds_test/hash_func.h>
+
+namespace map {
+
+    template <class GC, typename Key, typename T, typename Traits = cc::feldman_hashmap::traits>
+    class FeldmanHashMap : public cc::FeldmanHashMap< GC, Key, T, Traits >
+    {
+        typedef cc::FeldmanHashMap< GC, Key, T, Traits > base_class;
+    public:
+
+        template <typename OtherTraits>
+        struct rebind_traits {
+            typedef FeldmanHashMap<GC, Key, T, OtherTraits > result;
+        };
+
+        template <typename Config>
+        FeldmanHashMap( Config const& cfg)
+            : base_class( cfg.s_nFeldmanMap_HeadBits, cfg.s_nFeldmanMap_ArrayBits )
+        {}
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+        get_begin()
+        {
+            return base_class::begin();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+        get_end()
+        {
+            return base_class::end();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::reverse_iterator>::value, Iterator>::type
+            get_begin()
+        {
+            return base_class::rbegin();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::reverse_iterator>::value, Iterator>::type
+            get_end()
+        {
+            return base_class::rend();
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = true;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = true;
+    };
+
+    struct tag_FeldmanHashMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_FeldmanHashMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value >      base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+
+        struct traits_FeldmanHashMap_stdhash : public cc::feldman_hashmap::traits
+        {
+            typedef std::hash< Key >    hash;
+            typedef std::less<size_t>   less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
+        };
+
+        typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_stdhash >    FeldmanHashMap_hp_stdhash;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_stdhash >    FeldmanHashMap_dhp_stdhash;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value, traits_FeldmanHashMap_stdhash >    FeldmanHashMap_rcu_gpi_stdhash;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value, traits_FeldmanHashMap_stdhash >    FeldmanHashMap_rcu_gpb_stdhash;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value, traits_FeldmanHashMap_stdhash >    FeldmanHashMap_rcu_gpt_stdhash;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value, traits_FeldmanHashMap_stdhash >    FeldmanHashMap_rcu_shb_stdhash;
+#endif
+
+        struct traits_FeldmanHashMap_stdhash_stat: traits_FeldmanHashMap_stdhash
+        {
+            typedef cc::feldman_hashmap::stat<> stat;
+            typedef std::less<size_t>   less;
+        };
+
+        typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_stdhash_stat >    FeldmanHashMap_hp_stdhash_stat;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_stdhash_stat >    FeldmanHashMap_dhp_stdhash_stat;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value, traits_FeldmanHashMap_stdhash_stat >    FeldmanHashMap_rcu_gpi_stdhash_stat;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value, traits_FeldmanHashMap_stdhash_stat >    FeldmanHashMap_rcu_gpb_stdhash_stat;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value, traits_FeldmanHashMap_stdhash_stat >    FeldmanHashMap_rcu_gpt_stdhash_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value, traits_FeldmanHashMap_stdhash_stat >    FeldmanHashMap_rcu_shb_stdhash_stat;
+#endif
+
+        // CityHash
+#if CDS_BUILD_BITS == 64
+        struct traits_FeldmanHashMap_city64 : public cc::feldman_hashmap::traits
+        {
+            typedef ::cds_test::city64 hash;
+            typedef ::cds_test::city64::less less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
+        };
+        typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_hp_city64;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_dhp_city64;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_rcu_gpi_city64;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_rcu_gpb_city64;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_rcu_gpt_city64;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_rcu_shb_city64;
+#endif
+
+        struct traits_FeldmanHashMap_city64_stat : public traits_FeldmanHashMap_city64
+        {
+            typedef cc::feldman_hashmap::stat<> stat;
+        };
+        typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_city64_stat >    FeldmanHashMap_hp_city64_stat;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_city64_stat >    FeldmanHashMap_dhp_city64_stat;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value, traits_FeldmanHashMap_city64_stat >    FeldmanHashMap_rcu_gpi_city64_stat;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value, traits_FeldmanHashMap_city64_stat >    FeldmanHashMap_rcu_gpb_city64_stat;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value, traits_FeldmanHashMap_city64_stat >    FeldmanHashMap_rcu_gpt_city64_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value, traits_FeldmanHashMap_city64_stat >    FeldmanHashMap_rcu_shb_city64_stat;
+#endif
+
+        struct traits_FeldmanHashMap_city128 : public cc::feldman_hashmap::traits
+        {
+            typedef ::cds_test::city128 hash;
+            typedef ::cds_test::city128::less less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
+        };
+        typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_hp_city128;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_dhp_city128;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_rcu_gpi_city128;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_rcu_gpb_city128;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_rcu_gpt_city128;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_rcu_shb_city128;
+#endif
+
+        struct traits_FeldmanHashMap_city128_stat : public traits_FeldmanHashMap_city128
+        {
+            typedef cc::feldman_hashmap::stat<> stat;
+        };
+        typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_city128_stat >    FeldmanHashMap_hp_city128_stat;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_city128_stat >    FeldmanHashMap_dhp_city128_stat;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value, traits_FeldmanHashMap_city128_stat >    FeldmanHashMap_rcu_gpi_city128_stat;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value, traits_FeldmanHashMap_city128_stat >    FeldmanHashMap_rcu_gpb_city128_stat;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value, traits_FeldmanHashMap_city128_stat >    FeldmanHashMap_rcu_gpt_city128_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value, traits_FeldmanHashMap_city128_stat >    FeldmanHashMap_rcu_shb_city128_stat;
+#endif
+#endif // CDS_BUILD_BITS == 64
+
+
+        // for fixed-sized keys - no hash functor required
+        struct traits_FeldmanHashMap_fixed: public cc::feldman_hashmap::traits
+        {
+            typedef map::cmp<Key>    compare;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
+        };
+
+        typedef FeldmanHashMap< cds::gc::HP, Key, Value,  traits_FeldmanHashMap_fixed >    FeldmanHashMap_hp_fixed;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_fixed >   FeldmanHashMap_dhp_fixed;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value,      traits_FeldmanHashMap_fixed >    FeldmanHashMap_rcu_gpi_fixed;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value,      traits_FeldmanHashMap_fixed >    FeldmanHashMap_rcu_gpb_fixed;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value,      traits_FeldmanHashMap_fixed >    FeldmanHashMap_rcu_gpt_fixed;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value,      traits_FeldmanHashMap_fixed >    FeldmanHashMap_rcu_shb_fixed;
+#endif
+
+        struct traits_FeldmanHashMap_fixed_stat : public traits_FeldmanHashMap_fixed
+        {
+            typedef cc::feldman_hashmap::stat<> stat;
+        };
+        typedef FeldmanHashMap< cds::gc::HP, Key, Value,    traits_FeldmanHashMap_fixed_stat >  FeldmanHashMap_hp_fixed_stat;
+        typedef FeldmanHashMap< cds::gc::DHP, Key, Value,   traits_FeldmanHashMap_fixed_stat >  FeldmanHashMap_dhp_fixed_stat;
+        typedef FeldmanHashMap< rcu_gpi, Key, Value,        traits_FeldmanHashMap_fixed_stat >  FeldmanHashMap_rcu_gpi_fixed_stat;
+        typedef FeldmanHashMap< rcu_gpb, Key, Value,        traits_FeldmanHashMap_fixed_stat >  FeldmanHashMap_rcu_gpb_fixed_stat;
+        typedef FeldmanHashMap< rcu_gpt, Key, Value,        traits_FeldmanHashMap_fixed_stat >  FeldmanHashMap_rcu_gpt_fixed_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef FeldmanHashMap< rcu_shb, Key, Value, traits_FeldmanHashMap_fixed_stat > FeldmanHashMap_rcu_shb_fixed_stat;
+#endif
+
+    };
+
+    template <typename GC, typename K, typename T, typename Traits >
+    static inline void print_stat( cds_test::property_stream& o, FeldmanHashMap< GC, K, T, Traits > const& m )
+    {
+        std::vector< cds::intrusive::feldman_hashset::level_statistics > level_stat;
+        m.get_level_statistics( level_stat );
+
+        o << m.statistics()
+          << level_stat;
+    }
+
+#define CDSSTRESS_FeldmanHashMap_case( fixture, test_case, feldman_map_type, key_type, value_type ) \
+    TEST_F( fixture, feldman_map_type ) \
+    { \
+        typedef map::map_type< tag_FeldmanHashMap, key_type, value_type >::feldman_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+#   define CDSSTRESS_FeldmanHashMap_fixed_SHRCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_shb_fixed, key_type, value_type ) \
+
+#   define CDSSTRESS_FeldmanHashMap_stdhash_SHRCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_shb_stdhash, key_type, value_type ) \
+
+#   if CDS_BUILD_BITS == 64
+#       define CDSSTRESS_FeldmanHashMap_city64_SHRCU( fixture, test_case, key_type, value_type ) \
+            CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_shb_city64, key_type, value_type ) \
+
+#       define CDSSTRESS_FeldmanHashMap_city128_SHRCU( fixture, test_case, key_type, value_type ) \
+            CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_shb_city64, key_type, value_type ) \
+
+#   else
+#       define CDSSTRESS_FeldmanHashMap_city64_SHRCU( fixture, test_case, key_type, value_type )
+#       define CDSSTRESS_FeldmanHashMap_city128_SHRCU( fixture, test_case, key_type, value_type )
+#   endif
+
+#else
+#   define CDSSTRESS_FeldmanHashMap_fixed_SHRCU( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_stdhash_SHRCU( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city64_SHRCU( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city128_SHRCU( fixture, test_case, key_type, value_type )
+#endif
+
+#define CDSSTRESS_FeldmanHashMap_fixed_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_hp_fixed,         key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_dhp_fixed,        key_type, value_type ) \
+
+#define CDSSTRESS_FeldmanHashMap_fixed_RCU( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpi_fixed,        key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpb_fixed,        key_type, value_type ) \
+
+    //CDSSTRESS_FeldmanHashMap_fixed_SHRCU( fixture, test_case, key_type, value_type )
+
+#define CDSSTRESS_FeldmanHashMap_fixed( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_fixed_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_fixed_RCU( fixture, test_case, key_type, value_type ) \
+
+
+#define CDSSTRESS_FeldmanHashMap_stdhash_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_hp_stdhash,       key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_dhp_stdhash,      key_type, value_type ) \
+
+#define CDSSTRESS_FeldmanHashMap_stdhash_RCU( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpi_stdhash,      key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpb_stdhash,      key_type, value_type ) \
+
+    //CDSSTRESS_FeldmanHashMap_stdhash_SHRCU( fixture, test_case, key_type, value_type )
+
+#define CDSSTRESS_FeldmanHashMap_stdhash( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_stdhash_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_FeldmanHashMap_stdhash_RCU( fixture, test_case, key_type, value_type ) \
+
+
+#if CDS_BUILD_BITS == 64
+#   define CDSSTRESS_FeldmanHashMap_city64_HP( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_hp_city64, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_dhp_city64, key_type, value_type ) \
+
+#   define CDSSTRESS_FeldmanHashMap_city64_RCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpi_city64, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpb_city64, key_type, value_type ) \
+
+        //CDSSTRESS_FeldmanHashMap_city64_SHRCU( fixture, test_case, key_type, value_type )
+
+#   define CDSSTRESS_FeldmanHashMap_city64( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city64_HP( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city64_RCU( fixture, test_case, key_type, value_type ) \
+
+
+#   define CDSSTRESS_FeldmanHashMap_city128_HP( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_hp_city128, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_dhp_city128, key_type, value_type ) \
+
+#   define CDSSTRESS_FeldmanHashMap_city128_RCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpi_city128, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_case( fixture, test_case, FeldmanHashMap_rcu_gpb_city128, key_type, value_type ) \
+
+        //CDSSTRESS_FeldmanHashMap_city128_SHRCU( fixture, test_case, key_type, value_type )
+
+#   define CDSSTRESS_FeldmanHashMap_city128( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city128_HP( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city128_RCU( fixture, test_case, key_type, value_type ) \
+
+#   define CDSSTRESS_FeldmanHashMap_city_HP( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city64_HP( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city128_HP( fixture, test_case, key_type, value_type )
+
+#   define CDSSTRESS_FeldmanHashMap_city_RCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city64_RCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city128_RCU( fixture, test_case, key_type, value_type )
+
+#   define CDSSTRESS_FeldmanHashMap_city( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city_HP( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_FeldmanHashMap_city_RCU( fixture, test_case, key_type, value_type )
+
+#else
+#   define CDSSTRESS_FeldmanHashMap_city64_HP( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city64_RCU( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city64( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city128_HP( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city128_RCU( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city128( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city_HP( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city_RCU( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_FeldmanHashMap_city( fixture, test_case, key_type, value_type )
+#endif
+
+
+}   // namespace map
+
+#endif // #ifndef CDSUNIT_MAP_TYPE_FELDMAN_HASHMAP_H
diff --git a/test/stress/sequential/sequential-map/map_type_iterable_list.h b/test/stress/sequential/sequential-map/map_type_iterable_list.h
new file mode 100644 (file)
index 0000000..0ad60fa
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_ITERABLE_LIST_H
+#define CDSUNIT_MAP_TYPE_ITERABLE_LIST_H
+
+#include "map_type.h"
+
+#include <cds/container/iterable_kvlist_hp.h>
+#include <cds/container/iterable_kvlist_dhp.h>
+
+#include <cds_test/stat_iterable_list_out.h>
+
+namespace map {
+
+    template <typename Key, typename Value>
+    struct iterable_list_type
+    {
+        typedef typename map_type_base<Key, Value>::key_compare compare;
+        typedef typename map_type_base<Key, Value>::key_less    less;
+
+        struct traits_IterableList_cmp :
+            public cc::iterable_list::make_traits<
+                co::compare< compare >
+            >::type
+        {};
+        typedef cc::IterableKVList< cds::gc::HP,  Key, Value, traits_IterableList_cmp > IterableList_HP_cmp;
+        typedef cc::IterableKVList< cds::gc::DHP, Key, Value, traits_IterableList_cmp > IterableList_DHP_cmp;
+
+        struct traits_IterableList_cmp_stat: public traits_IterableList_cmp
+        {
+            typedef cc::iterable_list::stat<> stat;
+        };
+        typedef cc::IterableKVList< cds::gc::HP, Key, Value, traits_IterableList_cmp_stat > IterableList_HP_cmp_stat;
+        typedef cc::IterableKVList< cds::gc::DHP, Key, Value, traits_IterableList_cmp_stat > IterableList_DHP_cmp_stat;
+
+        struct traits_IterableList_cmp_seqcst :
+            public cc::iterable_list::make_traits<
+                co::compare< compare >
+                ,co::memory_model< co::v::sequential_consistent >
+            >::type
+        {};
+        typedef cc::IterableKVList< cds::gc::HP,  Key, Value, traits_IterableList_cmp_seqcst > IterableList_HP_cmp_seqcst;
+        typedef cc::IterableKVList< cds::gc::DHP, Key, Value, traits_IterableList_cmp_seqcst > IterableList_DHP_cmp_seqcst;
+
+
+        struct traits_IterableList_less :
+            public cc::iterable_list::make_traits<
+                co::less< less >
+            >::type
+        {};
+        typedef cc::IterableKVList< cds::gc::HP,  Key, Value, traits_IterableList_less > IterableList_HP_less;
+        typedef cc::IterableKVList< cds::gc::DHP, Key, Value, traits_IterableList_less > IterableList_DHP_less;
+
+        struct traits_IterableList_less_stat: public traits_IterableList_less
+        {
+            typedef cc::iterable_list::stat<> stat;
+        };
+        typedef cc::IterableKVList< cds::gc::HP, Key, Value, traits_IterableList_less_stat > IterableList_HP_less_stat;
+        typedef cc::IterableKVList< cds::gc::DHP, Key, Value, traits_IterableList_less_stat > IterableList_DHP_less_stat;
+
+        struct traits_IterableList_less_seqcst :
+            public cc::iterable_list::make_traits<
+                co::less< less >
+                ,co::memory_model< co::v::sequential_consistent >
+            >::type
+        {};
+        typedef cc::IterableKVList< cds::gc::HP,  Key, Value, traits_IterableList_less_seqcst > IterableList_HP_less_seqcst;
+        typedef cc::IterableKVList< cds::gc::DHP, Key, Value, traits_IterableList_less_seqcst > IterableList_DHP_less_seqcst;
+
+    };
+
+} // namespace map
+
+#endif // ifndef CDSUNIT_MAP_TYPE_ITERABLE_LIST_H
diff --git a/test/stress/sequential/sequential-map/map_type_lazy_list.h b/test/stress/sequential/sequential-map/map_type_lazy_list.h
new file mode 100644 (file)
index 0000000..27675f0
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_LAZY_LIST_H
+#define CDSUNIT_MAP_TYPE_LAZY_LIST_H
+
+#include "map_type.h"
+
+#include <cds/container/lazy_kvlist_hp.h>
+#include <cds/container/lazy_kvlist_dhp.h>
+#include <cds/container/lazy_kvlist_rcu.h>
+#include <cds/container/lazy_kvlist_nogc.h>
+
+#include <cds_test/stat_lazy_list_out.h>
+
+namespace map {
+
+    template <typename Key, typename Value>
+    struct lazy_list_type
+    {
+        typedef typename map_type_base<Key, Value>::key_compare compare;
+        typedef typename map_type_base<Key, Value>::key_less    less;
+        typedef typename map_type_base<Key, Value>::equal_to    equal_to;
+
+        struct traits_LazyList_cmp:
+            public cc::lazy_list::make_traits<
+                co::compare< compare >
+            >::type
+        {};
+        typedef cc::LazyKVList< cds::gc::HP, Key, Value, traits_LazyList_cmp > LazyList_HP_cmp;
+        typedef cc::LazyKVList< cds::gc::DHP, Key, Value, traits_LazyList_cmp > LazyList_DHP_cmp;
+        typedef cc::LazyKVList< cds::gc::nogc, Key, Value, traits_LazyList_cmp > LazyList_NOGC_cmp;
+        typedef cc::LazyKVList< rcu_gpi, Key, Value, traits_LazyList_cmp > LazyList_RCU_GPI_cmp;
+        typedef cc::LazyKVList< rcu_gpb, Key, Value, traits_LazyList_cmp > LazyList_RCU_GPB_cmp;
+        typedef cc::LazyKVList< rcu_gpt, Key, Value, traits_LazyList_cmp > LazyList_RCU_GPT_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::LazyKVList< rcu_shb, Key, Value, traits_LazyList_cmp > LazyList_RCU_SHB_cmp;
+#endif
+
+        struct traits_LazyList_cmp_stat: public traits_LazyList_cmp
+        {
+            typedef cc::lazy_list::stat<> stat;
+        };
+        typedef cc::LazyKVList< cds::gc::HP, Key, Value, traits_LazyList_cmp_stat > LazyList_HP_cmp_stat;
+        typedef cc::LazyKVList< cds::gc::DHP, Key, Value, traits_LazyList_cmp_stat > LazyList_DHP_cmp_stat;
+        typedef cc::LazyKVList< cds::gc::nogc, Key, Value, traits_LazyList_cmp_stat > LazyList_NOGC_cmp_stat;
+        typedef cc::LazyKVList< rcu_gpi, Key, Value, traits_LazyList_cmp_stat > LazyList_RCU_GPI_cmp_stat;
+        typedef cc::LazyKVList< rcu_gpb, Key, Value, traits_LazyList_cmp_stat > LazyList_RCU_GPB_cmp_stat;
+        typedef cc::LazyKVList< rcu_gpt, Key, Value, traits_LazyList_cmp_stat > LazyList_RCU_GPT_cmp_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::LazyKVList< rcu_shb, Key, Value, traits_LazyList_cmp_stat > LazyList_RCU_SHB_cmp_stat;
+#endif
+
+        struct traits_LazyList_unord :
+            public cc::lazy_list::make_traits<
+                co::equal_to< equal_to >
+                ,co::sort< false >
+            >::type
+        {};
+        typedef cc::LazyKVList< cds::gc::nogc, Key, Value, traits_LazyList_unord > LazyList_NOGC_unord;
+
+        struct traits_LazyList_cmp_seqcst :
+            public cc::lazy_list::make_traits<
+                co::compare< compare >
+                ,co::memory_model< co::v::sequential_consistent >
+            >::type
+        {};
+        typedef cc::LazyKVList< cds::gc::HP, Key, Value, traits_LazyList_cmp_seqcst > LazyList_HP_cmp_seqcst;
+        typedef cc::LazyKVList< cds::gc::DHP, Key, Value, traits_LazyList_cmp_seqcst > LazyList_DHP_cmp_seqcst;
+        typedef cc::LazyKVList< cds::gc::nogc, Key, Value, traits_LazyList_cmp_seqcst > LazyList_NOGC_cmp_seqcst;
+        typedef cc::LazyKVList< rcu_gpi, Key, Value, traits_LazyList_cmp_seqcst > LazyList_RCU_GPI_cmp_seqcst;
+        typedef cc::LazyKVList< rcu_gpb, Key, Value, traits_LazyList_cmp_seqcst > LazyList_RCU_GPB_cmp_seqcst;
+        typedef cc::LazyKVList< rcu_gpt, Key, Value, traits_LazyList_cmp_seqcst > LazyList_RCU_GPT_cmp_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::LazyKVList< rcu_shb, Key, Value, traits_LazyList_cmp_seqcst > LazyList_RCU_SHB_cmp_seqcst;
+#endif
+
+        struct traits_LazyList_less :
+            public cc::lazy_list::make_traits<
+                co::less< less >
+            >::type
+        {};
+        typedef cc::LazyKVList< cds::gc::HP, Key, Value, traits_LazyList_less > LazyList_HP_less;
+        typedef cc::LazyKVList< cds::gc::DHP, Key, Value, traits_LazyList_less > LazyList_DHP_less;
+        typedef cc::LazyKVList< cds::gc::nogc, Key, Value, traits_LazyList_less > LazyList_NOGC_less;
+        typedef cc::LazyKVList< rcu_gpi, Key, Value, traits_LazyList_less > LazyList_RCU_GPI_less;
+        typedef cc::LazyKVList< rcu_gpb, Key, Value, traits_LazyList_less > LazyList_RCU_GPB_less;
+        typedef cc::LazyKVList< rcu_gpt, Key, Value, traits_LazyList_less > LazyList_RCU_GPT_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::LazyKVList< rcu_shb, Key, Value, traits_LazyList_less > LazyList_RCU_SHB_less;
+#endif
+
+        struct traits_LazyList_less_stat: public traits_LazyList_less
+        {
+            typedef cc::lazy_list::stat<> stat;
+        };
+        typedef cc::LazyKVList< cds::gc::HP, Key, Value, traits_LazyList_less_stat > LazyList_HP_less_stat;
+        typedef cc::LazyKVList< cds::gc::DHP, Key, Value, traits_LazyList_less_stat > LazyList_DHP_less_stat;
+        typedef cc::LazyKVList< cds::gc::nogc, Key, Value, traits_LazyList_less_stat > LazyList_NOGC_less_stat;
+        typedef cc::LazyKVList< rcu_gpi, Key, Value, traits_LazyList_less_stat > LazyList_RCU_GPI_less_stat;
+        typedef cc::LazyKVList< rcu_gpb, Key, Value, traits_LazyList_less_stat > LazyList_RCU_GPB_less_stat;
+        typedef cc::LazyKVList< rcu_gpt, Key, Value, traits_LazyList_less_stat > LazyList_RCU_GPT_less_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::LazyKVList< rcu_shb, Key, Value, traits_LazyList_less_stat > LazyList_RCU_SHB_less_stat;
+#endif
+
+        struct traits_LazyList_less_seqcst :
+            public cc::lazy_list::make_traits<
+                co::less< less >
+                ,co::memory_model< co::v::sequential_consistent >
+            >::type
+        {};
+        typedef cc::LazyKVList< cds::gc::HP, Key, Value, traits_LazyList_less_seqcst > LazyList_HP_less_seqcst;
+        typedef cc::LazyKVList< cds::gc::DHP, Key, Value, traits_LazyList_less_seqcst > LazyList_DHP_less_seqcst;
+        typedef cc::LazyKVList< cds::gc::nogc, Key, Value, traits_LazyList_less_seqcst > LazyList_NOGC_less_seqcst;
+        typedef cc::LazyKVList< rcu_gpi, Key, Value, traits_LazyList_less_seqcst > LazyList_RCU_GPI_less_seqcst;
+        typedef cc::LazyKVList< rcu_gpb, Key, Value, traits_LazyList_less_seqcst > LazyList_RCU_GPB_less_seqcst;
+        typedef cc::LazyKVList< rcu_gpt, Key, Value, traits_LazyList_less_seqcst > LazyList_RCU_GPT_less_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::LazyKVList< rcu_shb, Key, Value, traits_LazyList_less_seqcst > LazyList_RCU_SHB_less_seqcst;
+#endif
+
+    };
+
+} // namespace map
+
+#endif // ifndef CDSUNIT_MAP_TYPE_LAZY_LIST_H
diff --git a/test/stress/sequential/sequential-map/map_type_michael.h b/test/stress/sequential/sequential-map/map_type_michael.h
new file mode 100644 (file)
index 0000000..a07e463
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_MICHAEL_H
+#define CDSUNIT_MAP_TYPE_MICHAEL_H
+
+#include "map_type_michael_list.h"
+#include "map_type_lazy_list.h"
+#include "map_type_iterable_list.h"
+
+#include <cds/container/michael_map.h>
+#include <cds/container/michael_map_rcu.h>
+#include <cds/container/michael_map_nogc.h>
+
+namespace map {
+
+    template <class GC, typename List, typename Traits = cc::michael_map::traits>
+    class MichaelHashMap : public cc::MichaelHashMap< GC, List, Traits >
+    {
+        typedef cc::MichaelHashMap< GC, List, Traits > base_class;
+    public:
+        template <typename Config>
+        MichaelHashMap( Config const& cfg)
+            : base_class( cfg.s_nMapSize, cfg.s_nLoadFactor )
+        {}
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+        get_begin()
+        {
+            return base_class::begin();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+        get_end()
+        {
+            return base_class::end();
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = true;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = true;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    struct tag_MichaelHashMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_MichaelHashMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value > base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+        typedef typename base_class::equal_to    equal_to;
+        typedef typename base_class::key_hash    hash;
+
+        struct traits_MichaelMap_hash :
+            public cc::michael_map::make_traits<
+                co::hash< hash >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+
+        // ***************************************************************************
+        // MichaelHashMap based on MichaelKVList
+        typedef michael_list_type< Key, Value > ml;
+
+        typedef MichaelHashMap< cds::gc::HP,  typename ml::MichaelList_HP_cmp,  traits_MichaelMap_hash > MichaelMap_HP_cmp;
+        typedef MichaelHashMap< cds::gc::DHP, typename ml::MichaelList_DHP_cmp, traits_MichaelMap_hash > MichaelMap_DHP_cmp;
+        typedef MichaelHashMap< cds::gc::nogc, typename ml::MichaelList_NOGC_cmp, traits_MichaelMap_hash > MichaelMap_NOGC_cmp;
+        typedef MichaelHashMap< rcu_gpi, typename ml::MichaelList_RCU_GPI_cmp, traits_MichaelMap_hash > MichaelMap_RCU_GPI_cmp;
+        typedef MichaelHashMap< rcu_gpb, typename ml::MichaelList_RCU_GPB_cmp, traits_MichaelMap_hash > MichaelMap_RCU_GPB_cmp;
+        typedef MichaelHashMap< rcu_gpt, typename ml::MichaelList_RCU_GPT_cmp, traits_MichaelMap_hash > MichaelMap_RCU_GPT_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ml::MichaelList_RCU_SHB_cmp, traits_MichaelMap_hash > MichaelMap_RCU_SHB_cmp;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ml::MichaelList_HP_cmp_stat, traits_MichaelMap_hash > MichaelMap_HP_cmp_stat;
+        typedef MichaelHashMap< cds::gc::DHP, typename ml::MichaelList_DHP_cmp_stat, traits_MichaelMap_hash > MichaelMap_DHP_cmp_stat;
+        typedef MichaelHashMap< cds::gc::nogc, typename ml::MichaelList_NOGC_cmp_stat, traits_MichaelMap_hash > MichaelMap_NOGC_cmp_stat;
+        typedef MichaelHashMap< rcu_gpi, typename ml::MichaelList_RCU_GPI_cmp_stat, traits_MichaelMap_hash > MichaelMap_RCU_GPI_cmp_stat;
+        typedef MichaelHashMap< rcu_gpb, typename ml::MichaelList_RCU_GPB_cmp_stat, traits_MichaelMap_hash > MichaelMap_RCU_GPB_cmp_stat;
+        typedef MichaelHashMap< rcu_gpt, typename ml::MichaelList_RCU_GPT_cmp_stat, traits_MichaelMap_hash > MichaelMap_RCU_GPT_cmp_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ml::MichaelList_RCU_SHB_cmp_stat, traits_MichaelMap_hash > MichaelMap_RCU_SHB_cmp_stat;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ml::MichaelList_HP_less, traits_MichaelMap_hash > MichaelMap_HP_less;
+        typedef MichaelHashMap< cds::gc::DHP, typename ml::MichaelList_DHP_less, traits_MichaelMap_hash > MichaelMap_DHP_less;
+        typedef MichaelHashMap< cds::gc::nogc, typename ml::MichaelList_NOGC_less, traits_MichaelMap_hash > MichaelMap_NOGC_less;
+        typedef MichaelHashMap< rcu_gpi, typename ml::MichaelList_RCU_GPI_less, traits_MichaelMap_hash > MichaelMap_RCU_GPI_less;
+        typedef MichaelHashMap< rcu_gpb, typename ml::MichaelList_RCU_GPB_less, traits_MichaelMap_hash > MichaelMap_RCU_GPB_less;
+        typedef MichaelHashMap< rcu_gpt, typename ml::MichaelList_RCU_GPT_less, traits_MichaelMap_hash > MichaelMap_RCU_GPT_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ml::MichaelList_RCU_SHB_less, traits_MichaelMap_hash > MichaelMap_RCU_SHB_less;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ml::MichaelList_HP_less_stat, traits_MichaelMap_hash > MichaelMap_HP_less_stat;
+        typedef MichaelHashMap< cds::gc::DHP, typename ml::MichaelList_DHP_less_stat, traits_MichaelMap_hash > MichaelMap_DHP_less_stat;
+        typedef MichaelHashMap< cds::gc::nogc, typename ml::MichaelList_NOGC_less_stat, traits_MichaelMap_hash > MichaelMap_NOGC_less_stat;
+        typedef MichaelHashMap< rcu_gpi, typename ml::MichaelList_RCU_GPI_less_stat, traits_MichaelMap_hash > MichaelMap_RCU_GPI_less_stat;
+        typedef MichaelHashMap< rcu_gpb, typename ml::MichaelList_RCU_GPB_less_stat, traits_MichaelMap_hash > MichaelMap_RCU_GPB_less_stat;
+        typedef MichaelHashMap< rcu_gpt, typename ml::MichaelList_RCU_GPT_less_stat, traits_MichaelMap_hash > MichaelMap_RCU_GPT_less_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ml::MichaelList_RCU_SHB_less_stat, traits_MichaelMap_hash > MichaelMap_RCU_SHB_less_stat;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ml::MichaelList_HP_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_HP_cmp_seqcst;
+        typedef MichaelHashMap< cds::gc::DHP, typename ml::MichaelList_DHP_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_DHP_cmp_seqcst;
+        typedef MichaelHashMap< cds::gc::nogc, typename ml::MichaelList_NOGC_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_NOGC_cmp_seqcst;
+        typedef MichaelHashMap< rcu_gpi, typename ml::MichaelList_RCU_GPI_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_GPI_cmp_seqcst;
+        typedef MichaelHashMap< rcu_gpb, typename ml::MichaelList_RCU_GPB_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_GPB_cmp_seqcst;
+        typedef MichaelHashMap< rcu_gpt, typename ml::MichaelList_RCU_GPT_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_GPT_cmp_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ml::MichaelList_RCU_SHB_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_SHB_cmp_seqcst;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ml::MichaelList_HP_less_seqcst, traits_MichaelMap_hash > MichaelMap_HP_less_seqcst;
+        typedef MichaelHashMap< cds::gc::DHP, typename ml::MichaelList_DHP_less_seqcst, traits_MichaelMap_hash > MichaelMap_DHP_less_seqcst;
+        typedef MichaelHashMap< cds::gc::nogc, typename ml::MichaelList_NOGC_less_seqcst, traits_MichaelMap_hash > MichaelMap_NOGC_less_seqcst;
+        typedef MichaelHashMap< rcu_gpi, typename ml::MichaelList_RCU_GPI_less_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_GPI_less_seqcst;
+        typedef MichaelHashMap< rcu_gpb, typename ml::MichaelList_RCU_GPB_less_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_GPB_less_seqcst;
+        typedef MichaelHashMap< rcu_gpt, typename ml::MichaelList_RCU_GPT_less_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_GPT_less_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ml::MichaelList_RCU_SHB_less_seqcst, traits_MichaelMap_hash > MichaelMap_RCU_SHB_less_seqcst;
+#endif
+
+
+        // ***************************************************************************
+        // MichaelHashMap based on LazyKVList
+        typedef lazy_list_type< Key, Value > ll;
+
+        typedef MichaelHashMap< cds::gc::HP, typename ll::LazyList_HP_cmp, traits_MichaelMap_hash > MichaelMap_Lazy_HP_cmp;
+        typedef MichaelHashMap< cds::gc::DHP, typename ll::LazyList_DHP_cmp, traits_MichaelMap_hash > MichaelMap_Lazy_DHP_cmp;
+        typedef MichaelHashMap< cds::gc::nogc, typename ll::LazyList_NOGC_cmp, traits_MichaelMap_hash > MichaelMap_Lazy_NOGC_cmp;
+        typedef MichaelHashMap< rcu_gpi, typename ll::LazyList_RCU_GPI_cmp, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPI_cmp;
+        typedef MichaelHashMap< rcu_gpb, typename ll::LazyList_RCU_GPB_cmp, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPB_cmp;
+        typedef MichaelHashMap< rcu_gpt, typename ll::LazyList_RCU_GPT_cmp, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPT_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ll::LazyList_RCU_SHB_cmp, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_SHB_cmp;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ll::LazyList_HP_cmp_stat, traits_MichaelMap_hash > MichaelMap_Lazy_HP_cmp_stat;
+        typedef MichaelHashMap< cds::gc::DHP, typename ll::LazyList_DHP_cmp_stat, traits_MichaelMap_hash > MichaelMap_Lazy_DHP_cmp_stat;
+        typedef MichaelHashMap< cds::gc::nogc, typename ll::LazyList_NOGC_cmp_stat, traits_MichaelMap_hash > MichaelMap_Lazy_NOGC_cmp_stat;
+        typedef MichaelHashMap< rcu_gpi, typename ll::LazyList_RCU_GPI_cmp_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPI_cmp_stat;
+        typedef MichaelHashMap< rcu_gpb, typename ll::LazyList_RCU_GPB_cmp_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPB_cmp_stat;
+        typedef MichaelHashMap< rcu_gpt, typename ll::LazyList_RCU_GPT_cmp_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPT_cmp_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ll::LazyList_RCU_SHB_cmp_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_SHB_cmp_stat;
+#endif
+
+        typedef MichaelHashMap< cds::gc::nogc, typename ll::LazyList_NOGC_unord, traits_MichaelMap_hash > MichaelMap_Lazy_NOGC_unord;
+
+        typedef MichaelHashMap< cds::gc::HP, typename ll::LazyList_HP_less, traits_MichaelMap_hash > MichaelMap_Lazy_HP_less;
+        typedef MichaelHashMap< cds::gc::DHP, typename ll::LazyList_DHP_less, traits_MichaelMap_hash > MichaelMap_Lazy_DHP_less;
+        typedef MichaelHashMap< cds::gc::nogc, typename ll::LazyList_NOGC_less, traits_MichaelMap_hash > MichaelMap_Lazy_NOGC_less;
+        typedef MichaelHashMap< rcu_gpi, typename ll::LazyList_RCU_GPI_less, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPI_less;
+        typedef MichaelHashMap< rcu_gpb, typename ll::LazyList_RCU_GPB_less, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPB_less;
+        typedef MichaelHashMap< rcu_gpt, typename ll::LazyList_RCU_GPT_less, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPT_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ll::LazyList_RCU_SHB_less, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_SHB_less;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ll::LazyList_HP_less_stat, traits_MichaelMap_hash > MichaelMap_Lazy_HP_less_stat;
+        typedef MichaelHashMap< cds::gc::DHP, typename ll::LazyList_DHP_less_stat, traits_MichaelMap_hash > MichaelMap_Lazy_DHP_less_stat;
+        typedef MichaelHashMap< cds::gc::nogc, typename ll::LazyList_NOGC_less_stat, traits_MichaelMap_hash > MichaelMap_Lazy_NOGC_less_stat;
+        typedef MichaelHashMap< rcu_gpi, typename ll::LazyList_RCU_GPI_less_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPI_less_stat;
+        typedef MichaelHashMap< rcu_gpb, typename ll::LazyList_RCU_GPB_less_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPB_less_stat;
+        typedef MichaelHashMap< rcu_gpt, typename ll::LazyList_RCU_GPT_less_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPT_less_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ll::LazyList_RCU_SHB_less_stat, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_SHB_less_stat;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ll::LazyList_HP_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_HP_cmp_seqcst;
+        typedef MichaelHashMap< cds::gc::DHP, typename ll::LazyList_DHP_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_DHP_cmp_seqcst;
+        typedef MichaelHashMap< cds::gc::nogc, typename ll::LazyList_NOGC_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_NOGC_cmp_seqcst;
+        typedef MichaelHashMap< rcu_gpi, typename ll::LazyList_RCU_GPI_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPI_cmp_seqcst;
+        typedef MichaelHashMap< rcu_gpb, typename ll::LazyList_RCU_GPB_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPB_cmp_seqcst;
+        typedef MichaelHashMap< rcu_gpt, typename ll::LazyList_RCU_GPT_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPT_cmp_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ll::LazyList_RCU_SHB_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_SHB_cmp_seqcst;
+#endif
+
+        typedef MichaelHashMap< cds::gc::HP, typename ll::LazyList_HP_less_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_HP_less_seqcst;
+        typedef MichaelHashMap< cds::gc::DHP, typename ll::LazyList_DHP_less_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_DHP_less_seqcst;
+        typedef MichaelHashMap< cds::gc::nogc, typename ll::LazyList_NOGC_less_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_NOGC_less_seqcst;
+        typedef MichaelHashMap< rcu_gpi, typename ll::LazyList_RCU_GPI_less_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPI_less_seqcst;
+        typedef MichaelHashMap< rcu_gpb, typename ll::LazyList_RCU_GPB_less_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPB_less_seqcst;
+        typedef MichaelHashMap< rcu_gpt, typename ll::LazyList_RCU_GPT_less_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_GPT_less_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef MichaelHashMap< rcu_shb, typename ll::LazyList_RCU_SHB_less_seqcst, traits_MichaelMap_hash > MichaelMap_Lazy_RCU_SHB_less_seqcst;
+#endif
+
+
+        // ***************************************************************************
+        // MichaelHashMap based on IterableKVList
+        typedef iterable_list_type< Key, Value > il;
+
+        typedef MichaelHashMap< cds::gc::HP,  typename il::IterableList_HP_cmp,  traits_MichaelMap_hash > MichaelMap_Iterable_HP_cmp;
+        typedef MichaelHashMap< cds::gc::DHP, typename il::IterableList_DHP_cmp, traits_MichaelMap_hash > MichaelMap_Iterable_DHP_cmp;
+
+        typedef MichaelHashMap< cds::gc::HP, typename il::IterableList_HP_cmp_stat, traits_MichaelMap_hash > MichaelMap_Iterable_HP_cmp_stat;
+        typedef MichaelHashMap< cds::gc::DHP, typename il::IterableList_DHP_cmp_stat, traits_MichaelMap_hash > MichaelMap_Iterable_DHP_cmp_stat;
+
+        typedef MichaelHashMap< cds::gc::HP, typename il::IterableList_HP_less, traits_MichaelMap_hash > MichaelMap_Iterable_HP_less;
+        typedef MichaelHashMap< cds::gc::DHP, typename il::IterableList_DHP_less, traits_MichaelMap_hash > MichaelMap_Iterable_DHP_less;
+
+        typedef MichaelHashMap< cds::gc::HP, typename il::IterableList_HP_less_stat, traits_MichaelMap_hash > MichaelMap_Iterable_HP_less_stat;
+        typedef MichaelHashMap< cds::gc::DHP, typename il::IterableList_DHP_less_stat, traits_MichaelMap_hash > MichaelMap_Iterable_DHP_less_stat;
+
+        typedef MichaelHashMap< cds::gc::HP, typename il::IterableList_HP_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Iterable_HP_cmp_seqcst;
+        typedef MichaelHashMap< cds::gc::DHP, typename il::IterableList_DHP_cmp_seqcst, traits_MichaelMap_hash > MichaelMap_Iterable_DHP_cmp_seqcst;
+
+    };
+}   // namespace map
+
+#define CDSSTRESS_MichaelMap_case( fixture, test_case, michael_map_type, key_type, value_type ) \
+    TEST_P( fixture, michael_map_type ) \
+    { \
+        typedef map::map_type< tag_MichaelHashMap, key_type, value_type >::michael_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 1
+#   define CDSSTRESS_MichaelMap_SHRCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_MichaelMap_SHRCU_2( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL == 1
+#   define CDSSTRESS_MichaelMap_SHRCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_SHT_cmp,              key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_SHB_less,             key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_SHT_cmp,         key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_SHB_less,        key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_MichaelMap_SHRCU_1( fixture, test_case, key_type, value_type )
+#endif
+
+#   define CDSSTRESS_MichaelMap_SHRCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_SHB_cmp,              key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_SHT_less,             key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_SHB_cmp,         key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_SHT_less,        key_type, value_type ) \
+        CDSSTRESS_MichaelMap_SHRCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_SHRCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_MichaelMap_SHRCU( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 1
+#   define  CDSSTRESS_MichaelMap_HP_2( fixture, test_case, key_type, value_type ) \
+
+#   define  CDSSTRESS_MichaelMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#   define  CDSSTRESS_MichaelMap_2( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_HP_2( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define  CDSSTRESS_MichaelMap_HP_2( fixture, test_case, key_type, value_type )
+#   define  CDSSTRESS_MichaelMap_RCU_2( fixture, test_case, key_type, value_type )
+#   define  CDSSTRESS_MichaelMap_2( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL == 1
+
+#   define CDSSTRESS_MichaelMap_Iterable_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Iterable_DHP_cmp,            key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Iterable_HP_less,            key_type, value_type ) \
+
+#   define CDSSTRESS_MichaelMap_HP_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_DHP_cmp,                     key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_HP_less,                     key_type, value_type ) \
+        \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_DHP_cmp,                key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_HP_less,                key_type, value_type ) \
+
+#   define  CDSSTRESS_MichaelMap_RCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_GPB_cmp,                 key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_GPI_less,                key_type, value_type ) \
+        \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_GPB_cmp,            key_type, value_type ) \
+        CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_GPI_less,           key_type, value_type ) \
+        \
+        CDSSTRESS_MichaelMap_SHRCU( fixture, test_case, key_type, value_type ) \
+
+#   define  CDSSTRESS_MichaelMap_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_HP_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_MichaelMap_RCU_1( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_MichaelMap_Iterable_1( fixture, test_case, key_type, value_type )
+#   define  CDSSTRESS_MichaelMap_HP_1( fixture, test_case, key_type, value_type )
+#   define  CDSSTRESS_MichaelMap_RCU_1( fixture, test_case, key_type, value_type )
+#   define  CDSSTRESS_MichaelMap_1( fixture, test_case, key_type, value_type )
+#endif
+
+#define CDSSTRESS_MichaelMap_Iterable( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Iterable_HP_cmp,             key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Iterable_DHP_less,           key_type, value_type ) \
+    CDSSTRESS_MichaelMap_Iterable_1( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_MichaelMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_HP_cmp,                      key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_DHP_less,                    key_type, value_type ) \
+    \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_HP_cmp,                 key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_DHP_less,               key_type, value_type ) \
+    \
+    CDSSTRESS_MichaelMap_Iterable( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_HP_1( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_HP_2( fixture, test_case, key_type, value_type ) \
+
+
+#define CDSSTRESS_MichaelMap_RCU( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_GPI_cmp,                 key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_RCU_GPB_less,                key_type, value_type ) \
+    \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_GPI_cmp,            key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_RCU_GPB_less,           key_type, value_type ) \
+    \
+    CDSSTRESS_MichaelMap_RCU_1( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_MichaelMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_RCU( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_MichaelMap_nogc( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_NOGC_cmp,                    key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_NOGC_less,                   key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_NOGC_cmp,               key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_NOGC_unord,             key_type, value_type ) \
+    CDSSTRESS_MichaelMap_case( fixture, test_case, MichaelMap_Lazy_NOGC_less,              key_type, value_type ) \
+
+
+#endif // ifndef CDSUNIT_MAP_TYPE_MICHAEL_H
diff --git a/test/stress/sequential/sequential-map/map_type_michael_list.h b/test/stress/sequential/sequential-map/map_type_michael_list.h
new file mode 100644 (file)
index 0000000..e09a3b7
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_MICHAEL_LIST_H
+#define CDSUNIT_MAP_TYPE_MICHAEL_LIST_H
+
+#include "map_type.h"
+
+#include <cds/container/michael_kvlist_hp.h>
+#include <cds/container/michael_kvlist_dhp.h>
+#include <cds/container/michael_kvlist_rcu.h>
+#include <cds/container/michael_kvlist_nogc.h>
+
+#include <cds_test/stat_michael_list_out.h>
+
+namespace map {
+
+    template <typename Key, typename Value>
+    struct michael_list_type
+    {
+        typedef typename map_type_base<Key, Value>::key_compare compare;
+        typedef typename map_type_base<Key, Value>::key_less    less;
+
+        struct traits_MichaelList_cmp :
+            public cc::michael_list::make_traits<
+                co::compare< compare >
+            >::type
+        {};
+        typedef cc::MichaelKVList< cds::gc::HP,  Key, Value, traits_MichaelList_cmp > MichaelList_HP_cmp;
+        typedef cc::MichaelKVList< cds::gc::DHP, Key, Value, traits_MichaelList_cmp > MichaelList_DHP_cmp;
+        typedef cc::MichaelKVList< cds::gc::nogc, Key, Value, traits_MichaelList_cmp > MichaelList_NOGC_cmp;
+        typedef cc::MichaelKVList< rcu_gpi, Key, Value, traits_MichaelList_cmp > MichaelList_RCU_GPI_cmp;
+        typedef cc::MichaelKVList< rcu_gpb, Key, Value, traits_MichaelList_cmp > MichaelList_RCU_GPB_cmp;
+        typedef cc::MichaelKVList< rcu_gpt, Key, Value, traits_MichaelList_cmp > MichaelList_RCU_GPT_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::MichaelKVList< rcu_shb, Key, Value, traits_MichaelList_cmp > MichaelList_RCU_SHB_cmp;
+#endif
+
+        struct traits_MichaelList_cmp_stat : public traits_MichaelList_cmp
+        {
+            typedef cc::michael_list::stat<> stat;
+        };
+        typedef cc::MichaelKVList< cds::gc::HP,  Key, Value, traits_MichaelList_cmp_stat > MichaelList_HP_cmp_stat;
+        typedef cc::MichaelKVList< cds::gc::DHP, Key, Value, traits_MichaelList_cmp_stat > MichaelList_DHP_cmp_stat;
+        typedef cc::MichaelKVList< cds::gc::nogc, Key, Value, traits_MichaelList_cmp_stat > MichaelList_NOGC_cmp_stat;
+        typedef cc::MichaelKVList< rcu_gpi, Key, Value, traits_MichaelList_cmp_stat > MichaelList_RCU_GPI_cmp_stat;
+        typedef cc::MichaelKVList< rcu_gpb, Key, Value, traits_MichaelList_cmp_stat > MichaelList_RCU_GPB_cmp_stat;
+        typedef cc::MichaelKVList< rcu_gpt, Key, Value, traits_MichaelList_cmp_stat > MichaelList_RCU_GPT_cmp_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::MichaelKVList< rcu_shb, Key, Value, traits_MichaelList_cmp_stat > MichaelList_RCU_SHB_cmp_stat;
+#endif
+
+        struct traits_MichaelList_cmp_seqcst :
+            public cc::michael_list::make_traits<
+                co::compare< compare >
+                ,co::memory_model< co::v::sequential_consistent >
+            >::type
+        {};
+        typedef cc::MichaelKVList< cds::gc::HP,  Key, Value, traits_MichaelList_cmp_seqcst > MichaelList_HP_cmp_seqcst;
+        typedef cc::MichaelKVList< cds::gc::DHP, Key, Value, traits_MichaelList_cmp_seqcst > MichaelList_DHP_cmp_seqcst;
+        typedef cc::MichaelKVList< cds::gc::nogc, Key, Value, traits_MichaelList_cmp_seqcst > MichaelList_NOGC_cmp_seqcst;
+        typedef cc::MichaelKVList< rcu_gpi, Key, Value, traits_MichaelList_cmp_seqcst > MichaelList_RCU_GPI_cmp_seqcst;
+        typedef cc::MichaelKVList< rcu_gpb, Key, Value, traits_MichaelList_cmp_seqcst > MichaelList_RCU_GPB_cmp_seqcst;
+        typedef cc::MichaelKVList< rcu_gpt, Key, Value, traits_MichaelList_cmp_seqcst > MichaelList_RCU_GPT_cmp_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::MichaelKVList< rcu_shb, Key, Value, traits_MichaelList_cmp_seqcst > MichaelList_RCU_SHB_cmp_seqcst;
+#endif
+
+        struct traits_MichaelList_less :
+            public cc::michael_list::make_traits<
+                co::less< less >
+            >::type
+        {};
+        typedef cc::MichaelKVList< cds::gc::HP,  Key, Value, traits_MichaelList_less > MichaelList_HP_less;
+        typedef cc::MichaelKVList< cds::gc::DHP, Key, Value, traits_MichaelList_less > MichaelList_DHP_less;
+        typedef cc::MichaelKVList< cds::gc::nogc, Key, Value, traits_MichaelList_less > MichaelList_NOGC_less;
+        typedef cc::MichaelKVList< rcu_gpi, Key, Value, traits_MichaelList_less > MichaelList_RCU_GPI_less;
+        typedef cc::MichaelKVList< rcu_gpb, Key, Value, traits_MichaelList_less > MichaelList_RCU_GPB_less;
+        typedef cc::MichaelKVList< rcu_gpt, Key, Value, traits_MichaelList_less > MichaelList_RCU_GPT_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::MichaelKVList< rcu_shb, Key, Value, traits_MichaelList_less > MichaelList_RCU_SHB_less;
+#endif
+
+        struct traits_MichaelList_less_stat: public traits_MichaelList_less
+        {
+            typedef cc::michael_list::stat<> stat;
+        };
+        typedef cc::MichaelKVList< cds::gc::HP, Key, Value, traits_MichaelList_less_stat > MichaelList_HP_less_stat;
+        typedef cc::MichaelKVList< cds::gc::DHP, Key, Value, traits_MichaelList_less_stat > MichaelList_DHP_less_stat;
+        typedef cc::MichaelKVList< cds::gc::nogc, Key, Value, traits_MichaelList_less_stat > MichaelList_NOGC_less_stat;
+        typedef cc::MichaelKVList< rcu_gpi, Key, Value, traits_MichaelList_less_stat > MichaelList_RCU_GPI_less_stat;
+        typedef cc::MichaelKVList< rcu_gpb, Key, Value, traits_MichaelList_less_stat > MichaelList_RCU_GPB_less_stat;
+        typedef cc::MichaelKVList< rcu_gpt, Key, Value, traits_MichaelList_less_stat > MichaelList_RCU_GPT_less_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::MichaelKVList< rcu_shb, Key, Value, traits_MichaelList_less_stat > MichaelList_RCU_SHB_less_stat;
+#endif
+
+        struct traits_MichaelList_less_seqcst :
+            public cc::michael_list::make_traits<
+                co::less< less >
+                ,co::memory_model< co::v::sequential_consistent >
+            >::type
+        {};
+        typedef cc::MichaelKVList< cds::gc::HP,  Key, Value, traits_MichaelList_less_seqcst > MichaelList_HP_less_seqcst;
+        typedef cc::MichaelKVList< cds::gc::DHP, Key, Value, traits_MichaelList_less_seqcst > MichaelList_DHP_less_seqcst;
+        typedef cc::MichaelKVList< cds::gc::nogc, Key, Value, traits_MichaelList_less_seqcst > MichaelList_NOGC_less_seqcst;
+        typedef cc::MichaelKVList< rcu_gpi, Key, Value, traits_MichaelList_less_seqcst > MichaelList_RCU_GPI_less_seqcst;
+        typedef cc::MichaelKVList< rcu_gpb, Key, Value, traits_MichaelList_less_seqcst > MichaelList_RCU_GPB_less_seqcst;
+        typedef cc::MichaelKVList< rcu_gpt, Key, Value, traits_MichaelList_less_seqcst > MichaelList_RCU_GPT_less_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef cc::MichaelKVList< rcu_shb, Key, Value, traits_MichaelList_less_seqcst > MichaelList_RCU_SHB_less_seqcst;
+#endif
+
+    };
+
+} // namespace map
+
+#endif // ifndef CDSUNIT_MAP_TYPE_MICHAEL_LIST_H
diff --git a/test/stress/sequential/sequential-map/map_type_skip_list.h b/test/stress/sequential/sequential-map/map_type_skip_list.h
new file mode 100644 (file)
index 0000000..b56f14e
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_SKIP_LIST_H
+#define CDSUNIT_MAP_TYPE_SKIP_LIST_H
+
+#include "map_type.h"
+
+#include <cds/container/skip_list_map_hp.h>
+#include <cds/container/skip_list_map_dhp.h>
+#include <cds/container/skip_list_map_rcu.h>
+#include <cds/container/skip_list_map_nogc.h>
+
+#include <cds_test/stat_skiplist_out.h>
+
+namespace map {
+
+    template <class GC, typename Key, typename T, typename Traits = cc::skip_list::traits >
+    class SkipListMap : public cc::SkipListMap< GC, Key, T, Traits >
+    {
+        typedef cc::SkipListMap< GC, Key, T, Traits > base_class;
+    public:
+        template <typename Config>
+        SkipListMap( Config const& /*cfg*/)
+            : base_class()
+        {}
+
+        std::pair<Key, bool> extract_min_key()
+        {
+            auto xp = base_class::extract_min();
+            if ( xp )
+                return std::make_pair( xp->first, true );
+            return std::make_pair( Key(), false );
+        }
+
+        std::pair<Key, bool> extract_max_key()
+        {
+            auto xp = base_class::extract_max();
+            if ( xp )
+                return std::make_pair( xp->first, true );
+            return std::make_pair( Key(), false );
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = true;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    struct tag_SkipListMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_SkipListMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value >      base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+
+        class traits_SkipListMap_less_turbo32: public cc::skip_list::make_traits <
+                co::less< less >
+                ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_hp_less_turbo32;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_dhp_less_turbo32;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_nogc_less_turbo32;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_rcu_gpi_less_turbo32;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_rcu_gpb_less_turbo32;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_rcu_gpt_less_turbo32;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_rcu_shb_less_turbo32;
+#endif
+
+        class traits_SkipListMap_less_turbo24: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::turbo24 >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_hp_less_turbo24;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_dhp_less_turbo24;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_nogc_less_turbo24;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_rcu_gpi_less_turbo24;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_rcu_gpb_less_turbo24;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_rcu_gpt_less_turbo24;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_rcu_shb_less_turbo24;
+#endif
+
+        class traits_SkipListMap_less_turbo16: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::turbo16 >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_hp_less_turbo16;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_dhp_less_turbo16;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_nogc_less_turbo16;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_rcu_gpi_less_turbo16;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_rcu_gpb_less_turbo16;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_rcu_gpt_less_turbo16;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_rcu_shb_less_turbo16;
+#endif
+
+        class traits_SkipListMap_less_turbo32_seqcst: public cc::skip_list::make_traits <
+                co::less< less >
+                ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
+                ,co::memory_model< co::v::sequential_consistent >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_hp_less_turbo32_seqcst;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_dhp_less_turbo32_seqcst;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_nogc_less_turbo32_seqcst;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_rcu_gpi_less_turbo32_seqcst;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_rcu_gpb_less_turbo32_seqcst;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_rcu_gpt_less_turbo32_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_rcu_shb_less_turbo32_seqcst;
+#endif
+
+        class traits_SkipListMap_less_turbo32_stat: public cc::skip_list::make_traits <
+                co::less< less >
+                ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
+                ,co::stat< cc::skip_list::stat<> >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_hp_less_turbo32_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_dhp_less_turbo32_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_nogc_less_turbo32_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_rcu_gpi_less_turbo32_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_rcu_gpb_less_turbo32_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_rcu_gpt_less_turbo32_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_rcu_shb_less_turbo32_stat;
+#endif
+
+        class traits_SkipListMap_less_turbo24_stat: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::turbo24 >
+            , co::stat< cc::skip_list::stat<> >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_hp_less_turbo24_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_dhp_less_turbo24_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_nogc_less_turbo24_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_rcu_gpi_less_turbo24_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_rcu_gpb_less_turbo24_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_rcu_gpt_less_turbo24_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_rcu_shb_less_turbo24_stat;
+#endif
+
+        class traits_SkipListMap_less_turbo16_stat: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::turbo16 >
+            , co::stat< cc::skip_list::stat<> >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_hp_less_turbo16_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_dhp_less_turbo16_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_nogc_less_turbo16_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_rcu_gpi_less_turbo16_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_rcu_gpb_less_turbo16_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_rcu_gpt_less_turbo16_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_rcu_shb_less_turbo16_stat;
+#endif
+
+        class traits_SkipListMap_cmp_turbo32: public cc::skip_list::make_traits <
+                co::compare< compare >
+                ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_hp_cmp_turbo32;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_dhp_cmp_turbo32;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_nogc_cmp_turbo32;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_rcu_gpi_cmp_turbo32;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_rcu_gpb_cmp_turbo32;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_rcu_gpt_cmp_turbo32;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_rcu_shb_cmp_turbo32;
+#endif
+
+        class traits_SkipListMap_cmp_turbo32_stat: public cc::skip_list::make_traits <
+                co::compare< compare >
+                ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
+                ,co::stat< cc::skip_list::stat<> >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_hp_cmp_turbo32_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_dhp_cmp_turbo32_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_nogc_cmp_turbo32_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_rcu_gpi_cmp_turbo32_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_rcu_gpb_cmp_turbo32_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_rcu_gpt_cmp_turbo32_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_rcu_shb_cmp_turbo32_stat;
+#endif
+
+        class traits_SkipListMap_less_xorshift32: public cc::skip_list::make_traits <
+                co::less< less >
+                ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_hp_less_xorshift32;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_dhp_less_xorshift32;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_nogc_less_xorshift32;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_rcu_gpi_less_xorshift32;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_rcu_gpb_less_xorshift32;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_rcu_gpt_less_xorshift32;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_rcu_shb_less_xorshift32;
+#endif
+
+        class traits_SkipListMap_less_xorshift24: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::xorshift24 >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_hp_less_xorshift24;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_dhp_less_xorshift24;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_nogc_less_xorshift24;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_rcu_gpi_less_xorshift24;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_rcu_gpb_less_xorshift24;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_rcu_gpt_less_xorshift24;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_rcu_shb_less_xorshift24;
+#endif
+
+        class traits_SkipListMap_less_xorshift16: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::xorshift16 >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_hp_less_xorshift16;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_dhp_less_xorshift16;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_nogc_less_xorshift16;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_rcu_gpi_less_xorshift16;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_rcu_gpb_less_xorshift16;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_rcu_gpt_less_xorshift16;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_rcu_shb_less_xorshift16;
+#endif
+
+        class traits_SkipListMap_less_xorshift32_stat: public cc::skip_list::make_traits <
+                co::less< less >
+                ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
+                ,co::stat< cc::skip_list::stat<> >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_hp_less_xorshift32_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_dhp_less_xorshift32_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_nogc_less_xorshift32_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_rcu_gpi_less_xorshift32_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_rcu_gpb_less_xorshift32_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_rcu_gpt_less_xorshift32_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_rcu_shb_less_xorshift32_stat;
+#endif
+
+        class traits_SkipListMap_less_xorshift24_stat: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::xorshift24 >
+            , co::stat< cc::skip_list::stat<> >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_hp_less_xorshift24_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_dhp_less_xorshift24_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_nogc_less_xorshift24_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_rcu_gpi_less_xorshift24_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_rcu_gpb_less_xorshift24_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_rcu_gpt_less_xorshift24_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_rcu_shb_less_xorshift24_stat;
+#endif
+
+        class traits_SkipListMap_less_xorshift16_stat: public cc::skip_list::make_traits <
+            co::less< less >
+            , cc::skip_list::random_level_generator< cc::skip_list::xorshift16 >
+            , co::stat< cc::skip_list::stat<> >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+        >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_hp_less_xorshift16_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_dhp_less_xorshift16_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_nogc_less_xorshift16_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_rcu_gpi_less_xorshift16_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_rcu_gpb_less_xorshift16_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_rcu_gpt_less_xorshift16_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_rcu_shb_less_xorshift16_stat;
+#endif
+
+        class traits_SkipListMap_cmp_xorshift32: public cc::skip_list::make_traits <
+                co::compare< compare >
+                ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_hp_cmp_xorshift32;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_dhp_cmp_xorshift32;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_nogc_cmp_xorshift32;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_rcu_gpi_cmp_xorshift32;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_rcu_gpb_cmp_xorshift32;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_rcu_gpt_cmp_xorshift32;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_rcu_shb_cmp_xorshift32;
+#endif
+
+        class traits_SkipListMap_cmp_xorshift32_stat: public cc::skip_list::make_traits <
+                co::compare< compare >
+                ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
+                ,co::stat< cc::skip_list::stat<> >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+            >::type
+        {};
+        typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_hp_cmp_xorshift32_stat;
+        typedef SkipListMap< cds::gc::DHP, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_dhp_cmp_xorshift32_stat;
+        typedef SkipListMap< cds::gc::nogc, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_nogc_cmp_xorshift32_stat;
+        typedef SkipListMap< rcu_gpi, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_rcu_gpi_cmp_xorshift32_stat;
+        typedef SkipListMap< rcu_gpb, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_rcu_gpb_cmp_xorshift32_stat;
+        typedef SkipListMap< rcu_gpt, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_rcu_gpt_cmp_xorshift32_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SkipListMap< rcu_shb, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_rcu_shb_cmp_xorshift32_stat;
+#endif
+
+    };
+
+    template <typename GC, typename K, typename T, typename Traits >
+    static inline void print_stat( cds_test::property_stream& o, SkipListMap< GC, K, T, Traits > const& m )
+    {
+        o << m.statistics();
+    }
+
+}   // namespace map
+
+#define CDSSTRESS_SkipListMap_case( fixture, test_case, skiplist_map_type, key_type, value_type ) \
+    TEST_F( fixture, skiplist_map_type ) \
+    { \
+        typedef map::map_type< tag_SkipListMap, key_type, value_type >::skiplist_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 1
+#   define CDSSTRESS_SkipListMap_SHRCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SkipListMap_SHRCU_2( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL == 1
+#   define CDSSTRESS_SkipListMap_SHRCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_shb_cmp_turbo32,         key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_shb_cmp_xorshift32,       key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SkipListMap_SHRCU_1( fixture, test_case, key_type, value_type )
+#endif
+
+
+#   define CDSSTRESS_SkipListMap_SHRCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_shb_less_turbo32,        key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_shb_less_xorshift32,      key_type, value_type ) \
+        CDSSTRESS_SkipListMap_SHRCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_SHRCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SkipListMap_SHRCU( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 1
+#   define CDSSTRESS_SkipListMap_HP_2( fixture, test_case, key_type, value_type ) \
+
+#   define CDSSTRESS_SkipListMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#   define CDSSTRESS_SkipListMap_2( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_HP_2( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SkipListMap_HP_2( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SkipListMap_RCU_2( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SkipListMap_2( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL == 1
+#   define CDSSTRESS_SkipListMap_HP_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_dhp_less_turbo32,            key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_cmp_turbo32,              key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_dhp_less_xorshift32,          key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_cmp_xorshift32,            key_type, value_type ) \
+
+#   define CDSSTRESS_SkipListMap_RCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpb_less_turbo32,        key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpi_cmp_turbo32,         key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpb_less_xorshift32,      key_type, value_type ) \
+        CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpi_cmp_xorshift32,       key_type, value_type ) \
+        CDSSTRESS_SkipListMap_SHRCU( fixture, test_case, key_type, value_type )
+
+#   define CDSSTRESS_SkipListMap_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_HP_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SkipListMap_RCU_1( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SkipListMap_HP_1( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SkipListMap_RCU_1( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SkipListMap_1( fixture, test_case, key_type, value_type )
+#endif
+
+
+#define CDSSTRESS_SkipListMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_less_turbo32,             key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_less_turbo24,             key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_less_turbo16,             key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_dhp_cmp_turbo32,             key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_less_xorshift32,           key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_less_xorshift24,           key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_hp_less_xorshift16,           key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_dhp_cmp_xorshift32,           key_type, value_type ) \
+    CDSSTRESS_SkipListMap_HP_1( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SkipListMap_HP_2( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_SkipListMap_RCU( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpi_less_turbo32,        key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpb_cmp_turbo32,         key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpi_less_xorshift32,      key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_rcu_gpb_cmp_xorshift32,       key_type, value_type ) \
+    CDSSTRESS_SkipListMap_RCU_1( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SkipListMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_SkipListMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SkipListMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SkipListMap_RCU( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_SkipListMap_nogc( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_nogc_less_turbo32,           key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_nogc_less_turbo24,           key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_nogc_less_turbo16,           key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_nogc_cmp_turbo32,            key_type, value_type ) \
+    CDSSTRESS_SkipListMap_case( fixture, test_case, SkipListMap_nogc_cmp_xorshift32,          key_type, value_type ) \
+
+#endif // ifndef CDSUNIT_MAP_TYPE_SKIP_LIST_H
diff --git a/test/stress/sequential/sequential-map/map_type_split_list.h b/test/stress/sequential/sequential-map/map_type_split_list.h
new file mode 100644 (file)
index 0000000..2c0eefc
--- /dev/null
@@ -0,0 +1,741 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_SPLIT_LIST_H
+#define CDSUNIT_MAP_TYPE_SPLIT_LIST_H
+
+#include "map_type.h"
+
+#include <cds/container/michael_kvlist_hp.h>
+#include <cds/container/michael_kvlist_dhp.h>
+#include <cds/container/michael_kvlist_rcu.h>
+#include <cds/container/michael_kvlist_nogc.h>
+
+#include <cds/container/lazy_kvlist_hp.h>
+#include <cds/container/lazy_kvlist_dhp.h>
+#include <cds/container/lazy_kvlist_rcu.h>
+#include <cds/container/lazy_kvlist_nogc.h>
+
+#include <cds/container/iterable_kvlist_hp.h>
+#include <cds/container/iterable_kvlist_dhp.h>
+
+#include <cds/container/split_list_map.h>
+#include <cds/container/split_list_map_rcu.h>
+#include <cds/container/split_list_map_nogc.h>
+
+#include <cds_test/stat_splitlist_out.h>
+#include <cds_test/stat_michael_list_out.h>
+#include <cds_test/stat_lazy_list_out.h>
+#include <cds_test/stat_iterable_list_out.h>
+
+namespace map {
+
+    template <class GC, typename Key, typename T, typename Traits = cc::split_list::traits >
+    class SplitListMap : public cc::SplitListMap< GC, Key, T, Traits >
+    {
+        typedef cc::SplitListMap< GC, Key, T, Traits > base_class;
+    public:
+        template <typename Config>
+        SplitListMap( Config const& cfg)
+            : base_class( cfg.s_nMapSize, cfg.s_nLoadFactor )
+        {}
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+        get_begin()
+        {
+            return base_class::begin();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+        get_end()
+        {
+            return base_class::end();
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = true;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = true;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    template <typename Key, typename T, typename Traits >
+    class SplitListMap< cds::gc::nogc, Key, T, Traits> : public cc::SplitListMap< cds::gc::nogc, Key, T, Traits >
+    {
+        typedef cc::SplitListMap< cds::gc::nogc, Key, T, Traits > base_class;
+    public:
+        template <typename Config>
+        SplitListMap( Config const& cfg)
+            : base_class( cfg.s_nMapSize, cfg.s_nLoadFactor )
+        {}
+
+        template <typename K>
+        bool insert( K const& key )
+        {
+            return base_class::insert( key ) != base_class::end();
+        }
+
+        template <typename K, typename V>
+        bool insert( K const& key, V const& val )
+        {
+            return base_class::insert( key, val ) != base_class::end();
+        }
+
+        template <typename K, typename Func>
+        bool insert_with( K const& key, Func func )
+        {
+            return base_class::insert_with( key, func ) != base_class::end();
+        }
+
+        template <typename K>
+        bool find( K const& key )
+        {
+            return base_class::find( key ) != base_class::end();
+        }
+
+        void clear()
+        {}
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = true;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = true;
+    };
+
+    struct tag_SplitListMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_SplitListMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value >      base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+        typedef typename base_class::equal_to    equal_to;
+        typedef typename base_class::key_hash    hash;
+
+
+        // ***************************************************************************
+        // SplitListMap based on MichaelList
+        struct traits_SplitList_Michael_dyn_cmp: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::michael_list_tag>
+                ,co::hash< hash >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::michael_list::make_traits<
+                        co::compare< compare >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_dyn_cmp > SplitList_Michael_HP_dyn_cmp;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_dyn_cmp > SplitList_Michael_DHP_dyn_cmp;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_dyn_cmp > SplitList_Michael_NOGC_dyn_cmp;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_dyn_cmp > SplitList_Michael_RCU_GPI_dyn_cmp;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_dyn_cmp > SplitList_Michael_RCU_GPB_dyn_cmp;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_dyn_cmp > SplitList_Michael_RCU_GPT_dyn_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_dyn_cmp > SplitList_Michael_RCU_SHB_dyn_cmp;
+#endif
+
+        struct traits_SplitList_Michael_dyn_cmp_swar: public traits_SplitList_Michael_dyn_cmp
+        {
+            typedef cds::algo::bit_reversal::swar bit_reversal;
+        };
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_dyn_cmp_swar > SplitList_Michael_HP_dyn_cmp_swar;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_dyn_cmp_swar > SplitList_Michael_DHP_dyn_cmp_swar;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_dyn_cmp_swar > SplitList_Michael_NOGC_dyn_cmp_swar;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_dyn_cmp_swar > SplitList_Michael_RCU_GPI_dyn_cmp_swar;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_dyn_cmp_swar > SplitList_Michael_RCU_GPB_dyn_cmp_swar;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_dyn_cmp_swar > SplitList_Michael_RCU_GPT_dyn_cmp_swar;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_dyn_cmp_swar > SplitList_Michael_RCU_SHB_dyn_cmp_swar;
+#endif
+
+        struct traits_SplitList_Michael_dyn_cmp_stat : public traits_SplitList_Michael_dyn_cmp
+        {
+            typedef cc::split_list::stat<> stat;
+            typedef typename cc::michael_list::make_traits<
+                co::compare< compare >
+                ,co::stat< cc::michael_list::stat<> >
+            >::type ordered_list_traits;
+        };
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_dyn_cmp_stat > SplitList_Michael_HP_dyn_cmp_stat;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_dyn_cmp_stat > SplitList_Michael_DHP_dyn_cmp_stat;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_dyn_cmp_stat> SplitList_Michael_NOGC_dyn_cmp_stat;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_dyn_cmp_stat > SplitList_Michael_RCU_GPI_dyn_cmp_stat;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_dyn_cmp_stat > SplitList_Michael_RCU_GPB_dyn_cmp_stat;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_dyn_cmp_stat > SplitList_Michael_RCU_GPT_dyn_cmp_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_dyn_cmp_stat > SplitList_Michael_RCU_SHB_dyn_cmp_stat;
+#endif
+
+        struct traits_SplitList_Michael_dyn_cmp_seqcst: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::michael_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,co::memory_model< co::v::sequential_consistent >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::michael_list::make_traits<
+                        co::compare< compare >
+                        ,co::memory_model< co::v::sequential_consistent >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_dyn_cmp_seqcst > SplitList_Michael_HP_dyn_cmp_seqcst;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_dyn_cmp_seqcst > SplitList_Michael_DHP_dyn_cmp_seqcst;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_dyn_cmp_seqcst> SplitList_Michael_NOGC_dyn_cmp_seqcst;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_dyn_cmp_seqcst > SplitList_Michael_RCU_GPI_dyn_cmp_seqcst;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_dyn_cmp_seqcst > SplitList_Michael_RCU_GPB_dyn_cmp_seqcst;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_dyn_cmp_seqcst > SplitList_Michael_RCU_GPT_dyn_cmp_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_dyn_cmp_seqcst > SplitList_Michael_RCU_SHB_dyn_cmp_seqcst;
+#endif
+
+        struct traits_SplitList_Michael_st_cmp: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::michael_list_tag>
+                ,cc::split_list::dynamic_bucket_table< false >
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::michael_list::make_traits<
+                        co::compare< compare >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_st_cmp > SplitList_Michael_HP_st_cmp;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_st_cmp > SplitList_Michael_DHP_st_cmp;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_st_cmp> SplitList_Michael_NOGC_st_cmp;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_st_cmp > SplitList_Michael_RCU_GPI_st_cmp;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_st_cmp > SplitList_Michael_RCU_GPB_st_cmp;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_st_cmp > SplitList_Michael_RCU_GPT_st_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_st_cmp > SplitList_Michael_RCU_SHB_st_cmp;
+#endif
+
+        //HP + less
+        struct traits_SplitList_Michael_dyn_less: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::michael_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::michael_list::make_traits<
+                        co::less< less >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_dyn_less > SplitList_Michael_HP_dyn_less;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_dyn_less > SplitList_Michael_DHP_dyn_less;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_dyn_less> SplitList_Michael_NOGC_dyn_less;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_dyn_less > SplitList_Michael_RCU_GPI_dyn_less;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_dyn_less > SplitList_Michael_RCU_GPB_dyn_less;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_dyn_less > SplitList_Michael_RCU_GPT_dyn_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_dyn_less > SplitList_Michael_RCU_SHB_dyn_less;
+#endif
+
+
+        struct traits_SplitList_Michael_st_less: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::michael_list_tag>
+                ,cc::split_list::dynamic_bucket_table< false >
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::michael_list::make_traits<
+                        co::less< less >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_st_less > SplitList_Michael_HP_st_less;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_st_less > SplitList_Michael_DHP_st_less;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_st_less> SplitList_Michael_NOGC_st_less;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_st_less > SplitList_Michael_RCU_GPI_st_less;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_st_less > SplitList_Michael_RCU_GPB_st_less;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_st_less > SplitList_Michael_RCU_GPT_st_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_st_less > SplitList_Michael_RCU_SHB_st_less;
+#endif
+
+        struct traits_SplitList_Michael_st_less_stat : traits_SplitList_Michael_st_less
+        {
+            typedef cc::split_list::stat<> stat;
+            typedef typename cc::michael_list::make_traits<
+                co::less< less >
+                , co::stat< cc::michael_list::stat<> >
+            >::type ordered_list_traits;
+
+        };
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Michael_st_less_stat > SplitList_Michael_HP_st_less_stat;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Michael_st_less_stat > SplitList_Michael_DHP_st_less_stat;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, traits_SplitList_Michael_st_less_stat> SplitList_Michael_NOGC_st_less_stat;
+        typedef SplitListMap< rcu_gpi, Key, Value, traits_SplitList_Michael_st_less_stat > SplitList_Michael_RCU_GPI_st_less_stat;
+        typedef SplitListMap< rcu_gpb, Key, Value, traits_SplitList_Michael_st_less_stat > SplitList_Michael_RCU_GPB_st_less_stat;
+        typedef SplitListMap< rcu_gpt, Key, Value, traits_SplitList_Michael_st_less_stat > SplitList_Michael_RCU_GPT_st_less_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, traits_SplitList_Michael_st_less_stat > SplitList_Michael_RCU_SHB_st_less_stat;
+#endif
+
+
+        // ***************************************************************************
+        // SplitListMap based on LazyKVList
+
+        struct SplitList_Lazy_dyn_cmp :
+            public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::lazy_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::lazy_list::make_traits<
+                        co::compare< compare >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, SplitList_Lazy_dyn_cmp > SplitList_Lazy_HP_dyn_cmp;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, SplitList_Lazy_dyn_cmp > SplitList_Lazy_DHP_dyn_cmp;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, SplitList_Lazy_dyn_cmp> SplitList_Lazy_NOGC_dyn_cmp;
+        typedef SplitListMap< rcu_gpi, Key, Value, SplitList_Lazy_dyn_cmp > SplitList_Lazy_RCU_GPI_dyn_cmp;
+        typedef SplitListMap< rcu_gpb, Key, Value, SplitList_Lazy_dyn_cmp > SplitList_Lazy_RCU_GPB_dyn_cmp;
+        typedef SplitListMap< rcu_gpt, Key, Value, SplitList_Lazy_dyn_cmp > SplitList_Lazy_RCU_GPT_dyn_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, SplitList_Lazy_dyn_cmp > SplitList_Lazy_RCU_SHB_dyn_cmp;
+#endif
+
+        struct SplitList_Lazy_dyn_cmp_stat : public SplitList_Lazy_dyn_cmp
+        {
+            typedef cc::split_list::stat<> stat;
+            typedef typename cc::lazy_list::make_traits<
+                co::compare< compare >
+                , co::stat< cc::lazy_list::stat<>>
+            >::type ordered_list_traits;
+        };
+        typedef SplitListMap< cds::gc::HP, Key, Value, SplitList_Lazy_dyn_cmp_stat > SplitList_Lazy_HP_dyn_cmp_stat;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, SplitList_Lazy_dyn_cmp_stat > SplitList_Lazy_DHP_dyn_cmp_stat;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, SplitList_Lazy_dyn_cmp_stat> SplitList_Lazy_NOGC_dyn_cmp_stat;
+        typedef SplitListMap< rcu_gpi, Key, Value, SplitList_Lazy_dyn_cmp_stat > SplitList_Lazy_RCU_GPI_dyn_cmp_stat;
+        typedef SplitListMap< rcu_gpb, Key, Value, SplitList_Lazy_dyn_cmp_stat > SplitList_Lazy_RCU_GPB_dyn_cmp_stat;
+        typedef SplitListMap< rcu_gpt, Key, Value, SplitList_Lazy_dyn_cmp_stat > SplitList_Lazy_RCU_GPT_dyn_cmp_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, SplitList_Lazy_dyn_cmp_stat > SplitList_Lazy_RCU_SHB_dyn_cmp_stat;
+#endif
+
+        struct SplitList_Lazy_dyn_cmp_seqcst :
+            public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::lazy_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,co::memory_model< co::v::sequential_consistent >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::lazy_list::make_traits<
+                        co::compare< compare >
+                        ,co::memory_model< co::v::sequential_consistent >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, SplitList_Lazy_dyn_cmp_seqcst > SplitList_Lazy_HP_dyn_cmp_seqcst;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, SplitList_Lazy_dyn_cmp_seqcst > SplitList_Lazy_DHP_dyn_cmp_seqcst;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, SplitList_Lazy_dyn_cmp_seqcst> SplitList_Lazy_NOGC_dyn_cmp_seqcst;
+        typedef SplitListMap< rcu_gpi, Key, Value, SplitList_Lazy_dyn_cmp_seqcst > SplitList_Lazy_RCU_GPI_dyn_cmp_seqcst;
+        typedef SplitListMap< rcu_gpb, Key, Value, SplitList_Lazy_dyn_cmp_seqcst > SplitList_Lazy_RCU_GPB_dyn_cmp_seqcst;
+        typedef SplitListMap< rcu_gpt, Key, Value, SplitList_Lazy_dyn_cmp_seqcst > SplitList_Lazy_RCU_GPT_dyn_cmp_seqcst;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, SplitList_Lazy_dyn_cmp_seqcst > SplitList_Lazy_RCU_SHB_dyn_cmp_seqcst;
+#endif
+
+        struct SplitList_Lazy_st_cmp :
+            public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::lazy_list_tag>
+                ,cc::split_list::dynamic_bucket_table< false >
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::lazy_list::make_traits<
+                        co::compare< compare >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, SplitList_Lazy_st_cmp > SplitList_Lazy_HP_st_cmp;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, SplitList_Lazy_st_cmp > SplitList_Lazy_DHP_st_cmp;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, SplitList_Lazy_st_cmp> SplitList_Lazy_NOGC_st_cmp;
+        typedef SplitListMap< rcu_gpi, Key, Value, SplitList_Lazy_st_cmp > SplitList_Lazy_RCU_GPI_st_cmp;
+        typedef SplitListMap< rcu_gpb, Key, Value, SplitList_Lazy_st_cmp > SplitList_Lazy_RCU_GPB_st_cmp;
+        typedef SplitListMap< rcu_gpt, Key, Value, SplitList_Lazy_st_cmp > SplitList_Lazy_RCU_GPT_st_cmp;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, SplitList_Lazy_st_cmp > SplitList_Lazy_RCU_SHB_st_cmp;
+#endif
+
+
+        struct SplitList_Lazy_dyn_less :
+            public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::lazy_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::lazy_list::make_traits<
+                        co::less< less >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, SplitList_Lazy_dyn_less > SplitList_Lazy_HP_dyn_less;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, SplitList_Lazy_dyn_less > SplitList_Lazy_DHP_dyn_less;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, SplitList_Lazy_dyn_less> SplitList_Lazy_NOGC_dyn_less;
+        typedef SplitListMap< rcu_gpi, Key, Value, SplitList_Lazy_dyn_less > SplitList_Lazy_RCU_GPI_dyn_less;
+        typedef SplitListMap< rcu_gpb, Key, Value, SplitList_Lazy_dyn_less > SplitList_Lazy_RCU_GPB_dyn_less;
+        typedef SplitListMap< rcu_gpt, Key, Value, SplitList_Lazy_dyn_less > SplitList_Lazy_RCU_GPT_dyn_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, SplitList_Lazy_dyn_less > SplitList_Lazy_RCU_SHB_dyn_less;
+#endif
+
+        struct SplitList_Lazy_st_less :
+            public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::lazy_list_tag>
+                ,cc::split_list::dynamic_bucket_table< false >
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::lazy_list::make_traits<
+                        co::less< less >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, SplitList_Lazy_st_less > SplitList_Lazy_HP_st_less;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, SplitList_Lazy_st_less > SplitList_Lazy_DHP_st_less;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, SplitList_Lazy_st_less> SplitList_Lazy_NOGC_st_less;
+        typedef SplitListMap< rcu_gpi, Key, Value, SplitList_Lazy_st_less > SplitList_Lazy_RCU_GPI_st_less;
+        typedef SplitListMap< rcu_gpb, Key, Value, SplitList_Lazy_st_less > SplitList_Lazy_RCU_GPB_st_less;
+        typedef SplitListMap< rcu_gpt, Key, Value, SplitList_Lazy_st_less > SplitList_Lazy_RCU_GPT_st_less;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, SplitList_Lazy_st_less > SplitList_Lazy_RCU_SHB_st_less;
+#endif
+
+        struct SplitList_Lazy_st_less_stat : public SplitList_Lazy_st_less
+        {
+            typedef cc::split_list::stat<> stat;
+            typedef typename cc::lazy_list::make_traits<
+                co::less< less >
+                , co::stat< cc::lazy_list::stat<>>
+            >::type ordered_list_traits;
+        };
+        typedef SplitListMap< cds::gc::HP, Key, Value, SplitList_Lazy_st_less_stat > SplitList_Lazy_HP_st_less_stat;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, SplitList_Lazy_st_less_stat > SplitList_Lazy_DHP_st_less_stat;
+        typedef SplitListMap< cds::gc::nogc, Key, Value, SplitList_Lazy_st_less_stat> SplitList_Lazy_NOGC_st_less_stat;
+        typedef SplitListMap< rcu_gpi, Key, Value, SplitList_Lazy_st_less_stat > SplitList_Lazy_RCU_GPI_st_less_stat;
+        typedef SplitListMap< rcu_gpb, Key, Value, SplitList_Lazy_st_less_stat > SplitList_Lazy_RCU_GPB_st_less_stat;
+        typedef SplitListMap< rcu_gpt, Key, Value, SplitList_Lazy_st_less_stat > SplitList_Lazy_RCU_GPT_st_less_stat;
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+        typedef SplitListMap< rcu_shb, Key, Value, SplitList_Lazy_st_less_stat > SplitList_Lazy_RCU_SHB_st_less_stat;
+#endif
+
+
+        // ***************************************************************************
+        // SplitListMap based on IterableList
+        struct traits_SplitList_Iterable_dyn_cmp: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::iterable_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::iterable_list::make_traits<
+                        co::compare< compare >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Iterable_dyn_cmp > SplitList_Iterable_HP_dyn_cmp;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Iterable_dyn_cmp > SplitList_Iterable_DHP_dyn_cmp;
+
+        struct traits_SplitList_Iterable_dyn_cmp_stat : public traits_SplitList_Iterable_dyn_cmp
+        {
+            typedef cc::split_list::stat<> stat;
+            typedef typename cc::iterable_list::make_traits<
+                co::compare< compare >
+                , co::stat< cc::iterable_list::stat<>>
+            >::type ordered_list_traits;
+        };
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Iterable_dyn_cmp_stat > SplitList_Iterable_HP_dyn_cmp_stat;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Iterable_dyn_cmp_stat > SplitList_Iterable_DHP_dyn_cmp_stat;
+
+        struct traits_SplitList_Iterable_dyn_cmp_seqcst: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::iterable_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,co::memory_model< co::v::sequential_consistent >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::iterable_list::make_traits<
+                        co::compare< compare >
+                        ,co::memory_model< co::v::sequential_consistent >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Iterable_dyn_cmp_seqcst > SplitList_Iterable_HP_dyn_cmp_seqcst;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Iterable_dyn_cmp_seqcst > SplitList_Iterable_DHP_dyn_cmp_seqcst;
+
+        struct traits_SplitList_Iterable_st_cmp: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::iterable_list_tag>
+                ,cc::split_list::dynamic_bucket_table< false >
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::iterable_list::make_traits<
+                        co::compare< compare >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Iterable_st_cmp > SplitList_Iterable_HP_st_cmp;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Iterable_st_cmp > SplitList_Iterable_DHP_st_cmp;
+
+        //HP + less
+        struct traits_SplitList_Iterable_dyn_less: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::iterable_list_tag>
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::iterable_list::make_traits<
+                        co::less< less >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Iterable_dyn_less > SplitList_Iterable_HP_dyn_less;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Iterable_dyn_less > SplitList_Iterable_DHP_dyn_less;
+
+        struct traits_SplitList_Iterable_st_less: public cc::split_list::make_traits<
+                cc::split_list::ordered_list<cc::iterable_list_tag>
+                ,cc::split_list::dynamic_bucket_table< false >
+                ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
+                ,cc::split_list::ordered_list_traits<
+                    typename cc::iterable_list::make_traits<
+                        co::less< less >
+                    >::type
+                >
+            >::type
+        {};
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Iterable_st_less > SplitList_Iterable_HP_st_less;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Iterable_st_less > SplitList_Iterable_DHP_st_less;
+
+        struct traits_SplitList_Iterable_st_less_stat : traits_SplitList_Iterable_st_less
+        {
+            typedef cc::split_list::stat<> stat;
+            typedef typename cc::iterable_list::make_traits<
+                co::less< less >
+                , co::stat< cc::iterable_list::stat<>>
+            >::type ordered_list_traits;
+        };
+        typedef SplitListMap< cds::gc::HP, Key, Value, traits_SplitList_Iterable_st_less_stat > SplitList_Iterable_HP_st_less_stat;
+        typedef SplitListMap< cds::gc::DHP, Key, Value, traits_SplitList_Iterable_st_less_stat > SplitList_Iterable_DHP_st_less_stat;
+    };
+
+    template <typename GC, typename K, typename T, typename Traits >
+    static inline void print_stat( cds_test::property_stream& o, SplitListMap< GC, K, T, Traits > const& m )
+    {
+        o << m.statistics()
+          << cds_test::stat_prefix( "list_stat" )
+          << m.list_statistics()
+          << cds_test::stat_prefix( "" );
+    }
+
+}   // namespace map
+
+#define CDSSTRESS_SplitListMap_case( fixture, test_case, splitlist_map_type, key_type, value_type ) \
+    TEST_P( fixture, splitlist_map_type ) \
+    { \
+        typedef map::map_type< tag_SplitListMap, key_type, value_type >::splitlist_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 1
+#   define CDSSTRESS_SplitListMap_SHRCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SplitListMap_SHRCU_2( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL == 1
+#   define CDSSTRESS_SplitListMap_SHRCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHT_dyn_cmp,         key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHB_st_cmp,          key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHT_st_cmp,          key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHB_dyn_less,        key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHT_st_less,         key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHT_dyn_cmp,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHB_st_cmp,             key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHT_st_cmp,             key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHB_dyn_less,           key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHT_st_less,            key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SplitListMap_SHRCU_1( fixture, test_case, key_type, value_type )
+#endif
+
+
+#   define CDSSTRESS_SplitListMap_SHRCU( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHB_dyn_cmp,         key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHT_dyn_less,        key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_SHB_st_less,         key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHB_dyn_cmp,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHT_dyn_less,           key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_SHB_st_less,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_SHRCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_SHRCU_2( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SplitListMap_SHRCU( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 1
+#   define CDSSTRESS_SplitListMap_HP_2( fixture, test_case, key_type, value_type ) \
+
+#   define CDSSTRESS_SplitListMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#   define CDSSTRESS_SplitListMap_2( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_HP_2( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+
+#else
+#   define CDSSTRESS_SplitListMap_HP_2( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SplitListMap_RCU_2( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SplitListMap_2( fixture, test_case, key_type, value_type )
+#endif
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL == 1
+#   define CDSSTRESS_SplitListMap_HP_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_DHP_dyn_cmp,             key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_DHP_dyn_cmp_swar,        key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_HP_st_cmp,               key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_DHP_dyn_less,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_HP_st_less,              key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_DHP_dyn_cmp,                key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_HP_st_cmp,                  key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_DHP_dyn_less,               key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_HP_st_less,                 key_type, value_type ) \
+
+#   define CDSSTRESS_SplitListMap_RCU_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPT_dyn_cmp,         key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPI_st_cmp,          key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPT_st_cmp,          key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPB_dyn_less,        key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPI_st_less,         key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPT_st_less,         key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPB_dyn_cmp,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPI_st_cmp,             key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPT_st_cmp,             key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPB_dyn_less,           key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPI_st_less,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPT_st_less,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_SHRCU( fixture, test_case, key_type, value_type ) \
+
+#   define CDSSTRESS_SplitListMap_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_HP_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_RCU_1( fixture, test_case, key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SplitListMap_HP_1( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SplitListMap_RCU_1( fixture, test_case, key_type, value_type )
+#   define CDSSTRESS_SplitListMap_1( fixture, test_case, key_type, value_type )
+#endif
+
+
+#define CDSSTRESS_SplitListMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_HP_dyn_cmp,              key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_HP_dyn_cmp_swar,         key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_DHP_st_cmp,              key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_HP_dyn_less,             key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_DHP_st_less,             key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_HP_dyn_cmp,                 key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_DHP_st_cmp,                 key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_HP_dyn_less,                key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_DHP_st_less,                key_type, value_type ) \
+    CDSSTRESS_SplitListMap_HP_1( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_HP_2( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_SplitListMap_RCU( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPI_dyn_cmp,         key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPB_dyn_cmp,         key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPB_dyn_cmp_swar,    key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPB_st_cmp,          key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPI_dyn_less,        key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPT_dyn_less,        key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_RCU_GPB_st_less,         key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPI_dyn_cmp,            key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPT_dyn_cmp,            key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPB_st_cmp,             key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPI_dyn_less,           key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPT_dyn_less,           key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_RCU_GPB_st_less,            key_type, value_type ) \
+    CDSSTRESS_SplitListMap_RCU_1( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_RCU_2( fixture, test_case, key_type, value_type ) \
+
+#define CDSSTRESS_SplitListMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_HP( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_RCU( fixture, test_case, key_type, value_type ) \
+
+#if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 0
+#   define CDSSTRESS_SplitListIterableMap_1( fixture, test_case, key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_DHP_dyn_cmp,             key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_HP_st_cmp,               key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_DHP_dyn_less,            key_type, value_type ) \
+        CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_HP_st_less,              key_type, value_type ) \
+
+#else
+#   define CDSSTRESS_SplitListIterableMap_1( fixture, test_case, key_type, value_type )
+#endif
+
+
+#define CDSSTRESS_SplitListIterableMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_HP_dyn_cmp,              key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_DHP_st_cmp,              key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_HP_dyn_less,             key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Iterable_DHP_st_less,             key_type, value_type ) \
+    CDSSTRESS_SplitListIterableMap_1( fixture, test_case, key_type, value_type ) \
+
+
+#define CDSSTRESS_SplitListMap_nogc( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_NOGC_dyn_cmp,            key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_NOGC_st_cmp,             key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_NOGC_dyn_less,           key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Michael_NOGC_st_less,            key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_NOGC_dyn_cmp,               key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_NOGC_st_cmp,                key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_NOGC_dyn_less,              key_type, value_type ) \
+    CDSSTRESS_SplitListMap_case( fixture, test_case, SplitList_Lazy_NOGC_st_less,               key_type, value_type ) \
+
+#endif // ifndef CDSUNIT_MAP_TYPE_SPLIT_LIST_H
diff --git a/test/stress/sequential/sequential-map/map_type_std.h b/test/stress/sequential/sequential-map/map_type_std.h
new file mode 100644 (file)
index 0000000..8b88c67
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_STD_H
+#define CDSUNIT_MAP_TYPE_STD_H
+
+#include "map_type.h"
+
+#include <map>
+#include <unordered_map>
+
+namespace map {
+
+    struct empty_lock
+    {
+        void lock() {}
+        void unlock() {}
+    };
+
+    template <typename Key, typename Value, typename Lock,
+        class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<std::pair<Key const, Value> >::other
+    >
+        class StdMap: public std::map<Key, Value, std::less<Key>, Alloc>
+    {
+        Lock m_lock;
+        typedef std::unique_lock<Lock> scoped_lock;
+        typedef std::map<Key, Value, std::less<Key>, Alloc> base_class;
+    public:
+        typedef typename base_class::mapped_type value_type;
+        typedef typename base_class::value_type  pair_type;
+        typedef size_t      item_counter;
+
+        StdMap()
+        {}
+
+        template <class Config>
+        StdMap( Config const& )
+        {}
+
+        bool contains( const Key& key )
+        {
+            scoped_lock al( m_lock );
+            return base_class::find( key ) != base_class::end();
+        }
+
+        bool insert( const Key& key, const Value& val )
+        {
+            scoped_lock al( m_lock );
+            return base_class::insert( typename base_class::value_type( key, val )).second;
+        }
+
+        template <typename T, typename Func>
+        bool insert( const Key& key, const T& val, Func func )
+        {
+            scoped_lock al( m_lock );
+            std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value()));
+            if ( pRet.second ) {
+                func( pRet.first->second, val );
+                return true;
+            }
+            return false;
+        }
+
+        template <typename T, typename Func>
+        std::pair<bool, bool> update( const T& key, Func func, bool /*bAllowInsert*/ = true )
+        {
+            scoped_lock al( m_lock );
+            std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value()));
+            if ( pRet.second ) {
+                func( true, *pRet.first );
+                return std::make_pair( true, true );
+            }
+            else {
+                func( false, *pRet.first );
+                return std::make_pair( true, false );
+            }
+        }
+
+        bool erase( const Key& key )
+        {
+            scoped_lock al( m_lock );
+            return base_class::erase( key ) != 0;
+        }
+
+        template <typename T, typename Func>
+        bool erase( const T& key, Func func )
+        {
+            scoped_lock al( m_lock );
+            typename base_class::iterator it = base_class::find( key );
+            if ( it != base_class::end()) {
+                func( (*it));
+                base_class::erase( it );
+                return true;
+            }
+            return false;
+        }
+
+        empty_stat statistics() const
+        {
+            return empty_stat();
+        }
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = false;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    template <typename Key, typename Value, typename Lock,
+        class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<std::pair<Key const, Value> >::other
+    >
+    class StdHashMap
+        : public std::unordered_map<
+            Key, Value
+            , std::hash<Key>
+            , std::equal_to<Key>
+            , Alloc
+        >
+    {
+    public:
+        Lock m_lock;
+        typedef std::unique_lock<Lock> scoped_lock;
+        typedef std::unordered_map<
+            Key, Value
+            , std::hash<Key>
+            , std::equal_to<Key>
+            , Alloc
+        >   base_class;
+    public:
+        typedef typename base_class::mapped_type value_type;
+        typedef size_t      item_counter;
+
+        StdHashMap()
+        {}
+
+        template <class Config>
+        StdHashMap( Config const& )
+        {}
+
+        bool contains( const Key& key )
+        {
+            scoped_lock al( m_lock );
+            return base_class::find( key ) != base_class::end();
+        }
+
+        bool insert( const Key& key, const Value& val )
+        {
+            scoped_lock al( m_lock );
+            return base_class::insert( typename base_class::value_type(key, val)).second;
+        }
+
+        template <typename T, typename Func>
+        bool insert( const Key& key, const T& val, Func func )
+        {
+            scoped_lock al( m_lock );
+            std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type(key, Value()));
+            if ( pRet.second ) {
+                func( pRet.first->second, val );
+                return true;
+            }
+            return false;
+        }
+
+        template <typename T, typename Func>
+        std::pair<bool, bool> update( const T& key, Func func, bool /*bAllowInsert*/ = true )
+        {
+            scoped_lock al( m_lock );
+            std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value()));
+            if ( pRet.second ) {
+                func( true, *pRet.first );
+                return std::make_pair( true, true );
+            }
+            else {
+                func( false, *pRet.first );
+                return std::make_pair( true, false );
+            }
+        }
+
+        bool erase( const Key& key )
+        {
+            scoped_lock al( m_lock );
+            return base_class::erase( key ) != 0;
+        }
+
+        template <typename T, typename Func>
+        bool erase( const T& key, Func func )
+        {
+            scoped_lock al( m_lock );
+            typename base_class::iterator it = base_class::find( key );
+            if ( it != base_class::end()) {
+                func( *it );
+                return base_class::erase( key ) != 0;
+            }
+            return false;
+        }
+
+        empty_stat statistics() const
+        {
+            return empty_stat();
+        }
+
+
+        // for testing
+        static CDS_CONSTEXPR bool const c_bExtractSupported = false;
+        static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
+    };
+
+    struct tag_StdMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_StdMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value >      base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+
+        typedef StdMap< Key, Value, cds::sync::spin > StdMap_Spin;
+        typedef StdMap< Key, Value, std::mutex >      StdMap_Mutex;
+        typedef StdMap< Key, Value, empty_lock>       StdMap_NoLock;
+
+        typedef StdHashMap< Key, Value, cds::sync::spin > StdHashMap_Spin;
+        typedef StdHashMap< Key, Value, std::mutex >      StdHashMap_Mutex;
+        typedef StdHashMap< Key, Value, empty_lock >      StdHashMap_NoLock;
+    };
+}   // namespace map
+
+
+#define CDSSTRESS_StdMap_case( fixture, test_case, std_map_type, key_type, value_type ) \
+    TEST_F( fixture, std_map_type ) \
+    { \
+        typedef map::map_type< tag_StdMap, key_type, value_type >::std_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#define CDSSTRESS_StdMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_StdMap_case( fixture, test_case, StdMap_Spin,      key_type, value_type ) \
+    CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_Spin,  key_type, value_type ) \
+
+#define CDSSTRESS_StdMap_nolock( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_StdMap_case( fixture, test_case, StdMap_NoLock,      key_type, value_type ) \
+    CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_NoLock,  key_type, value_type )
+
+#endif // ifndef CDSUNIT_MAP_TYPE_STD_H
diff --git a/test/stress/sequential/sequential-map/map_type_striped.h b/test/stress/sequential/sequential-map/map_type_striped.h
new file mode 100644 (file)
index 0000000..88be541
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSUNIT_MAP_TYPE_STRIPED_H
+#define CDSUNIT_MAP_TYPE_STRIPED_H
+
+#include "map_type.h"
+#include <cds/container/striped_map/std_list.h>
+#include <cds/container/striped_map/std_map.h>
+#include <cds/container/striped_map/std_hash_map.h>
+
+#include <boost/version.hpp>
+#if BOOST_VERSION >= 104800
+#   include <cds/container/striped_map/boost_list.h>
+#   include <cds/container/striped_map/boost_slist.h>
+#   include <cds/container/striped_map/boost_map.h>
+#   include <cds/container/striped_map/boost_flat_map.h>
+#endif
+#include <cds/container/striped_map/boost_unordered_map.h>
+#include <cds/container/striped_map.h>
+
+namespace map {
+
+    struct tag_StripedMap;
+
+    template <typename Key, typename Value>
+    struct map_type< tag_StripedMap, Key, Value >: public map_type_base< Key, Value >
+    {
+        typedef map_type_base< Key, Value >      base_class;
+        typedef typename base_class::key_compare compare;
+        typedef typename base_class::key_less    less;
+        typedef typename base_class::equal_to    equal_to;
+        typedef typename base_class::key_hash    hash;
+        typedef typename base_class::hash2       hash2;
+
+        // for sequential containers
+        template <class BucketEntry, typename... Options>
+        class StripedHashMap_seq:
+            public cc::StripedMap< BucketEntry,
+                co::mutex_policy< cc::striped_set::striping<> >
+                ,co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                , Options...
+            >
+        {
+            typedef cc::StripedMap< BucketEntry,
+                co::mutex_policy< cc::striped_set::striping<> >
+                ,co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                , Options...
+            > base_class;
+            typedef typename base_class::resizing_policy resizing_policy_t;
+
+            resizing_policy_t   m_placeHolder;
+        public:
+            template <class Config>
+            StripedHashMap_seq( Config const& cfg )
+                : base_class( cfg.s_nMapSize / cfg.s_nLoadFactor / 16, *(new(&m_placeHolder) resizing_policy_t( cfg.s_nLoadFactor )))
+            {}
+
+            empty_stat statistics() const
+            {
+                return empty_stat();
+            }
+
+            // for testing
+            static CDS_CONSTEXPR bool const c_bExtractSupported = false;
+            static CDS_CONSTEXPR bool const c_bLoadFactorDepended = true;
+        };
+
+        // for non-sequential ordered containers
+        template <class BucketEntry, typename... Options>
+        class StripedHashMap_ord:
+            public cc::StripedMap< BucketEntry,
+                co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                ,co::mutex_policy< cc::striped_set::striping<> >
+                , Options...
+            >
+        {
+            typedef cc::StripedMap< BucketEntry,
+               co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                ,co::mutex_policy< cc::striped_set::striping<> >
+                , Options...
+            > base_class;
+            typedef typename base_class::resizing_policy resizing_policy_t;
+
+            resizing_policy_t   m_placeHolder;
+        public:
+            template <class Config>
+            StripedHashMap_ord( Config const& cfg )
+                : base_class( 0, *(new(&m_placeHolder) resizing_policy_t( cfg.s_nMaxLoadFactor * 1024 )))
+            {}
+
+            empty_stat statistics() const
+            {
+                return empty_stat();
+            }
+
+            // for testing
+            static CDS_CONSTEXPR bool const c_bExtractSupported = false;
+            static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        };
+
+
+        typedef StripedHashMap_seq<
+            std::list< std::pair< Key const, Value > >
+            , co::hash< hash2 >
+            , co::less< less >
+        > StripedMap_list;
+
+        typedef StripedHashMap_ord<
+            std::unordered_map< Key, Value, hash, equal_to >
+            , co::hash< hash2 >
+        > StripedMap_hashmap;
+
+        typedef StripedHashMap_ord<
+            std::map< Key, Value, less >
+            , co::hash< hash2 >
+        > StripedMap_map;
+
+        typedef StripedHashMap_ord<
+            boost::unordered_map< Key, Value, hash, equal_to >
+            , co::hash< hash2 >
+        > StripedMap_boost_unordered_map;
+
+#   if BOOST_VERSION >= 104800
+        typedef StripedHashMap_seq<
+            boost::container::slist< std::pair< Key const, Value > >
+            , co::hash< hash2 >
+            , co::less< less >
+        > StripedMap_slist;
+
+        typedef StripedHashMap_seq<
+            boost::container::list< std::pair< Key const, Value > >
+            , co::hash< hash2 >
+            , co::less< less >
+        > StripedMap_boost_list;
+
+        typedef StripedHashMap_ord<
+            boost::container::map< Key, Value, less >
+            , co::hash< hash2 >
+        > StripedMap_boost_map;
+
+        typedef StripedHashMap_ord<
+            boost::container::flat_map< Key, Value, less >
+            , co::hash< hash2 >
+        > StripedMap_boost_flat_map;
+#   endif  // BOOST_VERSION >= 104800
+
+
+        // ***************************************************************************
+        // RefinableHashMap
+
+        // for sequential containers
+        template <class BucketEntry, typename... Options>
+        class RefinableHashMap_seq:
+            public cc::StripedMap< BucketEntry,
+                co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                ,co::mutex_policy< cc::striped_set::refinable<> >
+                , Options...
+            >
+        {
+            typedef cc::StripedMap< BucketEntry,
+               co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                ,co::mutex_policy< cc::striped_set::refinable<> >
+                , Options...
+            > base_class;
+            typedef typename base_class::resizing_policy resizing_policy_t;
+
+            resizing_policy_t   m_placeHolder;
+        public:
+            template <class Config>
+            RefinableHashMap_seq( Config const& cfg )
+                : base_class( cfg.s_nMapSize / cfg.s_nLoadFactor / 16, *(new(&m_placeHolder) resizing_policy_t( cfg.s_nLoadFactor )))
+            {}
+
+            empty_stat statistics() const
+            {
+                return empty_stat();
+            }
+
+            // for testing
+            static CDS_CONSTEXPR bool const c_bExtractSupported = false;
+            static CDS_CONSTEXPR bool const c_bLoadFactorDepended = true;
+        };
+
+        // for non-sequential ordered containers
+        template <class BucketEntry, typename... Options>
+        class RefinableHashMap_ord:
+            public cc::StripedMap< BucketEntry,
+                co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                ,co::mutex_policy< cc::striped_set::refinable<> >
+                , Options...
+            >
+        {
+            typedef cc::StripedMap< BucketEntry,
+               co::resizing_policy<cc::striped_set::load_factor_resizing<0> >
+                ,co::mutex_policy< cc::striped_set::refinable<> >
+                , Options...
+            > base_class;
+            typedef typename base_class::resizing_policy resizing_policy_t;
+
+            resizing_policy_t   m_placeHolder;
+        public:
+            template <class Config>
+            RefinableHashMap_ord( Config const& cfg )
+                : base_class( 0, *(new(&m_placeHolder) resizing_policy_t( cfg.s_nMaxLoadFactor * 1024 )))
+            {}
+
+            empty_stat statistics() const
+            {
+                return empty_stat();
+            }
+
+            // for testing
+            static CDS_CONSTEXPR bool const c_bExtractSupported = false;
+            static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
+        };
+
+
+        typedef RefinableHashMap_seq<
+            std::list< std::pair< Key const, Value > >
+            , co::hash< hash2 >
+            , co::less< less >
+        > RefinableMap_list;
+
+#   if BOOST_VERSION >= 104800
+        typedef RefinableHashMap_seq<
+            boost::container::slist< std::pair< Key const, Value > >
+            , co::hash< hash2 >
+            , co::less< less >
+        > RefinableMap_slist;
+#   endif
+
+        typedef RefinableHashMap_ord<
+            std::map< Key, Value, less >
+            , co::hash< hash2 >
+        > RefinableMap_map;
+
+        typedef RefinableHashMap_ord<
+            std::unordered_map< Key, Value, hash, equal_to >
+            , co::hash< hash2 >
+        > RefinableMap_hashmap;
+
+        typedef RefinableHashMap_ord<
+            boost::unordered_map< Key, Value, hash, equal_to >
+            , co::hash< hash2 >
+        > RefinableMap_boost_unordered_map;
+
+#   if BOOST_VERSION >= 104800
+        typedef RefinableHashMap_seq<
+            boost::container::list< std::pair< Key const, Value > >
+            , co::hash< hash2 >
+            , co::less< less >
+        > RefinableMap_boost_list;
+
+        typedef RefinableHashMap_ord<
+            boost::container::map< Key, Value, less >
+            , co::hash< hash2 >
+        > RefinableMap_boost_map;
+
+        typedef RefinableHashMap_ord<
+            boost::container::flat_map< Key, Value, less >
+            , co::hash< hash2 >
+        > RefinableMap_boost_flat_map;
+#   endif // #if BOOST_VERSION >= 104800
+
+    };
+}   // namespace map
+
+#define CDSSTRESS_StripedMap_case( fixture, test_case, striped_map_type, key_type, value_type ) \
+    TEST_P( fixture, striped_map_type ) \
+    { \
+        typedef map::map_type< tag_StripedMap, key_type, value_type >::striped_map_type map_type; \
+        test_case<map_type>(); \
+    }
+
+#define CDSSTRESS_StripedMap( fixture, test_case, key_type, value_type ) \
+    CDSSTRESS_StripedMap_case( fixture, test_case, StripedMap_list,         key_type, value_type ) \
+    CDSSTRESS_StripedMap_case( fixture, test_case, StripedMap_hashmap,      key_type, value_type ) \
+    CDSSTRESS_StripedMap_case( fixture, test_case, StripedMap_map,          key_type, value_type ) \
+    CDSSTRESS_StripedMap_case( fixture, test_case, RefinableMap_list,       key_type, value_type ) \
+    CDSSTRESS_StripedMap_case( fixture, test_case, RefinableMap_map,        key_type, value_type ) \
+    CDSSTRESS_StripedMap_case( fixture, test_case, RefinableMap_hashmap,    key_type, value_type ) \
+
+#endif // ifndef CDSUNIT_MAP_TYPE_STRIPED_H
diff --git a/test/stress/sequential/sequential-map/minmax/CMakeLists.txt b/test/stress/sequential/sequential-map/minmax/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2481fe9
--- /dev/null
@@ -0,0 +1,19 @@
+set(PACKAGE_NAME stress-sequential-map-minmax)
+
+set(CDSSTRESS_MAP_MINMAX_SOURCES
+    ../../../main.cpp
+    map_minmax.cpp
+    map_minmax_bronsonavltree.cpp
+    map_minmax_ellentree.cpp
+    map_minmax_skip.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_MINMAX_SOURCES})
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
diff --git a/test/stress/sequential/sequential-map/minmax/map_minmax.cpp b/test/stress/sequential/sequential-map/minmax/map_minmax.cpp
new file mode 100644 (file)
index 0000000..fd7f672
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_minmax.h"
+
+namespace map {
+
+    size_t  Map_MinMax::s_nMapSize = 50000;
+    size_t  Map_MinMax::s_nInsThreadCount = 4;
+    size_t  Map_MinMax::s_nExtractThreadCount = 4;
+    size_t  Map_MinMax::s_nPassCount = 1000;
+
+    size_t Map_MinMax::s_nFeldmanMap_HeadBits = 8;
+    size_t Map_MinMax::s_nFeldmanMap_ArrayBits = 8;
+
+    void Map_MinMax::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "map_minmax" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsThreadCount = cfg.get_size_t( "InsThreadCount", s_nInsThreadCount );
+        if ( s_nInsThreadCount == 0 )
+            s_nInsThreadCount = 1;
+
+        s_nExtractThreadCount = cfg.get_size_t( "ExtractThreadCount", s_nExtractThreadCount );
+        if ( s_nExtractThreadCount )
+            s_nExtractThreadCount = 1;
+
+        s_nPassCount = cfg.get_size_t( "PassCount", s_nPassCount );
+        if ( s_nPassCount == 0 )
+            s_nPassCount = 100;
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 4;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 4;
+    }
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/minmax/map_minmax.h b/test/stress/sequential/sequential-map/minmax/map_minmax.h
new file mode 100644 (file)
index 0000000..6958d72
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+#include <cds/os/topology.h>
+
+namespace map {
+
+    class Map_MinMax: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nInsThreadCount;      // insert thread count
+        static size_t s_nExtractThreadCount;  // extract thread count
+        static size_t s_nMapSize;             // max map size
+        static size_t s_nPassCount;
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static void SetUpTestCase();
+        //static void TearDownTestCase();
+
+    protected:
+        typedef int     key_type;
+        typedef int     value_type;
+        typedef std::pair<key_type const, value_type> pair_type;
+
+        atomics::atomic<size_t> m_nInsThreadCount;
+        key_type    m_KeyMin;
+        key_type    m_KeyMax;
+
+        enum {
+            inserter_thread,
+            extractor_thread,
+        };
+
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+            std::vector<key_type> m_arr;
+
+            void init_data()
+            {
+                Map_MinMax& fixture = pool().template fixture<Map_MinMax>();
+                key_type keyMin = fixture.m_KeyMin;
+                key_type keyMax = fixture.m_KeyMax;
+
+                for ( key_type i = keyMin + 10; i >= keyMin; --i )
+                    m_arr.push_back( i );
+                for ( key_type i = keyMax - 10; i <= keyMax; ++i )
+                    m_arr.push_back( i );
+                shuffle( m_arr.begin(), m_arr.end());
+            }
+
+        public:
+            size_t m_nInsertMinSuccess = 0;
+            size_t m_nInsertMinFailed = 0;
+            size_t m_nInsertMaxSuccess = 0;
+            size_t m_nInsertMaxFailed = 0;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, inserter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map_MinMax& fixture = pool().template fixture<Map_MinMax>();
+
+                key_type keyMin = fixture.m_KeyMin;
+                key_type keyMax = fixture.m_KeyMax;
+
+                for ( size_t nPass = 0; nPass < s_nPassCount; ++nPass ) {
+                    for ( key_type key : m_arr ) {
+                        if ( m_Map.insert( key, key )) {
+                            if ( key == keyMin )
+                                ++m_nInsertMinSuccess;
+                            else if ( key == keyMax )
+                                ++m_nInsertMaxSuccess;
+                        }
+                        else {
+                            if ( key == keyMin )
+                                ++m_nInsertMinFailed;
+                            else if ( key == keyMax )
+                                ++m_nInsertMaxFailed;
+                        }
+                    }
+                }
+
+                fixture.m_nInsThreadCount.fetch_sub( 1, atomics::memory_order_release );
+            }
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class GC, class Map >
+        class Extractor: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+        public:
+            size_t  m_nDeleteMin = 0;
+            size_t  m_nDeleteMinFailed = 0;
+            size_t  m_nDeleteMax = 0;
+            size_t  m_nDeleteMaxFailed = 0;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {}
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                typename Map::guarded_ptr gp;
+                Map_MinMax& fixture = pool().template fixture<Map_MinMax>();
+
+                key_type keyMin = fixture.m_KeyMin;
+                key_type keyMax = fixture.m_KeyMax;
+
+                do {
+                    gp = rMap.extract_min();
+                    if ( gp ) {
+                        if ( gp->first == keyMin )
+                            ++m_nDeleteMin;
+                    }
+                    else
+                        ++m_nDeleteMinFailed;
+
+                    gp = rMap.extract_max();
+                    if ( gp ) {
+                        if ( gp->first == keyMax )
+                            ++m_nDeleteMax;
+                    }
+                    else
+                        ++m_nDeleteMaxFailed;
+
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                gp = rMap.extract_min();
+                if ( gp ) {
+                    if ( gp->first == keyMin )
+                        ++m_nDeleteMin;
+                }
+                else
+                    ++m_nDeleteMinFailed;
+
+                gp = rMap.extract_max();
+                if ( gp ) {
+                    if ( gp->first == keyMax )
+                        ++m_nDeleteMax;
+                }
+                else
+                    ++m_nDeleteMaxFailed;
+            }
+        };
+
+        template <class RCU, class Map >
+        class Extractor< cds::urcu::gc<RCU>, Map > : public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+        public:
+            size_t  m_nDeleteMin = 0;
+            size_t  m_nDeleteMinFailed = 0;
+            size_t  m_nDeleteMax = 0;
+            size_t  m_nDeleteMaxFailed = 0;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {}
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_MinMax& fixture = pool().template fixture<Map_MinMax>();
+
+                key_type keyMin = fixture.m_KeyMin;
+                key_type keyMax = fixture.m_KeyMax;
+
+                static_assert( !Map::c_bExtractLockExternal, "No external RCU locking required" );
+
+                do {
+                    auto res = rMap.extract_min_key();
+                    if ( res.second ) {
+                        if ( res.first == keyMin )
+                            ++m_nDeleteMin;
+                    }
+                    else
+                        ++m_nDeleteMinFailed;
+
+                    res = rMap.extract_max_key();
+                    if ( res.second ) {
+                        if ( res.first == keyMax )
+                            ++m_nDeleteMax;
+                    }
+                    else
+                        ++m_nDeleteMaxFailed;
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                auto res = rMap.extract_min_key();
+                if ( res.second ) {
+                    if ( res.first == keyMin )
+                        ++m_nDeleteMin;
+                }
+                else
+                    ++m_nDeleteMinFailed;
+
+                res = rMap.extract_max_key();
+                if ( res.second ) {
+                    if ( res.first == keyMax )
+                        ++m_nDeleteMax;
+                }
+                else
+                    ++m_nDeleteMaxFailed;
+            }
+        };
+
+    protected:
+        template <class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Extractor< typename Map::gc, Map > extract_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            {
+                std::vector<key_type> arr;
+                arr.resize( s_nMapSize );
+                for ( int i = 0; i < static_cast<int>( s_nMapSize ); ++i )
+                    arr[i] = i;;
+                shuffle( arr.begin(), arr.end());
+
+                for ( key_type key : arr )
+                    testMap.insert( key, key );
+            }
+
+            m_KeyMin = 0;
+            m_KeyMax = static_cast<int>( s_nMapSize - 1 );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            pool.add( new extract_thread( pool, testMap ), s_nExtractThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "extract_thread_count", s_nExtractThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertMinSuccess = 0;
+            size_t nInsertMinFailed = 0;
+            size_t nInsertMaxSuccess = 0;
+            size_t nInsertMaxFailed = 0;
+            size_t nDeleteMin = 0;
+            size_t nDeleteMinFailed = 0;
+            size_t nDeleteMax = 0;
+            size_t nDeleteMaxFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                {
+                    insert_thread& inserter = static_cast<insert_thread&>(thr);
+                    nInsertMinSuccess += inserter.m_nInsertMinSuccess;
+                    nInsertMinFailed += inserter.m_nInsertMinFailed;
+                    nInsertMaxSuccess += inserter.m_nInsertMaxSuccess;
+                    nInsertMaxFailed += inserter.m_nInsertMaxFailed;
+                }
+                break;
+                case extractor_thread:
+                {
+                    extract_thread& extractor = static_cast<extract_thread&>(thr);
+                    nDeleteMin += extractor.m_nDeleteMin;
+                    nDeleteMinFailed += extractor.m_nDeleteMinFailed;
+                    nDeleteMax += extractor.m_nDeleteMax;
+                    nDeleteMaxFailed += extractor.m_nDeleteMaxFailed;
+                }
+                break;
+                default:
+                    assert( false );
+                }
+            }
+
+            EXPECT_EQ( nDeleteMinFailed, 0u );
+            EXPECT_EQ( nDeleteMaxFailed, 0u );
+
+            EXPECT_EQ( nDeleteMin, nInsertMinSuccess + 1 );
+            EXPECT_EQ( nDeleteMax, nInsertMaxSuccess + 1 );
+
+            propout()
+                << std::make_pair( "insert_min", nInsertMinSuccess + 1 )
+                << std::make_pair( "insert_min_double", nInsertMinFailed )
+                << std::make_pair( "insert_max", nInsertMaxSuccess + 1 )
+                << std::make_pair( "insert_max_double", nInsertMaxFailed )
+                << std::make_pair( "extract_min", nDeleteMin )
+                << std::make_pair( "extract_min_failed", nDeleteMinFailed )
+                << std::make_pair( "extract_max", nDeleteMax )
+                << std::make_pair( "extract_max_failed", nDeleteMaxFailed );
+
+            analyze( testMap );
+        }
+
+        template <class Map>
+        void analyze( Map& testMap )
+        {
+            print_stat( propout(), testMap );
+
+            check_before_cleanup( testMap );
+            testMap.clear();
+            EXPECT_TRUE( testMap.empty()) << "map.size=" << testMap.size();
+
+            additional_check( testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map>
+        void run_test()
+        {
+            static_assert( Map::c_bExtractSupported, "Map class must support extract() method" );
+            Map testMap( *this );
+            do_test( testMap );
+        }
+    };
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/minmax/map_minmax_bronsonavltree.cpp b/test/stress/sequential/sequential-map/minmax/map_minmax_bronsonavltree.cpp
new file mode 100644 (file)
index 0000000..3319a0b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_minmax.h"
+#include "map_type_bronson_avltree.h"
+
+namespace map {
+
+    CDSSTRESS_BronsonAVLTreeMap( Map_MinMax, run_test, int, int )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/minmax/map_minmax_ellentree.cpp b/test/stress/sequential/sequential-map/minmax/map_minmax_ellentree.cpp
new file mode 100644 (file)
index 0000000..3329efa
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_minmax.h"
+#include "map_type_ellen_bintree.h"
+
+namespace map {
+
+    CDSSTRESS_EllenBinTreeMap( Map_MinMax, run_test, int, int )
+
+} // namespace map
diff --git a/test/stress/sequential/sequential-map/minmax/map_minmax_skip.cpp b/test/stress/sequential/sequential-map/minmax/map_minmax_skip.cpp
new file mode 100644 (file)
index 0000000..c75767a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_minmax.h"
+#include "map_type_skip_list.h"
+
+namespace map {
+
+    CDSSTRESS_SkipListMap( Map_MinMax, run_test, int, int )
+
+} // namespace map