StripedMap: replace ensure() with update(), find(key) with contains(key)
authorkhizmax <libcds.dev@gmail.com>
Sat, 5 Sep 2015 15:21:04 +0000 (18:21 +0300)
committerkhizmax <libcds.dev@gmail.com>
Sat, 5 Sep 2015 15:21:04 +0000 (18:21 +0300)
Refactored Map_InsDel_func MT-test

25 files changed:
cds/container/striped_map.h
cds/container/striped_map/boost_list.h
cds/container/striped_map/boost_slist.h
cds/container/striped_map/std_hash_map.h
cds/container/striped_map/std_list.h
cds/container/striped_map/std_map.h
cds/container/striped_set/adapter.h
projects/Win/vc12/unit-map-insdel.vcxproj
projects/Win/vc12/unit-map-insdel.vcxproj.filters
projects/source.unit.map.mk
tests/data/test-debug.conf
tests/data/test-express.conf
tests/data/test.conf
tests/unit/map2/CMakeLists.txt
tests/unit/map2/map_insdel_func.cpp
tests/unit/map2/map_insdel_func.h
tests/unit/map2/map_insdel_func_bronsonavltree.cpp
tests/unit/map2/map_insdel_func_cuckoo.cpp
tests/unit/map2/map_insdel_func_ellentree.cpp
tests/unit/map2/map_insdel_func_michael.cpp
tests/unit/map2/map_insdel_func_multilevelhashmap.cpp [new file with mode: 0644]
tests/unit/map2/map_insdel_func_refinable.cpp [deleted file]
tests/unit/map2/map_insdel_func_skip.cpp
tests/unit/map2/map_insdel_func_split.cpp
tests/unit/map2/map_insdel_func_striped.cpp

index a40e5d319651167eb7bc159d28521f0992409d58..06739d92f9a32c46d5f38c8afe35367d1d0093ee 100644 (file)
@@ -636,37 +636,29 @@ template <class Container, typename... Options>
             return bOk;
         }
 
             return bOk;
         }
 
-        /// Ensures that the \p key exists in the map
+        /// Updates the node
         /**
             The operation performs inserting or changing data with lock-free manner.
 
         /**
             The operation performs inserting or changing data with lock-free manner.
 
-            If the \p key not found in the map, then the new item created from \p key
-            is inserted into the map (note that in this case the \p key_type should be
-            constructible from type \p K).
+            If \p key is not found in the map, then \p key is inserted iff \p bAllowInsert is \p true.
             Otherwise, the functor \p func is called with item found.
             Otherwise, the functor \p func is called with item found.
-            The functor \p Func may be a function with signature:
-            \code
-                void func( bool bNew, value_type& item );
-            \endcode
-            or a functor:
+
+            The functor signature is:
             \code
                 struct my_functor {
                     void operator()( bool bNew, value_type& item );
                 };
             \endcode
             \code
                 struct my_functor {
                     void operator()( bool bNew, value_type& item );
                 };
             \endcode
-
             with arguments:
             - \p bNew - \p true if the item has been inserted, \p false otherwise
             with arguments:
             - \p bNew - \p true if the item has been inserted, \p false otherwise
-            - \p item - item of the list
-
-            The functor may change any fields of the \p item.second that is \p mapped_type.
+            - \p item - item of the map
 
             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
             \p second is true if new item has been added or \p false if the item with \p key
 
             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
             \p second is true if new item has been added or \p false if the item with \p key
-            already is in the list.
+            already is in the map.
         */
         template <typename K, typename Func>
         */
         template <typename K, typename Func>
-        std::pair<bool, bool> ensure( K const& key, Func func )
+        std::pair<bool, bool> update( K const& key, Func func, bool bAllowInsert = true )
         {
             std::pair<bool, bool> result;
             bool bResize;
         {
             std::pair<bool, bool> result;
             bool bResize;
@@ -676,7 +668,7 @@ template <class Container, typename... Options>
                 scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
                 pBucket = base_class::bucket( nHash );
 
                 scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
                 pBucket = base_class::bucket( nHash );
 
-                result = pBucket->ensure( key, func );
+                result = pBucket->update( key, func, bAllowInsert );
                 bResize = result.first && result.second && base_class::m_ResizingPolicy( ++base_class::m_ItemCounter, *this, *pBucket );
             }
 
                 bResize = result.first && result.second && base_class::m_ResizingPolicy( ++base_class::m_ItemCounter, *this, *pBucket );
             }
 
@@ -684,6 +676,13 @@ template <class Container, typename... Options>
                 base_class::resize();
             return result;
         }
                 base_class::resize();
             return result;
         }
+        //@cond
+        template <typename K, typename Func>
+        CDS_DEPRECATED("ensure() is deprecated, use update() instead")
+        std::pair<bool, bool> ensure( K const& key, Func func )
+        {
+            return update( key, func, true );
+        }
 
         /// Delete \p key from the map
         /** \anchor cds_nonintrusive_StripedMap_erase
 
         /// Delete \p key from the map
         /** \anchor cds_nonintrusive_StripedMap_erase
@@ -796,36 +795,51 @@ template <class Container, typename... Options>
                 [&f]( value_type& pair, K const& ) mutable { f(pair); } );
         }
 
                 [&f]( value_type& pair, K const& ) mutable { f(pair); } );
         }
 
-        /// Find the key \p key
-        /** \anchor cds_nonintrusive_StripedMap_find_val
-
+        /// Checks whether the map contains \p key
+        /**
             The function searches the item with key equal to \p key
             and returns \p true if it is found, and \p false otherwise.
         */
         template <typename K>
             The function searches the item with key equal to \p key
             and returns \p true if it is found, and \p false otherwise.
         */
         template <typename K>
+        bool contains( K const& key )
+        {
+            return base_class::contains( key );
+        }
+        //@cond
+        template <typename K>
+        CDS_DEPRECATED("use contains()")
         bool find( K const& key )
         {
         bool find( K const& key )
         {
-            return base_class::find( key );
+            return contains( key );
         }
         }
+        //@endcond
 
 
-        /// Find the key \p val using \p pred predicate
+        /// Checks whether the set contains \p key using \p pred predicate for searching
         /**
         /**
-            The function is an analog of \ref cds_nonintrusive_StripedMap_find_val "find(K const&)"
-            but \p pred is used for key comparing
-            \p Less has the interface like \p std::less.
-            \p pred must imply the same element order as the comparator used for building the set.
+            The function is similar to <tt>contains( key )</tt> but \p pred is used for key comparing.
+            \p Less functor has the interface like \p std::less.
+            \p Less must imply the same element order as the comparator used for building the set.
 
             @note This function is enabled if the compiler supports C++11
             default template arguments for function template <b>and</b> the underlying container
 
             @note This function is enabled if the compiler supports C++11
             default template arguments for function template <b>and</b> the underlying container
-            supports \p %find_with feature.
+            supports \p %contains() feature.
         */
         template <typename K, typename Less
             ,typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
         */
         template <typename K, typename Less
             ,typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
-        bool find_with( K const& key, Less pred )
+        bool contains( K const& key, Less pred )
         {
             CDS_UNUSED( pred );
         {
             CDS_UNUSED( pred );
-            return base_class::find_with( key, cds::details::predicate_wrapper< value_type, Less, key_accessor >() );
+            return base_class::contains( key, cds::details::predicate_wrapper< value_type, Less, key_accessor >() );
+        }
+        //@cond
+        template <typename K, typename Less
+            ,typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
+        CDS_DEPRECATED("use contains()")
+        bool find_with( K const& key, Less pred )
+        {
+            return contains( key, pred );
         }
         }
