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_SET_TEST_FELDMAN_HASHSET_RCU_H
32 #define CDSUNIT_SET_TEST_FELDMAN_HASHSET_RCU_H
34 #include "test_feldman_hashset.h"
36 #include <cds/container/feldman_hashset_rcu.h>
40 namespace cc = cds::container;
42 template <typename RCU>
43 class FeldmanHashSet: public cds_test::feldman_hashset
45 typedef cds_test::feldman_hashset base_class;
48 typedef cds::urcu::gc<RCU> rcu_type;
50 template <typename Set>
53 // Precondition: set is empty
54 // Postcondition: set is empty
56 ASSERT_TRUE( s.empty());
57 ASSERT_CONTAINER_SIZE( s, 0 );
59 base_class::test( s );
61 typedef typename Set::value_type value_type;
63 size_t const nSetSize = kSize;
64 std::vector< value_type > data;
65 std::vector< size_t> indices;
66 data.reserve( kSize );
67 indices.reserve( kSize );
68 for ( size_t key = 0; key < kSize; ++key ) {
69 data.push_back( value_type( static_cast<int>(key)));
70 indices.push_back( key );
72 shuffle( indices.begin(), indices.end());
74 for ( auto& i : data ) {
75 ASSERT_TRUE( s.insert( i ));
77 ASSERT_FALSE( s.empty());
78 ASSERT_CONTAINER_SIZE( s, nSetSize );
80 typedef typename Set::rcu_lock rcu_lock;
86 for ( auto it = s.begin(); it != s.end(); ++it ) {
87 it->nFindCount = it->key() * 3;
90 for ( auto it = s.cbegin(); it != s.cend(); ++it ) {
91 EXPECT_EQ( it->nFindCount, static_cast<size_t>( it->key() * 3 ));
94 for ( auto it = s.rbegin(); it != s.rend(); ++it ) {
95 it->nFindCount = it->key() * 2;
98 for ( auto it = s.crbegin(); it != s.crend(); ++it ) {
99 EXPECT_EQ( it->nFindCount, static_cast<size_t>( it->key() * 2 ));
103 typedef typename Set::exempt_ptr exempt_ptr;
106 for ( auto idx : indices ) {
111 value_type * p = s.get( i.key());
112 ASSERT_TRUE( p != nullptr );
113 EXPECT_EQ( p->key(), i.key());
114 EXPECT_EQ( p->nFindCount, static_cast<size_t>( i.key() * 2 ));
121 for ( auto idx : indices ) {
125 xp = s.extract( i.key());
127 EXPECT_EQ( xp->key(), i.key());
128 EXPECT_EQ( xp->nFindCount, static_cast<size_t>( i.key() * 4 ));
130 xp = s.extract( i.key());
135 value_type * p = s.get( i.key());
136 EXPECT_TRUE( p == nullptr );
140 ASSERT_TRUE( s.empty());
141 ASSERT_CONTAINER_SIZE( s, 0 );
147 cds::threading::Manager::attachThread();
152 cds::threading::Manager::detachThread();
157 TYPED_TEST_CASE_P( FeldmanHashSet );
159 TYPED_TEST_P( FeldmanHashSet, defaulted )
161 typedef typename TestFixture::rcu_type rcu_type;
162 typedef typename TestFixture::int_item int_item;
163 typedef typename TestFixture::get_hash get_hash;
165 typedef cc::FeldmanHashSet< rcu_type, int_item,
166 typename cc::feldman_hashset::make_traits<
167 cc::feldman_hashset::hash_accessor< get_hash >
175 TYPED_TEST_P( FeldmanHashSet, compare )
177 typedef typename TestFixture::rcu_type rcu_type;
178 typedef typename TestFixture::int_item int_item;
179 typedef typename TestFixture::get_hash get_hash;
181 typedef cc::FeldmanHashSet< rcu_type, int_item,
182 typename cc::feldman_hashset::make_traits<
183 cc::feldman_hashset::hash_accessor< get_hash >
184 , cds::opt::compare< typename TestFixture::cmp >
192 TYPED_TEST_P( FeldmanHashSet, less )
194 typedef typename TestFixture::rcu_type rcu_type;
195 typedef typename TestFixture::int_item int_item;
196 typedef typename TestFixture::get_hash get_hash;
198 typedef cc::FeldmanHashSet< rcu_type, int_item,
199 typename cc::feldman_hashset::make_traits<
200 cc::feldman_hashset::hash_accessor< get_hash >
201 , cds::opt::less< std::less<int> >
209 TYPED_TEST_P( FeldmanHashSet, cmpmix )
211 typedef typename TestFixture::rcu_type rcu_type;
212 typedef typename TestFixture::int_item int_item;
213 typedef typename TestFixture::get_hash get_hash;
215 typedef cc::FeldmanHashSet< rcu_type, int_item,
216 typename cc::feldman_hashset::make_traits<
217 cc::feldman_hashset::hash_accessor< get_hash >
218 , cds::opt::less< std::less<int> >
219 , cds::opt::compare< typename TestFixture::cmp >
227 TYPED_TEST_P( FeldmanHashSet, item_counting )
229 typedef typename TestFixture::rcu_type rcu_type;
230 typedef typename TestFixture::int_item int_item;
231 typedef typename TestFixture::get_hash get_hash;
233 struct set_traits: public cc::feldman_hashset::traits
235 typedef get_hash hash_accessor;
236 typedef typename TestFixture::cmp compare;
237 typedef std::less<int> less;
238 typedef typename TestFixture::simple_item_counter item_counter;
240 typedef cc::FeldmanHashSet< rcu_type, int_item, set_traits > set_type;
246 TYPED_TEST_P( FeldmanHashSet, backoff )
248 typedef typename TestFixture::rcu_type rcu_type;
249 typedef typename TestFixture::int_item int_item;
250 typedef typename TestFixture::get_hash get_hash;
252 struct set_traits: public cc::feldman_hashset::traits
254 typedef get_hash hash_accessor;
255 typedef typename TestFixture::cmp compare;
256 typedef cds::atomicity::item_counter item_counter;
257 typedef cds::backoff::yield back_off;
259 typedef cc::FeldmanHashSet< rcu_type, int_item, set_traits > set_type;
265 TYPED_TEST_P( FeldmanHashSet, stat )
267 typedef typename TestFixture::rcu_type rcu_type;
268 typedef typename TestFixture::int_item int_item;
269 typedef typename TestFixture::get_hash get_hash;
271 struct set_traits: public cc::feldman_hashset::traits
273 typedef get_hash hash_accessor;
274 typedef cds::backoff::yield back_off;
275 typedef cc::feldman_hashset::stat<> stat;
277 typedef cc::FeldmanHashSet< rcu_type, int_item, set_traits > set_type;
283 TYPED_TEST_P( FeldmanHashSet, explicit_hash_size )
285 typedef typename TestFixture::rcu_type rcu_type;
286 typedef typename TestFixture::int_item2 int_item;
287 typedef typename TestFixture::get_hash2 get_hash2;
289 struct set_traits: public cc::feldman_hashset::traits
292 hash_size = sizeof( std::declval<int_item>().nKey )
294 typedef get_hash2 hash_accessor;
295 typedef typename TestFixture::cmp2 compare;
296 typedef cc::feldman_hashset::stat<> stat;
298 typedef cc::FeldmanHashSet< rcu_type, int_item, set_traits > set_type;
304 // GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as
305 // "No test named <test_name> can be found in this test case"
306 REGISTER_TYPED_TEST_CASE_P( FeldmanHashSet,
307 defaulted, compare, less, cmpmix, item_counting, backoff, stat, explicit_hash_size
311 #endif // CDSUNIT_SET_TEST_FELDMAN_HASHSET_RCU_H