2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
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 std::ostream& dump( std::ostream& stm ) { return stm; }
129 static CDS_CONSTEXPR bool const c_bExtractSupported = false;
130 static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
131 static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
134 template <typename Key, typename Value, typename Lock,
135 class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<std::pair<Key const, Value> >::other
138 : public std::unordered_map<
147 typedef std::unique_lock<Lock> scoped_lock;
148 typedef std::unordered_map<
155 typedef typename base_class::mapped_type value_type;
156 typedef size_t item_counter;
161 template <class Config>
162 StdHashMap( Config const& )
165 bool contains( const Key& key )
167 scoped_lock al( m_lock );
168 return base_class::find( key ) != base_class::end();
171 bool insert( const Key& key, const Value& val )
173 scoped_lock al( m_lock );
174 return base_class::insert( typename base_class::value_type(key, val)).second;
177 template <typename T, typename Func>
178 bool insert( const Key& key, const T& val, Func func )
180 scoped_lock al( m_lock );
181 std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type(key, Value() ));
183 func( pRet.first->second, val );
189 template <typename T, typename Func>
190 std::pair<bool, bool> update( const T& key, Func func, bool /*bAllowInsert*/ = true )
192 scoped_lock al( m_lock );
193 std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value() ));
195 func( true, *pRet.first );
196 return std::make_pair( true, true );
199 func( false, *pRet.first );
200 return std::make_pair( true, false );
204 bool erase( const Key& key )
206 scoped_lock al( m_lock );
207 return base_class::erase( key ) != 0;
210 template <typename T, typename Func>
211 bool erase( const T& key, Func func )
213 scoped_lock al( m_lock );
214 typename base_class::iterator it = base_class::find( key );
215 if ( it != base_class::end() ) {
217 return base_class::erase( key ) != 0;
222 std::ostream& dump( std::ostream& stm ) { return stm; }
226 static CDS_CONSTEXPR bool const c_bExtractSupported = false;
227 static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
228 static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
233 template <typename Key, typename Value>
234 struct map_type< tag_StdMap, Key, Value >: public map_type_base< Key, Value >
236 typedef map_type_base< Key, Value > base_class;
237 typedef typename base_class::key_compare compare;
238 typedef typename base_class::key_less less;
240 typedef StdMap< Key, Value, cds::sync::spin > StdMap_Spin;
241 typedef StdMap< Key, Value, std::mutex > StdMap_Mutex;
242 typedef StdMap< Key, Value, empty_lock> StdMap_NoLock;
244 typedef StdHashMap< Key, Value, cds::sync::spin > StdHashMap_Spin;
245 typedef StdHashMap< Key, Value, std::mutex > StdHashMap_Mutex;
246 typedef StdHashMap< Key, Value, empty_lock > StdHashMap_NoLock;
250 #define CDSSTRESS_StdMap_case( fixture, test_case, std_map_type, key_type, value_type ) \
251 TEST_F( fixture, std_map_type ) \
253 typedef map::map_type< tag_StdMap, key_type, value_type >::std_map_type map_type; \
254 test_case<map_type>(); \
257 #define CDSSTRESS_StdMap( fixture, test_case, key_type, value_type ) \
258 CDSSTRESS_StdMap_case( fixture, test_case, StdMap_Spin, key_type, value_type ) \
259 CDSSTRESS_StdMap_case( fixture, test_case, StdMap_Mutex, key_type, value_type ) \
260 CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_Spin, key_type, value_type ) \
261 CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_Mutex, key_type, value_type )
263 #define CDSSTRESS_StdMap_nolock( fixture, test_case, key_type, value_type ) \
264 CDSSTRESS_StdMap_case( fixture, test_case, StdMap_NoLock, key_type, value_type ) \
265 CDSSTRESS_StdMap_case( fixture, test_case, StdHashMap_NoLock, key_type, value_type )
267 #endif // ifndef CDSUNIT_MAP_TYPE_STD_H