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_TEST_FELDMAN_HASHMAP_RCU_H
32 #define CDSUNIT_MAP_TEST_FELDMAN_HASHMAP_RCU_H
34 #include "test_feldman_hashmap.h"
35 #include <cds/container/feldman_hashmap_rcu.h>
39 template <typename RCU>
40 class FeldmanHashMap: public cds_test::feldman_hashmap
42 typedef cds_test::feldman_hashmap base_class;
45 typedef cds::urcu::gc<RCU> rcu_type;
50 // Precondition: map is empty
51 // Postcondition: map is empty
53 base_class::test( m );
55 ASSERT_TRUE( m.empty());
56 ASSERT_CONTAINER_SIZE( m, 0 );
58 typedef typename Map::key_type key_type;
59 typedef typename Map::mapped_type value_type;
60 typedef typename Map::value_type map_pair;
61 typedef typename Map::rcu_lock rcu_lock;
62 typedef typename Map::exempt_ptr exempt_ptr;
64 size_t const kkSize = base_class::kSize;
66 std::vector<key_type> arrKeys;
67 for ( int i = 0; i < static_cast<int>(kkSize); ++i )
68 arrKeys.push_back( key_type( i ));
69 shuffle( arrKeys.begin(), arrKeys.end());
71 std::vector< value_type > arrVals;
72 for ( size_t i = 0; i < kkSize; ++i ) {
74 val.nVal = static_cast<int>( i );
75 val.strVal = std::to_string( i );
76 arrVals.push_back( val );
79 for ( auto const& i : arrKeys )
80 ASSERT_TRUE( m.insert( i ));
81 ASSERT_FALSE( m.empty());
82 ASSERT_CONTAINER_SIZE( m, kkSize );
88 for ( auto it = m.begin(); it != m.end(); ++it ) {
89 EXPECT_EQ( it->second.nVal, 0 );
90 it->second.nVal = it->first.nKey * 2;
93 EXPECT_EQ( nCount, kkSize );
96 for ( auto it = m.cbegin(); it != m.cend(); ++it ) {
97 EXPECT_EQ( it->second.nVal, it->first.nKey * 2 );
100 EXPECT_EQ( nCount, kkSize );
103 for ( auto it = m.rbegin(); it != m.rend(); ++it ) {
104 EXPECT_EQ( it->second.nVal, it->first.nKey * 2 );
105 it->second.nVal = it->first.nKey * 4;
108 EXPECT_EQ( nCount, kkSize );
111 for ( auto it = m.crbegin(); it != m.crend(); ++it ) {
112 EXPECT_EQ( it->second.nVal, it->first.nKey * 4 );
115 EXPECT_EQ( nCount, kkSize );
121 for ( auto const& i : arrKeys ) {
122 value_type const& val = arrVals.at( i.nKey );
126 map_pair * p = m.get( i.nKey );
127 ASSERT_FALSE( p == nullptr );
128 EXPECT_EQ( p->first.nKey, i.nKey );
131 ASSERT_FALSE( p == nullptr );
132 EXPECT_EQ( p->first.nKey, i.nKey );
134 p = m.get( val.strVal );
135 ASSERT_FALSE( p == nullptr );
136 EXPECT_EQ( p->first.nKey, i.nKey );
139 switch ( i.nKey % 3 ) {
141 xp = m.extract( i.nKey );
147 xp = m.extract( val.strVal );
151 ASSERT_EQ( xp->first.nKey, i.nKey );
156 map_pair * p = m.get( i.nKey );
157 EXPECT_TRUE( p == nullptr );
159 EXPECT_TRUE( p == nullptr );
162 ASSERT_TRUE( m.empty());
163 ASSERT_CONTAINER_SIZE( m, 0 );
169 cds::threading::Manager::attachThread();
174 cds::threading::Manager::detachThread();
179 TYPED_TEST_CASE_P( FeldmanHashMap );
181 TYPED_TEST_P( FeldmanHashMap, defaulted )
183 typedef typename TestFixture::rcu_type rcu_type;
184 typedef typename TestFixture::key_type key_type;
185 typedef typename TestFixture::value_type value_type;
187 typedef cc::FeldmanHashMap< rcu_type, key_type, value_type > map_type;
193 TYPED_TEST_P( FeldmanHashMap, compare )
195 typedef typename TestFixture::rcu_type rcu_type;
196 typedef typename TestFixture::key_type key_type;
197 typedef typename TestFixture::value_type value_type;
199 typedef cc::FeldmanHashMap< rcu_type, key_type, value_type,
200 typename cc::feldman_hashmap::make_traits<
201 cds::opt::compare< typename TestFixture::cmp >
209 TYPED_TEST_P( FeldmanHashMap, less )
211 typedef typename TestFixture::rcu_type rcu_type;
212 typedef typename TestFixture::key_type key_type;
213 typedef typename TestFixture::value_type value_type;
215 typedef cc::FeldmanHashMap< rcu_type, key_type, value_type,
216 typename cc::feldman_hashmap::make_traits<
217 cds::opt::less< typename TestFixture::less >
225 TYPED_TEST_P( FeldmanHashMap, cmpmix )
227 typedef typename TestFixture::rcu_type rcu_type;
228 typedef typename TestFixture::key_type key_type;
229 typedef typename TestFixture::value_type value_type;
231 typedef cc::FeldmanHashMap< rcu_type, key_type, value_type,
232 typename cc::feldman_hashmap::make_traits<
233 cds::opt::less< typename TestFixture::less >
234 , cds::opt::compare< typename TestFixture::cmp >
242 TYPED_TEST_P( FeldmanHashMap, backoff )
244 typedef typename TestFixture::rcu_type rcu_type;
245 typedef typename TestFixture::key_type key_type;
246 typedef typename TestFixture::value_type value_type;
248 struct map_traits: public cc::feldman_hashmap::traits
250 typedef typename TestFixture::cmp compare;
251 typedef cds::atomicity::item_counter item_counter;
252 typedef cds::backoff::yield back_off;
254 typedef cc::FeldmanHashMap< rcu_type, key_type, value_type, map_traits > map_type;
260 TYPED_TEST_P( FeldmanHashMap, stat )
262 typedef typename TestFixture::rcu_type rcu_type;
263 typedef typename TestFixture::key_type key_type;
264 typedef typename TestFixture::value_type value_type;
266 struct map_traits: public cc::feldman_hashmap::traits
268 typedef cds::backoff::yield back_off;
269 typedef cc::feldman_hashmap::stat<> stat;
271 typedef cc::FeldmanHashMap< rcu_type, key_type, value_type, map_traits > map_type;
277 TYPED_TEST_P( FeldmanHashMap, explicit_key_size )
279 typedef typename TestFixture::rcu_type rcu_type;
280 typedef typename TestFixture::key_type2 key_type2;
281 typedef typename TestFixture::value_type value_type;
283 struct map_traits: public cc::feldman_hashmap::traits
286 hash_size = sizeof( int ) + sizeof( uint16_t )
288 typedef typename TestFixture::hash2 hash;
289 typedef typename TestFixture::less2 less;
290 typedef cc::feldman_hashmap::stat<> stat;
292 typedef cc::FeldmanHashMap< rcu_type, key_type2, value_type, map_traits > map_type;
295 EXPECT_EQ( m.head_size(), static_cast<size_t>(1 << 6));
296 EXPECT_EQ( m.array_node_size(), static_cast<size_t>(1 << 3));
300 TYPED_TEST_P( FeldmanHashMap, byte_cut )
302 typedef typename TestFixture::rcu_type rcu_type;
303 typedef typename TestFixture::key_type key_type;
304 typedef typename TestFixture::value_type value_type;
306 typedef cc::FeldmanHashMap< rcu_type, key_type, value_type,
307 typename cc::feldman_hashmap::make_traits<
308 cds::opt::compare< typename TestFixture::cmp >
309 , cc::feldman_hashmap::hash_splitter< cds::algo::byte_splitter< key_type >>
317 TYPED_TEST_P( FeldmanHashMap, byte_cut_explicit_key_size )
319 typedef typename TestFixture::rcu_type rcu_type;
320 typedef typename TestFixture::key_type2 key_type2;
321 typedef typename TestFixture::value_type value_type;
323 struct map_traits: public cc::feldman_hashmap::traits
326 hash_size = sizeof( int ) + sizeof( uint16_t )
328 typedef cds::algo::byte_splitter< key_type2, hash_size > hash_splitter;
329 typedef typename TestFixture::hash2 hash;
330 typedef typename TestFixture::less2 less;
331 typedef cc::feldman_hashmap::stat<> stat;
333 typedef cc::FeldmanHashMap< rcu_type, key_type2, value_type, map_traits > map_type;
340 // GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as
341 // "No test named <test_name> can be found in this test case"
342 REGISTER_TYPED_TEST_CASE_P( FeldmanHashMap,
343 defaulted, compare, less, cmpmix, backoff, stat, explicit_key_size, byte_cut, byte_cut_explicit_key_size
347 #endif // #ifndef CDSUNIT_MAP_TEST_FELDMAN_HASHMAP_RCU_H