+        //@endcond
 
         /// Clears the map
         void clear()
 
         /// Clears the map
         void clear()
index a82b0bfa6c2652e0d97e87a3393d7014892a7445..92526c2ea654c481f44ef9093fa73ec3c13ec4b1 100644 (file)
@@ -161,11 +161,14 @@ namespace cds { namespace intrusive { namespace striped_set {
             }
 
             template <typename Q, typename Func>
             }
 
             template <typename Q, typename Func>
-            std::pair<bool, bool> ensure( const Q& key, Func func )
+            std::pair<bool, bool> update( const Q& key, Func func, bool bAllowInsert )
             {
                 iterator it = std::lower_bound( m_List.begin(), m_List.end(), key, find_predicate() );
                 if ( it == m_List.end() || key_comparator()( key, it->first ) != 0 ) {
                     // insert new
             {
                 iterator it = std::lower_bound( m_List.begin(), m_List.end(), key, find_predicate() );
                 if ( it == m_List.end() || key_comparator()( key, it->first ) != 0 ) {
                     // insert new
+                    if ( !bAllowInsert )
+                        return std::make_pair( false, false );
+
                     value_type newItem( key, mapped_type() );
                     it = m_List.insert( it, newItem );
                     func( true, *it );
                     value_type newItem( key, mapped_type() );
                     it = m_List.insert( it, newItem );
                     func( true, *it );
index 5c3616655c53e09fa144068efe5f197ff6a6b258..4ff101eeaceaab49d4e0abb4a95237dea2d4391b 100644 (file)
@@ -172,11 +172,14 @@ namespace cds { namespace intrusive { namespace striped_set {
             }
 
             template <typename Q, typename Func>
             }
 
             template <typename Q, typename Func>
-            std::pair<bool, bool> ensure( const Q& key, Func func )
+            std::pair<bool, bool> update( const Q& key, Func func, bool bAllowInsert )
             {
                 std::pair< iterator, bool > pos = find_prev_item( key );
                 if ( !pos.second ) {
                     // insert new
             {
                 std::pair< iterator, bool > pos = find_prev_item( key );
                 if ( !pos.second ) {
                     // insert new
+                    if ( !bAllowInsert )
+                        return std::make_pair( false, false );
+
                     value_type newItem( key, mapped_type() );
                     pos.first = m_List.insert_after( pos.first, newItem );
                     func( true, *pos.first );
                     value_type newItem( key, mapped_type() );
                     pos.first = m_List.insert_after( pos.first, newItem );
                     func( true, *pos.first );
index 6904505dbdda64875bf28f75cf8d98e0c938111a..4173fb891e494d1fe4bb4785be2e790921b2d746 100644 (file)
@@ -118,11 +118,20 @@ namespace cds { namespace intrusive { namespace striped_set {
             }
 
             template <typename Q, typename Func>
             }
 
             template <typename Q, typename Func>
-            std::pair<bool, bool> ensure( const Q& key, Func func )
+            std::pair<bool, bool> update( const Q& key, Func func, bool bAllowInsert )
             {
             {
-                std::pair<iterator, bool> res = m_Map.insert( value_type( key, mapped_type() ) );
-                func( res.second, const_cast<value_type&>(*res.first));
-                return std::make_pair( true, res.second );
+                if ( bAllowInsert ) {
+                    std::pair<iterator, bool> res = m_Map.insert( value_type( key, mapped_type() ) );
+                    func( res.second, const_cast<value_type&>(*res.first));
+                    return std::make_pair( true, res.second );
+                }
+                else {
+                    auto it = m_Map.find(key_type( key ));
+                    if ( it == end() )
+                        return std::make_pair( false, false );
+                    func( false, *it );
+                    return std::make_pair( true, false );
+                }
             }
 
             template <typename Q, typename Func>
             }
 
             template <typename Q, typename Func>
index 4e7bdc180aaaeaeebe6ceb9af4bdc991d9c9fc9f..f25b1826bc6d041e938a9981815286594f3514e4 100644 (file)
@@ -180,11 +180,14 @@ namespace cds { namespace intrusive { namespace striped_set {
             }
 
             template <typename Q, typename Func>
             }
 
             template <typename Q, typename Func>
-            std::pair<bool, bool> ensure( const Q& key, Func func )
+            std::pair<bool, bool> update( const Q& key, Func func, bool bAllowInsert )
             {
                 iterator it = std::lower_bound( m_List.begin(), m_List.end(), key, find_predicate() );
                 if ( it == m_List.end() || key_comparator()( key, it->first ) != 0 ) {
                     // insert new
             {
                 iterator it = std::lower_bound( m_List.begin(), m_List.end(), key, find_predicate() );
                 if ( it == m_List.end() || key_comparator()( key, it->first ) != 0 ) {
                     // insert new
+                    if ( !bAllowInsert )
+                        return std::make_pair( false, false );
+
                     value_type newItem( key, mapped_type() );
                     it = m_List.insert( it, newItem );
                     func( true, *it );
                     value_type newItem( key, mapped_type() );
                     it = m_List.insert( it, newItem );
                     func( true, *it );
index 62a0c72f2f22de8bd4c256d5cadc4c405ff4de6e..a2f2fcdfa80c155b376a172a91eb8d969f42a207 100644 (file)
@@ -118,11 +118,20 @@ namespace cds { namespace intrusive { namespace striped_set {
             }
 
             template <typename Q, typename Func>
             }
 
             template <typename Q, typename Func>
-            std::pair<bool, bool> ensure( const Q& key, Func func )
+            std::pair<bool, bool> update( const Q& key, Func func, bool bAllowInsert )
             {
             {
-                std::pair<iterator, bool> res = m_Map.insert( value_type( key, mapped_type() ));
-                func( res.second, *res.first );
-                return std::make_pair( true, res.second );
+                if ( bAllowInsert ) {
+                    std::pair<iterator, bool> res = m_Map.insert( value_type( key, mapped_type() ));
+                    func( res.second, *res.first );
+                    return std::make_pair( true, res.second );
+                }
+                else {
+                    auto it = m_Map.find(key_type( key ));
+                    if ( it == end() )
+                        return std::make_pair( false, false );
+                    func( false, *it );
+                    return std::make_pair( true, false );
+                }
             }
 
             template <typename Q, typename Func>
             }
 
             template <typename Q, typename Func>
index b6deb8cc7f28c0c9cd3be59036b85d74a1427481..ef60abe48600a84a33cdae17729689d9dacfd670 100644 (file)
@@ -73,12 +73,12 @@ namespace cds { namespace container {
                 variadic template and move semantics
             <hr>
 
                 variadic template and move semantics
             <hr>
 
-            <b>Ensures that the \p item exists in the container</b>
-            \code template <typename Q, typename Func> std::pair<bool, bool> ensure( const Q& val, Func func ) \endcode
+            <b>Updates \p item</b>
+            \code template <typename Q, typename Func> std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert ) \endcode
                 The operation performs inserting or changing data.
 
                 If the \p val key not found in the container, then the new item created from \p val
                 The operation performs inserting or changing data.
 
                 If the \p val key not found in the container, then the new item created from \p val
-                is inserted. Otherwise, the functor \p func is called with the item found.
+                is inserted iff \p bAllowInsert is \p true. Otherwise, the functor \p func is called with the item found.
                 The \p Func functor has interface:
                 \code
                     void func( bool bNew, value_type& item, const Q& val );
                 The \p Func functor has interface:
                 \code
                     void func( bool bNew, value_type& item, const Q& val );
@@ -93,7 +93,7 @@ namespace cds { namespace container {
                 where arguments are:
                 - \p bNew - \p true if the item has been inserted, \p false otherwise
                 - \p item - container's item
                 where arguments are:
                 - \p bNew - \p true if the item has been inserted, \p false otherwise
                 - \p item - container's item
-                - \p val - argument \p val passed into the \p ensure function
+                - \p val - argument \p val passed into the \p update() function
 
                 The functor can change non-key fields of the \p item.
 
 
                 The functor can change non-key fields of the \p item.
 
@@ -429,11 +429,20 @@ namespace cds { namespace container {
                 }
 
                 template <typename Q, typename Func>
                 }
 
                 template <typename Q, typename Func>
-                std::pair<bool, bool> ensure( const Q& val, Func func )
+                std::pair<bool, bool> update( const Q& key, Func func, bool bAllowInsert )
                 {
                 {
-                    std::pair<iterator, bool> res = m_Map.insert( value_type( val, mapped_type() ));
-                    func( res.second, *res.first );
-                    return std::make_pair( true, res.second );
+                    if ( bAllowInsert ) {
+                        std::pair<iterator, bool> res = m_Map.insert( value_type( key, mapped_type() ));
+                        func( res.second, *res.first );
+                        return std::make_pair( true, res.second );
+                    }
+                    else {
+                        auto it = m_Map.find(key_type( key ));
+                        if ( it == end() )
+                            return std::make_pair( false, false );
+                        func( false, *it );
+                        return std::make_pair( true, false );
+                    }
                 }
 
                 template <typename Q, typename Func>
                 }
 
                 template <typename Q, typename Func>
index 48ce135ad7cbd0b51d74524105c90b932c28ce0c..fd0ee80b5edd9947651457d5f25ffe01da37bcf8 100644 (file)
@@ -48,7 +48,7 @@
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_cuckoo.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_ellentree.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_michael.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_cuckoo.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_ellentree.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_michael.cpp" />\r
-    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_refinable.cpp" />\r
+    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_multilevelhashmap.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_skip.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_split.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_striped.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_skip.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_split.cpp" />\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_striped.cpp" />\r
index f3be91cd8211c9cd1f7a9c58f54ca74c0f601c4a..c22d583e44310aae9eba9f24133007f2bb9e1723 100644 (file)
@@ -16,9 +16,6 @@
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_michael.cpp">\r
       <Filter>map_insdel_func</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_michael.cpp">\r
       <Filter>map_insdel_func</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_refinable.cpp">\r
-      <Filter>map_insdel_func</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_skip.cpp">\r
       <Filter>map_insdel_func</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_skip.cpp">\r
       <Filter>map_insdel_func</Filter>\r
     </ClCompile>\r
@@ -88,6 +85,9 @@
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_int_std.cpp">\r
       <Filter>map_insdel_int</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_int_std.cpp">\r
       <Filter>map_insdel_int</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\tests\unit\map2\map_insdel_func_multilevelhashmap.cpp">\r
+      <Filter>map_insdel_func</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="map_insdel_func">\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="map_insdel_func">\r
index accb93470e3c15eefbb29a6af3321b8978812619..2264a10a1876dde1a2dd0253abae48741dd9cc97 100644 (file)
@@ -31,14 +31,14 @@ CDSUNIT_MAP_SOURCES := \
     tests/unit/map2/map_insfind_int_refinable.cpp \
     tests/unit/map2/map_insfind_int_std.cpp \
     tests/unit/map2/map_insdel_func.cpp \
     tests/unit/map2/map_insfind_int_refinable.cpp \
     tests/unit/map2/map_insfind_int_std.cpp \
     tests/unit/map2/map_insdel_func.cpp \
+    tests/unit/map2/map_insdel_func_bronsonavltree.cpp \
+    tests/unit/map2/map_insdel_func_cuckoo.cpp \
+    tests/unit/map2/map_insdel_func_ellentree.cpp \
     tests/unit/map2/map_insdel_func_michael.cpp \
     tests/unit/map2/map_insdel_func_michael.cpp \
-    tests/unit/map2/map_insdel_func_split.cpp \
+    tests/unit/map2/map_insdel_func_multilevelhashmap.cpp \
     tests/unit/map2/map_insdel_func_skip.cpp \
     tests/unit/map2/map_insdel_func_skip.cpp \
-    tests/unit/map2/map_insdel_func_ellentree.cpp \
-    tests/unit/map2/map_insdel_func_bronsonavltree.cpp \
+    tests/unit/map2/map_insdel_func_split.cpp \
     tests/unit/map2/map_insdel_func_striped.cpp \
     tests/unit/map2/map_insdel_func_striped.cpp \
-    tests/unit/map2/map_insdel_func_refinable.cpp \
-    tests/unit/map2/map_insdel_func_cuckoo.cpp \
     tests/unit/map2/map_insdel_int.cpp \
     tests/unit/map2/map_insdel_int_bronsonavltree.cpp \
     tests/unit/map2/map_insdel_int_cuckoo.cpp \
     tests/unit/map2/map_insdel_int.cpp \
     tests/unit/map2/map_insdel_int_bronsonavltree.cpp \
     tests/unit/map2/map_insdel_int_cuckoo.cpp \
index 88c2207d1bdfe0e5b8b32b6f1056c57cad176a8a..304feb9da430e53a504dcbab0812fdb78621526d 100644 (file)
@@ -147,15 +147,22 @@ CuckooProbesetThreshold=0
 MultiLevelMapHeadBits=8\r
 MultiLevelMapArrayBits=4\r
 \r
 MultiLevelMapHeadBits=8\r
 MultiLevelMapArrayBits=4\r
 \r
-\r
 [Map_InsDel_func]\r
 InsertThreadCount=4\r
 DeleteThreadCount=4\r
 [Map_InsDel_func]\r
 InsertThreadCount=4\r
 DeleteThreadCount=4\r
-EnsureThreadCount=4\r
+UpdateThreadCount=4\r
 ThreadPassCount=8\r
 MapSize=5000\r
 MaxLoadFactor=4\r
 PrintGCStateFlag=1\r
 ThreadPassCount=8\r
 MapSize=5000\r
 MaxLoadFactor=4\r
 PrintGCStateFlag=1\r
+# *** Cuckoo map properties\r
+CuckooInitialSize=256\r
+CuckooProbesetSize=8\r
+# 0 - use default\r
+CuckooProbesetThreshold=0 \r
+# *** MultiLevelHashMap properties\r
+MultiLevelMapHeadBits=8\r
+MultiLevelMapArrayBits=4\r
 \r
 [Map_InsDel_Item_int]\r
 ThreadCount=4\r
 \r
 [Map_InsDel_Item_int]\r
 ThreadCount=4\r
index a177efdc2b49564485ebc765aa4f21b13c396128..929420ce602de48bdfed13ffdecd385d00f4623b 100644 (file)
@@ -145,15 +145,22 @@ CuckooProbesetThreshold=0
 MultiLevelMapHeadBits=8\r
 MultiLevelMapArrayBits=4\r
 \r
 MultiLevelMapHeadBits=8\r
 MultiLevelMapArrayBits=4\r
 \r
-\r
 [Map_InsDel_func]\r
 InsertThreadCount=4\r
 DeleteThreadCount=4\r
 [Map_InsDel_func]\r
 InsertThreadCount=4\r
 DeleteThreadCount=4\r
-EnsureThreadCount=4\r
+UpdateThreadCount=4\r
 ThreadPassCount=4\r
 MapSize=100000\r
 MaxLoadFactor=4\r
 PrintGCStateFlag=1\r
 ThreadPassCount=4\r
 MapSize=100000\r
 MaxLoadFactor=4\r
 PrintGCStateFlag=1\r
+# *** Cuckoo map properties\r
+CuckooInitialSize=1024\r
+CuckooProbesetSize=16\r
+# 0 - use default\r
+CuckooProbesetThreshold=0 \r
+# *** MultiLevelHashMap properties\r
+MultiLevelMapHeadBits=8\r
+MultiLevelMapArrayBits=4\r
 \r
 [Map_InsDel_Item_int]\r
 ThreadCount=8\r
 \r
 [Map_InsDel_Item_int]\r
 ThreadCount=8\r
index 97eafc50bf2dc8c94e5e16ca838fc7c9dd15ef57..d5be15c38ec3004dfd3de3c6658257c499b5d412 100644 (file)
@@ -143,11 +143,19 @@ MultiLevelMapArrayBits=4
 [Map_InsDel_func]\r
 InsertThreadCount=4\r
 DeleteThreadCount=4\r
 [Map_InsDel_func]\r
 InsertThreadCount=4\r
 DeleteThreadCount=4\r
-EnsureThreadCount=4\r
+UpdateThreadCount=4\r
 ThreadPassCount=2\r
 MapSize=1000000\r
 MaxLoadFactor=4\r
 PrintGCStateFlag=1\r
 ThreadPassCount=2\r
 MapSize=1000000\r
 MaxLoadFactor=4\r
 PrintGCStateFlag=1\r
+# *** Cuckoo map properties\r
+CuckooInitialSize=1024\r
+CuckooProbesetSize=16\r
+# 0 - use default\r
+CuckooProbesetThreshold=0 \r
+# *** MultiLevelHashMap properties\r
+MultiLevelMapHeadBits=10\r
+MultiLevelMapArrayBits=4\r
 \r
 [Map_InsDel_Item_int]\r
 ThreadCount=8\r
 \r
 [Map_InsDel_Item_int]\r
 ThreadCount=8\r
index fbcddeecd86cad2bf698d3ae0732b242a64ec461..95fc4fb58ae0c57564f7031af3ce522bc5710129 100644 (file)
@@ -32,14 +32,14 @@ set(CDSUNIT_MAP_SOURCES
     map_insfind_int_refinable.cpp
     map_insfind_int_std.cpp
     map_insdel_func.cpp
     map_insfind_int_refinable.cpp
     map_insfind_int_std.cpp
     map_insdel_func.cpp
+    map_insdel_func_bronsonavltree.cpp
+    map_insdel_func_cuckoo.cpp
+    map_insdel_func_ellentree.cpp
     map_insdel_func_michael.cpp
     map_insdel_func_michael.cpp
-    map_insdel_func_split.cpp
+    map_insdel_func_multilevelhashmap.cpp
     map_insdel_func_skip.cpp
     map_insdel_func_skip.cpp
-    map_insdel_func_ellentree.cpp
-    map_insdel_func_bronsonavltree.cpp
+    map_insdel_func_split.cpp
     map_insdel_func_striped.cpp
     map_insdel_func_striped.cpp
-    map_insdel_func_refinable.cpp
-    map_insdel_func_cuckoo.cpp
     map_insdel_int.cpp
     map_insdel_int_bronsonavltree.cpp
     map_insdel_int_cuckoo.cpp
     map_insdel_int.cpp
     map_insdel_int_bronsonavltree.cpp
     map_insdel_int_cuckoo.cpp
index 964b38e914cac7f5b447a4350018f1049239af13..f96723e1ce73f034c9f72524ffd4b409f2164242 100644 (file)
@@ -5,45 +5,22 @@
 namespace map2 {
     CPPUNIT_TEST_SUITE_REGISTRATION( Map_InsDel_func );
 
 namespace map2 {
     CPPUNIT_TEST_SUITE_REGISTRATION( Map_InsDel_func );
 
-    static const size_t def_nMapSize = 1000000;
-    static const size_t def_nInsertThreadCount = 4;
-    static const size_t def_nDeleteThreadCount = 4;
-    static const size_t def_nEnsureThreadCount = 4;
-    static const size_t def_nThreadPassCount = 4;
-    static const size_t def_nMaxLoadFactor = 8;
-
-    size_t  Map_InsDel_func::c_nMapSize = def_nMapSize    ;  // map size
-    size_t  Map_InsDel_func::c_nInsertThreadCount = def_nInsertThreadCount;  // count of insertion thread
-    size_t  Map_InsDel_func::c_nDeleteThreadCount = def_nDeleteThreadCount;  // count of deletion thread
-    size_t  Map_InsDel_func::c_nEnsureThreadCount = def_nEnsureThreadCount;  // count of ensure thread
-    size_t  Map_InsDel_func::c_nThreadPassCount = def_nThreadPassCount;  // pass count for each thread
-    size_t  Map_InsDel_func::c_nMaxLoadFactor = def_nMaxLoadFactor;  // maximum load factor
-    bool    Map_InsDel_func::c_bPrintGCState = true;
-
     void Map_InsDel_func::setUpParams( const CppUnitMini::TestCfg& cfg )
     {
     void Map_InsDel_func::setUpParams( const CppUnitMini::TestCfg& cfg )
     {
-        c_nInsertThreadCount = cfg.getULong("InsertThreadCount", def_nInsertThreadCount );
-        c_nDeleteThreadCount = cfg.getULong("DeleteThreadCount", def_nDeleteThreadCount );
-        c_nEnsureThreadCount = cfg.getULong("EnsureThreadCount", def_nEnsureThreadCount );
-        c_nThreadPassCount = cfg.getULong("ThreadPassCount", def_nThreadPassCount );
-        c_nMapSize = cfg.getULong("MapSize", def_nMapSize );
-        c_nMaxLoadFactor = cfg.getULong("MaxLoadFactor", def_nMaxLoadFactor );
+        c_nInsertThreadCount = cfg.getULong("InsertThreadCount", static_cast<unsigned long>(c_nInsertThreadCount));
+        c_nDeleteThreadCount = cfg.getULong("DeleteThreadCount", static_cast<unsigned long>(c_nDeleteThreadCount));
+        c_nUpdateThreadCount = cfg.getULong("UpdateThreadCount", static_cast<unsigned long>(c_nUpdateThreadCount));
+        c_nThreadPassCount = cfg.getULong("ThreadPassCount", static_cast<unsigned long>(c_nThreadPassCount));
+        c_nMapSize = cfg.getULong("MapSize", static_cast<unsigned long>(c_nMapSize));
+        c_nMaxLoadFactor = cfg.getULong("MaxLoadFactor", static_cast<unsigned long>(c_nMaxLoadFactor));
         c_bPrintGCState = cfg.getBool("PrintGCStateFlag", true );
         c_bPrintGCState = cfg.getBool("PrintGCStateFlag", true );
-    }
 
 
-    void Map_InsDel_func::myRun(const char *in_name, bool invert /*= false*/)
-    {
-        setUpParams( m_Cfg.get( "Map_InsDel_func" ));
+        c_nCuckooInitialSize = cfg.getULong("CuckooInitialSize", static_cast<unsigned long>(c_nCuckooInitialSize) );
+        c_nCuckooProbesetSize = cfg.getULong("CuckooProbesetSize", static_cast<unsigned long>(c_nCuckooProbesetSize) );
+        c_nCuckooProbesetThreshold = cfg.getULong("CuckooProbesetThreshold", static_cast<unsigned long>(c_nCuckooProbesetThreshold) );
 
 
-        run_MichaelMap(in_name, invert);
-        run_SplitList(in_name, invert);
-        run_SkipListMap(in_name, invert);
-        run_EllenBinTreeMap(in_name, invert);
-        run_BronsonAVLTreeMap(in_name, invert);
-        run_StripedMap(in_name, invert);
-        run_RefinableMap(in_name, invert);
-        run_CuckooMap(in_name, invert);
+        c_nMultiLevelMap_HeadBits = cfg.getULong("MultiLevelMapHeadBits", static_cast<unsigned long>(c_nMultiLevelMap_HeadBits) );
+        c_nMultiLevelMap_ArrayBits = cfg.getULong("MultiLevelMapArrayBits", static_cast<unsigned long>(c_nMultiLevelMap_ArrayBits) );
 
 
-        endTestCase();
     }
 } // namespace map2
     }
 } // namespace map2
index e4e075b45c8c4faee0469a0d57188b098a43fda5..9294fae6435a7a0fae9c28266e414ec599ccf1a7 100644 (file)
 
 namespace map2 {
 
 
 namespace map2 {
 
-#   define TEST_MAP(IMPL, C, X)          void C::X() { test<map_type<IMPL, key_type, value_type>::X >()    ; }
-#   define TEST_MAP_EXTRACT(IMPL, C, X)  TEST_MAP(IMPL, C, X)
-#   define TEST_MAP_NOLF(IMPL, C, X)     void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >()    ; }
-#   define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
+#   define TEST_CASE(TAG, X)  void X();
+
+//#   define TEST_MAP(IMPL, C, X)          void C::X() { test<map_type<IMPL, key_type, value_type>::X >()    ; }
+//#   define TEST_MAP_EXTRACT(IMPL, C, X)  TEST_MAP(IMPL, C, X)
+//#   define TEST_MAP_NOLF(IMPL, C, X)     void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >()    ; }
+//#   define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
 
     class Map_InsDel_func: public CppUnitMini::TestCase
     {
 
     class Map_InsDel_func: public CppUnitMini::TestCase
     {
-        static size_t  c_nMapSize;            // map size
-        static size_t  c_nInsertThreadCount;  // count of insertion thread
-        static size_t  c_nDeleteThreadCount;  // count of deletion thread
-        static size_t  c_nEnsureThreadCount;  // count of ensure thread
-        static size_t  c_nThreadPassCount;    // pass count for each thread
-        static size_t  c_nMaxLoadFactor;      // maximum load factor
-        static bool    c_bPrintGCState;
+    public:
+        size_t c_nMapSize = 1000000;      // map size
+        size_t c_nInsertThreadCount = 4;  // count of insertion thread
+        size_t c_nDeleteThreadCount = 4;  // count of deletion thread
+        size_t c_nUpdateThreadCount = 4;  // count of updating thread
+        size_t c_nThreadPassCount   = 4;  // pass count for each thread
+        size_t c_nMaxLoadFactor = 8;      // maximum load factor
+        bool   c_bPrintGCState = true;
+
+        size_t c_nCuckooInitialSize = 1024;// initial size for CuckooMap
+        size_t c_nCuckooProbesetSize = 16; // CuckooMap probeset size (only for list-based probeset)
+        size_t c_nCuckooProbesetThreshold = 0; // CUckooMap probeset threshold (o - use default)
+
+        size_t c_nMultiLevelMap_HeadBits = 10;
+        size_t c_nMultiLevelMap_ArrayBits = 4;
 
 
+        size_t  c_nLoadFactor;  // current load factor
+
+    private:
         typedef size_t  key_type;
         struct value_type {
             size_t      nKey;
             size_t      nData;
         typedef size_t  key_type;
         struct value_type {
             size_t      nKey;
             size_t      nData;
-            atomics::atomic<size_t> nEnsureCall;
+            atomics::atomic<size_t> nUpdateCall;
             atomics::atomic<bool>   bInitialized;
             cds::OS::ThreadId          threadId     ;   // insert thread id
 
             atomics::atomic<bool>   bInitialized;
             cds::OS::ThreadId          threadId     ;   // insert thread id
 
@@ -39,7 +52,7 @@ namespace map2 {
             value_type()
                 : nKey(0)
                 , nData(0)
             value_type()
                 : nKey(0)
                 , nData(0)
-                , nEnsureCall(0)
+                , nUpdateCall(0)
                 , bInitialized( false )
                 , threadId( cds::OS::get_current_thread_id() )
             {}
                 , bInitialized( false )
                 , threadId( cds::OS::get_current_thread_id() )
             {}
@@ -47,7 +60,7 @@ namespace map2 {
             value_type( value_type const& s )
                 : nKey(s.nKey)
                 , nData(s.nData)
             value_type( value_type const& s )
                 : nKey(s.nKey)
                 , nData(s.nData)
-                , nEnsureCall(s.nEnsureCall.load(atomics::memory_order_relaxed))
+                , nUpdateCall(s.nUpdateCall.load(atomics::memory_order_relaxed))
                 , bInitialized( s.bInitialized.load(atomics::memory_order_relaxed) )
                 , threadId( cds::OS::get_current_thread_id() )
             {}
                 , bInitialized( s.bInitialized.load(atomics::memory_order_relaxed) )
                 , threadId( cds::OS::get_current_thread_id() )
             {}
@@ -57,7 +70,7 @@ namespace map2 {
             {
                 nKey = v.nKey;
                 nData = v.nData;
             {
                 nKey = v.nKey;
                 nData = v.nData;
-                nEnsureCall.store( v.nEnsureCall.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed );
+                nUpdateCall.store( v.nUpdateCall.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed );
                 bInitialized.store(v.bInitialized.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed);
 
                 return *this;
                 bInitialized.store(v.bInitialized.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed);
 
                 return *this;
@@ -138,9 +151,10 @@ namespace map2 {
                 // func is passed by reference
                 insert_functor  func;
                 key_array const& arr = getTest().m_arrValues;
                 // func is passed by reference
                 insert_functor  func;
                 key_array const& arr = getTest().m_arrValues;
+                size_t const nPassCount = getTest().c_nThreadPassCount;
 
                 if ( m_nThreadNo & 1 ) {
 
                 if ( m_nThreadNo & 1 ) {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
                         for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
                             if ( rMap.insert_with( *it, std::ref(func) ) )
                                 ++m_nInsertSuccess;
                         for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
                             if ( rMap.insert_with( *it, std::ref(func) ) )
                                 ++m_nInsertSuccess;
@@ -150,7 +164,7 @@ namespace map2 {
                     }
                 }
                 else {
                     }
                 }
                 else {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
                         for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
                             if ( rMap.insert_with( *it, std::ref(func) ) )
                                 ++m_nInsertSuccess;
                         for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
                             if ( rMap.insert_with( *it, std::ref(func) ) )
                                 ++m_nInsertSuccess;
@@ -165,20 +179,20 @@ namespace map2 {
         };
 
         template <class Map>
         };
 
         template <class Map>
-        class Ensurer: public CppUnitMini::TestThread
+        class Updater: public CppUnitMini::TestThread
         {
             Map&     m_Map;
 
         {
             Map&     m_Map;
 
-            virtual Ensurer *    clone()
+            virtual Updater *    clone()
             {
             {
-                return new Ensurer( *this );
+                return new Updater( *this );
             }
 
             }
 
-            struct ensure_functor {
+            struct update_functor {
                 size_t  nCreated;
                 size_t  nModified;
 
                 size_t  nCreated;
                 size_t  nModified;
 
-                ensure_functor()
+                update_functor()
                     : nCreated(0)
                     , nModified(0)
                 {}
                     : nCreated(0)
                     , nModified(0)
                 {}
@@ -194,7 +208,7 @@ namespace map2 {
                         v.bInitialized.store( true, atomics::memory_order_relaxed);
                     }
                     else {
                         v.bInitialized.store( true, atomics::memory_order_relaxed);
                     }
                     else {
-                        v.nEnsureCall.fetch_add( 1, atomics::memory_order_relaxed );
+                        v.nUpdateCall.fetch_add( 1, atomics::memory_order_relaxed );
                         ++nModified;
                     }
                 }
                         ++nModified;
                     }
                 }
@@ -204,23 +218,31 @@ namespace map2 {
                 {
                     operator()( bNew, val.first, val.second );
                 }
                 {
                     operator()( bNew, val.first, val.second );
                 }
+
+                // For MultiLevelHashMap
+                template <typename Val>
+                void operator()( Val& cur, Val * old )
+                {
+                    operator()( old != nullptr, cur.first, cur.second );
+                }
+
             private:
             private:
-                ensure_functor(const ensure_functor& );
+                update_functor(const update_functor& ) = delete;
             };
 
         public:
             };
 
         public:
-            size_t  m_nEnsureFailed;
-            size_t  m_nEnsureCreated;
-            size_t  m_nEnsureExisted;
+            size_t  m_nUpdateFailed;
+            size_t  m_nUpdateCreated;
+            size_t  m_nUpdateExisted;
             size_t  m_nFunctorCreated;
             size_t  m_nFunctorModified;
 
         public:
             size_t  m_nFunctorCreated;
             size_t  m_nFunctorModified;
 
         public:
-            Ensurer( CppUnitMini::ThreadPool& pool, Map& rMap )
+            Updater( CppUnitMini::ThreadPool& pool, Map& rMap )
                 : CppUnitMini::TestThread( pool )
                 , m_Map( rMap )
             {}
                 : CppUnitMini::TestThread( pool )
                 , m_Map( rMap )
             {}
-            Ensurer( Ensurer& src )
+            Updater( Updater& src )
                 : CppUnitMini::TestThread( src )
                 , m_Map( src.m_Map )
             {}
                 : CppUnitMini::TestThread( src )
                 , m_Map( src.m_Map )
             {}
@@ -237,42 +259,43 @@ namespace map2 {
             {
                 Map& rMap = m_Map;
 
             {
                 Map& rMap = m_Map;
 
-                m_nEnsureCreated =
-                    m_nEnsureExisted =
-                    m_nEnsureFailed = 0;
+                m_nUpdateCreated =
+                    m_nUpdateExisted =
+                    m_nUpdateFailed = 0;
 
 
-                ensure_functor func;
+                update_functor func;
 
                 key_array const& arr = getTest().m_arrValues;
 
                 key_array const& arr = getTest().m_arrValues;
+                size_t const nPassCount = getTest().c_nThreadPassCount;
 
                 if ( m_nThreadNo & 1 ) {
 
                 if ( m_nThreadNo & 1 ) {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
                         for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
                         //for ( size_t nItem = 0; nItem < c_nMapSize; ++nItem ) {
                         for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
                         //for ( size_t nItem = 0; nItem < c_nMapSize; ++nItem ) {
-                            std::pair<bool, bool> ret = rMap.ensure( *it, std::ref( func ) );
+                            std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ) );
                             if ( ret.first  ) {
                                 if ( ret.second )
                             if ( ret.first  ) {
                                 if ( ret.second )
-                                    ++m_nEnsureCreated;
+                                    ++m_nUpdateCreated;
                                 else
                                 else
-                                    ++m_nEnsureExisted;
+                                    ++m_nUpdateExisted;
                             }
                             else
                             }
                             else
-                                ++m_nEnsureFailed;
+                                ++m_nUpdateFailed;
                         }
                     }
                 }
                 else {
                         }
                     }
                 }
                 else {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
                         for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
                         for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
-                            std::pair<bool, bool> ret = rMap.ensure( *it, std::ref( func ) );
+                            std::pair<bool, bool> ret = rMap.update( *it, std::ref( func ) );
                             if ( ret.first  ) {
                                 if ( ret.second )
                             if ( ret.first  ) {
                                 if ( ret.second )
-                                    ++m_nEnsureCreated;
+                                    ++m_nUpdateCreated;
                                 else
                                 else
-                                    ++m_nEnsureExisted;
+                                    ++m_nUpdateExisted;
                             }
                             else
                             }
                             else
-                                ++m_nEnsureFailed;
+                                ++m_nUpdateFailed;
                         }
                     }
                 }
                         }
                     }
                 }
@@ -370,9 +393,10 @@ namespace map2 {
 
                 erase_functor   func;
                 key_array const& arr = getTest().m_arrValues;
 
                 erase_functor   func;
                 key_array const& arr = getTest().m_arrValues;
+                size_t const nPassCount = getTest().c_nThreadPassCount;
 
                 if ( m_nThreadNo & 1 ) {
 
                 if ( m_nThreadNo & 1 ) {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
                         for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
                             func.m_cnt.nKeyExpected = *it;
                             if ( rMap.erase( *it, std::ref(func) ))
                         for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
                             func.m_cnt.nKeyExpected = *it;
                             if ( rMap.erase( *it, std::ref(func) ))
@@ -383,7 +407,7 @@ namespace map2 {
                     }
                 }
                 else {
                     }
                 }
                 else {
-                    for ( size_t nPass = 0; nPass < c_nThreadPassCount; ++nPass ) {
+                    for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
                         for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
                             func.m_cnt.nKeyExpected = *it;
                             if ( rMap.erase( *it, std::ref(func) ))
                         for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
                             func.m_cnt.nKeyExpected = *it;
                             if ( rMap.erase( *it, std::ref(func) ))
@@ -406,7 +430,7 @@ namespace map2 {
         {
             typedef Inserter<Map>       InserterThread;
             typedef Deleter<Map>        DeleterThread;
         {
             typedef Inserter<Map>       InserterThread;
             typedef Deleter<Map>        DeleterThread;
-            typedef Ensurer<Map>        EnsurerThread;
+            typedef Updater<Map>        UpdaterThread;
             cds::OS::Timer    timer;
 
             m_arrValues.clear();
             cds::OS::Timer    timer;
 
             m_arrValues.clear();
@@ -418,7 +442,7 @@ namespace map2 {
             CppUnitMini::ThreadPool pool( *this );
             pool.add( new InserterThread( pool, testMap ), c_nInsertThreadCount );
             pool.add( new DeleterThread( pool, testMap ), c_nDeleteThreadCount );
             CppUnitMini::ThreadPool pool( *this );
             pool.add( new InserterThread( pool, testMap ), c_nInsertThreadCount );
             pool.add( new DeleterThread( pool, testMap ), c_nDeleteThreadCount );
-            pool.add( new EnsurerThread( pool, testMap ), c_nEnsureThreadCount );
+            pool.add( new UpdaterThread( pool, testMap ), c_nUpdateThreadCount );
             pool.run();
             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
 
             pool.run();
             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
 
@@ -428,9 +452,9 @@ namespace map2 {
             size_t nDeleteFailed = 0;
             size_t nDelValueSuccess = 0;
             size_t nDelValueFailed = 0;
             size_t nDeleteFailed = 0;
             size_t nDelValueSuccess = 0;
             size_t nDelValueFailed = 0;
-            size_t nEnsureFailed = 0;
-            size_t nEnsureCreated = 0;
-            size_t nEnsureModified = 0;
+            size_t nUpdateFailed = 0;
+            size_t nUpdateCreated = 0;
+            size_t nUpdateModified = 0;
             size_t nEnsFuncCreated = 0;
             size_t nEnsFuncModified = 0;
             size_t nTestFunctorRef = 0;
             size_t nEnsFuncCreated = 0;
             size_t nEnsFuncModified = 0;
             size_t nTestFunctorRef = 0;
@@ -451,10 +475,10 @@ namespace map2 {
                         nDelValueFailed += p->m_nValueFailed;
                     }
                     else {
                         nDelValueFailed += p->m_nValueFailed;
                     }
                     else {
-                        EnsurerThread * pEns = static_cast<EnsurerThread *>( *it );
-                        nEnsureCreated += pEns->m_nEnsureCreated;
-                        nEnsureModified += pEns->m_nEnsureExisted;
-                        nEnsureFailed += pEns->m_nEnsureFailed;
+                        UpdaterThread * pEns = static_cast<UpdaterThread *>( *it );
+                        nUpdateCreated += pEns->m_nUpdateCreated;
+                        nUpdateModified += pEns->m_nUpdateExisted;
+                        nUpdateFailed += pEns->m_nUpdateFailed;
                         nEnsFuncCreated += pEns->m_nFunctorCreated;
                         nEnsFuncModified += pEns->m_nFunctorModified;
                     }
                         nEnsFuncCreated += pEns->m_nFunctorCreated;
                         nEnsFuncModified += pEns->m_nFunctorModified;
                     }
@@ -465,18 +489,18 @@ namespace map2 {
                 << " Del succ=" << nDeleteSuccess << "\n"
                 << "          : Ins fail=" << nInsertFailed
                 << " Del fail=" << nDeleteFailed << "\n"
                 << " Del succ=" << nDeleteSuccess << "\n"
                 << "          : Ins fail=" << nInsertFailed
                 << " Del fail=" << nDeleteFailed << "\n"
-                << "          : Ensure succ=" << (nEnsureCreated + nEnsureModified) << " fail=" << nEnsureFailed
-                << " create=" << nEnsureCreated << " modify=" << nEnsureModified << "\n"
+                << "          : Update succ=" << (nUpdateCreated + nUpdateModified) << " fail=" << nUpdateFailed
+                << " create=" << nUpdateCreated << " modify=" << nUpdateModified << "\n"
                 << "          Map size=" << testMap.size()
                 );
 
             CPPUNIT_CHECK_EX( nDelValueFailed == 0, "Functor del failed=" << nDelValueFailed );
             CPPUNIT_CHECK_EX( nDelValueSuccess == nDeleteSuccess,  "Delete success=" << nDeleteSuccess << " functor=" << nDelValueSuccess );
 
                 << "          Map size=" << testMap.size()
                 );
 
             CPPUNIT_CHECK_EX( nDelValueFailed == 0, "Functor del failed=" << nDelValueFailed );
             CPPUNIT_CHECK_EX( nDelValueSuccess == nDeleteSuccess,  "Delete success=" << nDeleteSuccess << " functor=" << nDelValueSuccess );
 
-            CPPUNIT_CHECK( nEnsureFailed == 0 );
+            CPPUNIT_CHECK( nUpdateFailed == 0 );
 
 
-            CPPUNIT_CHECK_EX( nEnsureCreated == nEnsFuncCreated, "Ensure created=" << nEnsureCreated << " functor=" << nEnsFuncCreated );
-            CPPUNIT_CHECK_EX( nEnsureModified == nEnsFuncModified, "Ensure modified=" << nEnsureModified << " functor=" << nEnsFuncModified );
+            CPPUNIT_CHECK_EX( nUpdateCreated == nEnsFuncCreated, "Update created=" << nUpdateCreated << " functor=" << nEnsFuncCreated );
+            CPPUNIT_CHECK_EX( nUpdateModified == nEnsFuncModified, "Update modified=" << nUpdateModified << " functor=" << nEnsFuncModified );
 
             // nTestFunctorRef is call count of insert functor
             CPPUNIT_CHECK_EX( nTestFunctorRef == nInsertSuccess, "nInsertSuccess=" << nInsertSuccess << " functor nTestFunctorRef=" << nTestFunctorRef );
 
             // nTestFunctorRef is call count of insert functor
             CPPUNIT_CHECK_EX( nTestFunctorRef == nInsertSuccess, "nInsertSuccess=" << nInsertSuccess << " functor nTestFunctorRef=" << nTestFunctorRef );
@@ -497,63 +521,57 @@ namespace map2 {
         }
 
         template <class Map>
         }
 
         template <class Map>
-        void test()
+        void run_test()
         {
             CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
                 << " delete=" << c_nDeleteThreadCount
         {
             CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
                 << " delete=" << c_nDeleteThreadCount
-                << " ensure=" << c_nEnsureThreadCount
+                << " update=" << c_nUpdateThreadCount
                 << " pass count=" << c_nThreadPassCount
                 << " map size=" << c_nMapSize
                 );
 
                 << " pass count=" << c_nThreadPassCount
                 << " map size=" << c_nMapSize
                 );
 
-            for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
-                CPPUNIT_MSG( "Load factor=" << nLoadFactor );
-                Map  testMap( c_nMapSize, nLoadFactor );
+            if ( Map::c_bLoadFactorDepended ) {
+                for ( size_t c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
+                    CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
+                    Map  testMap( *this );
+                    do_test( testMap );
+                    if ( c_bPrintGCState )
+                        print_gc_state();
+                }
+            }
+            else {
+                Map testMap( *this );
                 do_test( testMap );
                 if ( c_bPrintGCState )
                     print_gc_state();
             }
                 do_test( testMap );
                 if ( c_bPrintGCState )
                     print_gc_state();
             }
-
-        }
-
-        template <class Map>
-        void test_nolf()
-        {
-            CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
-                << " delete=" << c_nDeleteThreadCount
-                << " ensure=" << c_nEnsureThreadCount
-                << " pass count=" << c_nThreadPassCount
-                << " map size=" << c_nMapSize
-                );
-
-            Map testMap;
-            do_test( testMap );
-            if ( c_bPrintGCState )
-                print_gc_state();
         }
 
         typedef CppUnitMini::TestCase Base;
         void setUpParams( const CppUnitMini::TestCfg& cfg );
 
         }
 
         typedef CppUnitMini::TestCase Base;
         void setUpParams( const CppUnitMini::TestCfg& cfg );
 
-        void run_MichaelMap(const char *in_name, bool invert = false);
-        void run_SplitList(const char *in_name, bool invert = false);
-        void run_StripedMap(const char *in_name, bool invert = false);
-        void run_RefinableMap(const char *in_name, bool invert = false);
-        void run_CuckooMap(const char *in_name, bool invert = false);
-        void run_SkipListMap(const char *in_name, bool invert = false);
-        void run_EllenBinTreeMap(const char *in_name, bool invert = false);
-        void run_BronsonAVLTreeMap(const char *in_name, bool invert = false);
-
-        virtual void myRun(const char *in_name, bool invert = false);
-
 #   include "map2/map_defs.h"
 #   include "map2/map_defs.h"
-    CDSUNIT_DECLARE_MichaelMap
-    CDSUNIT_DECLARE_SplitList
-    CDSUNIT_DECLARE_SkipListMap
-    CDSUNIT_DECLARE_EllenBinTreeMap
-    CDSUNIT_DECLARE_BronsonAVLTreeMap
-    CDSUNIT_DECLARE_StripedMap
-    CDSUNIT_DECLARE_RefinableMap
-    CDSUNIT_DECLARE_CuckooMap
+        CDSUNIT_DECLARE_MichaelMap
+        CDSUNIT_DECLARE_SplitList
+        CDSUNIT_DECLARE_SkipListMap
+        CDSUNIT_DECLARE_EllenBinTreeMap
+        CDSUNIT_DECLARE_BronsonAVLTreeMap
+        CDSUNIT_DECLARE_MultiLevelHashMap
+        CDSUNIT_DECLARE_StripedMap
+        CDSUNIT_DECLARE_RefinableMap
+        CDSUNIT_DECLARE_CuckooMap
+
+        CPPUNIT_TEST_SUITE(Map_InsDel_func)
+            CDSUNIT_TEST_MichaelMap
+            CDSUNIT_TEST_SplitList
+            CDSUNIT_TEST_SkipListMap
+            CDSUNIT_TEST_EllenBinTreeMap
+            CDSUNIT_TEST_BronsonAVLTreeMap
+            CDSUNIT_TEST_MultiLevelHashMap
+            CDSUNIT_TEST_CuckooMap
+            CDSUNIT_TEST_StripedMap
+            CDSUNIT_TEST_RefinableMap
+        CPPUNIT_TEST_SUITE_END();
+
     };
 } // namespace map2
     };
 } // namespace map2
index 0c03dfc7e347e91f4ff7d92726666701002328a5..585311f7f032754491185898fb05a6bfad6964dd 100644 (file)
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_bronson_avltree.h"
 
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_bronson_avltree.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_BronsonAVLTreeMap( cc::bronson_avltree::implementation_tag, Map_InsDel_func)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_BronsonAVLTreeMap )
-        CDSUNIT_TEST_BronsonAVLTreeMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_BronsonAVLTreeMap
 } // namespace map2
 } // namespace map2
index 272e46af96019a4232f81ee31f0f6f3c1f5aa412..257562f47689c8f6cfc7edbba64cf918e9777a9e 100644 (file)
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_cuckoo.h"
 
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_cuckoo.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_CuckooMap(cds::intrusive::cuckoo::implementation_tag, Map_InsDel_func)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_CuckooMap )
-        CDSUNIT_TEST_CuckooMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_CuckooMap
 } // namespace map2
 } // namespace map2
index 3eca4dc27473909b04b7c630c80adf8910d0984c..450aa441ef856faf504d3e45568170a84696612f 100644 (file)
@@ -3,11 +3,10 @@
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_ellen_bintree.h"
 
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_ellen_bintree.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_EllenBinTreeMap( cc::ellen_bintree::implementation_tag, Map_InsDel_func)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_EllenBinTreeMap )
-        CDSUNIT_TEST_EllenBinTreeMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_EllenBinTreeMap
 } // namespace map2
 } // namespace map2
-
index 7ef1c98288649fa4051d71e52dedd4a701adb221..733c8332562640bf17d955245de0ccffa2e19347 100644 (file)
@@ -3,10 +3,10 @@
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_michael.h"
 
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_michael.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_MichaelMap( cc::michael_map::implementation_tag, Map_InsDel_func )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_MichaelMap )
-        CDSUNIT_TEST_MichaelMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_MichaelMap
 } // namespace map2
 } // namespace map2
diff --git a/tests/unit/map2/map_insdel_func_multilevelhashmap.cpp b/tests/unit/map2/map_insdel_func_multilevelhashmap.cpp
new file mode 100644 (file)
index 0000000..d215334
--- /dev/null
@@ -0,0 +1,12 @@
+//$$CDS-header$$
+
+#include "map2/map_insdel_func.h"
+#include "map2/map_type_multilevel_hashmap.h"
+
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
+
+namespace map2 {
+    CDSUNIT_DECLARE_MultiLevelHashMap
+} // namespace map2
diff --git a/tests/unit/map2/map_insdel_func_refinable.cpp b/tests/unit/map2/map_insdel_func_refinable.cpp
deleted file mode 100644 (file)
index 9203731..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-//$$CDS-header$$
-
-#include "map2/map_insdel_func.h"
-#include "map2/map_type_striped.h"
-
-namespace map2 {
-    CDSUNIT_DEFINE_RefinableMap(cc::striped_set::implementation_tag, Map_InsDel_func)
-
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_RefinableMap )
-        CDSUNIT_TEST_RefinableMap
-    CPPUNIT_TEST_SUITE_END_PART()
-} // namespace map2
index d0ba06701fa1fe52f493353b6f4f91ab8f80fb0a..106f6bad623dcbc0f2c91004ceca252ceaf55833 100644 (file)
@@ -3,11 +3,10 @@
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_skip_list.h"
 
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_skip_list.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_SkipListMap( cc::skip_list::implementation_tag, Map_InsDel_func)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_SkipListMap )
-        CDSUNIT_TEST_SkipListMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_SkipListMap
 } // namespace map2
 } // namespace map2
-
index d7761456b86a6887d078ecaf6f0a3442719bf10e..b6c732fb7038d3d54bfd97ef84c0353155e9aafa 100644 (file)
@@ -3,11 +3,10 @@
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_split_list.h"
 
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_split_list.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_SplitList( cc::split_list::implementation_tag, Map_InsDel_func )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_SplitList )
-        CDSUNIT_TEST_SplitList
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_SplitList
 } // namespace map2
 } // namespace map2
-
index 424184cecc320b51e5463bd88fa2e4b8041a20ae..b48e8c21b8e7e92c14cae3532904c64d4ee75e3c 100644 (file)
@@ -3,10 +3,11 @@
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_striped.h"
 
 #include "map2/map_insdel_func.h"
 #include "map2/map_type_striped.h"
 
-namespace map2 {
-    CDSUNIT_DEFINE_StripedMap(cc::striped_set::implementation_tag, Map_InsDel_func)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X)  void Map_InsDel_func::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
 
 
-    CPPUNIT_TEST_SUITE_PART( Map_InsDel_func, run_StripedMap )
-        CDSUNIT_TEST_StripedMap
-    CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+    CDSUNIT_DECLARE_StripedMap
+    CDSUNIT_DECLARE_RefinableMap
 } // namespace map2
 } // namespace map2