2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSUNIT_MAP_TYPE_STD_H
32 #define CDSUNIT_MAP_TYPE_STD_H
37 #include <unordered_map>
47 template <typename Key, typename Value, typename Lock,
48 class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<std::pair<Key const, Value> >::other
50 class StdMap: public std::map<Key, Value, std::less<Key>, Alloc>
53 typedef std::unique_lock<Lock> scoped_lock;
54 typedef std::map<Key, Value, std::less<Key>, Alloc> base_class;
56 typedef typename base_class::mapped_type value_type;
57 typedef typename base_class::value_type pair_type;
58 typedef size_t item_counter;
63 template <class Config>
64 StdMap( Config const& )
67 bool contains( const Key& key )
69 scoped_lock al( m_lock );
70 return base_class::find( key ) != base_class::end();
73 bool insert( const Key& key, const Value& val )
75 scoped_lock al( m_lock );
76 return base_class::insert( typename base_class::value_type( key, val )).second;
79 template <typename T, typename Func>
80 bool insert( const Key& key, const T& val, Func func )
82 scoped_lock al( m_lock );
83 std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value()));
85 func( pRet.first->second, val );
91 template <typename T, typename Func>
92 std::pair<bool, bool> update( const T& key, Func func, bool /*bAllowInsert*/ = true )
94 scoped_lock al( m_lock );
95 std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value()));
97 func( true, *pRet.first );
98 return std::make_pair( true, true );
101 func( false, *pRet.first );
102 return std::make_pair( true, false );
106 bool erase( const Key& key )
108 scoped_lock al( m_lock );
109 return base_class::erase( key ) != 0;
112 template <typename T, typename Func>
113 bool erase( const T& key, Func func )
115 scoped_lock al( m_lock );
116 typename base_class::iterator it = base_class::find( key );
117 if ( it != base_class::end()) {
119 base_class::erase( it );
125 empty_stat statistics() const
131 static CDS_CONSTEXPR bool const c_bExtractSupported = false;
132 static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
133 static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
136 template <typename Key, typename Value, typename Lock,
137 class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<std::pair<Key const, Value> >::other
140 : public std::unordered_map<
149 typedef std::unique_lock<Lock> scoped_lock;
150 typedef std::unordered_map<
157 typedef typename base_class::mapped_type value_type;
158 typedef size_t item_counter;
163 template <class Config>
164 StdHashMap( Config const& )
167 bool contains( const Key& key )
169 scoped_lock al( m_lock );
170 return base_class::find( key ) != base_class::end();
173 bool insert( const Key& key, const Value& val )
175 scoped_lock al( m_lock );
176 return base_class::insert( typename base_class::value_type(key, val)).second;
179 template <typename T, typename Func>
180 bool insert( const Key& key, const T& val, Func func )
182 scoped_lock al( m_lock );
183 std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type(key, Value()));
185 func( pRet.first->second, val );
191 template <typename T, typename Func>
192 std::pair<bool, bool> update( const T& key, Func func, bool /*bAllowInsert*/ = true )
194 scoped_lock al( m_lock );
195 std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value()));
197 func( true, *pRet.first );
198 return std::make_pair( true, true );
201 func( false, *pRet.first );
202 return std::make_pair( true, false );
206 bool erase( const Key& key )
208 scoped_lock al( m_lock );
209 return base_class::erase( key ) != 0;
212 template <typename T, typename Func>
213 bool erase( const T& key, Func func )
215 scoped_lock al( m_lock );
216 typename base_class::iterator it = base_class::find( key );
217 if ( it != base_class::end()) {
219 return base_class::erase( key ) != 0;
224 empty_stat statistics() const
231 static CDS_CONSTEXPR bool const c_bExtractSupported = false;
232 static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
233 static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
238 template <typename Key, typename Value>
239 struct map_type< tag_StdMap, Key, Value >: public map_type_base< Key, Value >
241 typedef map_type_base< Key, Value > base_class;
242 typedef typename base_class::key_compare compare;
243 typedef typename base_class::key_less less;
245 typedef StdMap< Key, Value, cds::sync::spin > StdMap_Spin;
246 typedef StdMap< Key, Value, std::mutex > StdMap_Mutex;
247 typedef StdMap< Key, Value, empty_lock> StdMap_NoLock;
249 typedef StdHashMap< Key, Value, cds::sync::spin > StdHashMap_Spin;
250 typedef StdHashMap< Key, Value, std::mutex > StdHashMap_Mutex;
251 typedef StdHashMap< Key, Value, empty_lock > StdHashMap_NoLock;
256 #define CDSSTRESS_StdMap_case( fixture, test_case, std_map_type, key_type, value_type ) \
257 TEST_F( fixture, std_map_type ) \
259 typedef map::map_type< tag_StdMap, key_type, value_type >::std_map_type map_type; \
260 test_case<map_type>(); \
263 #define CDSSTRESS_StdMap( fixture, test_case, key_type, value_type ) \
264 CDSSTRESS_StdMap_case( fixture, test_case, StdMap_Spin, key_type, value_type ) \
265 CDSSTRESS_StdMap_case( fixture, test_case, StdMap_Mutex, key_type, value_type ) \
266 CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_Spin, key_type, value_type ) \
267 CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_Mutex, key_type, value_type )
269 #define CDSSTRESS_StdMap_nolock( fixture, test_case, key_type, value_type ) \
270 CDSSTRESS_StdMap_case( fixture, test_case, StdMap_NoLock, key_type, value_type ) \
271 CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_NoLock, key_type, value_type )
273 #endif // ifndef CDSUNIT_MAP_TYPE_STD_H