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_INTRUSIVE_FELDMAN_HASHSET_RCU_H
32 #define CDSUNIT_SET_TEST_INTRUSIVE_FELDMAN_HASHSET_RCU_H
34 #include "test_intrusive_feldman_hashset.h"
36 #include <cds/intrusive/feldman_hashset_rcu.h>
38 namespace ci = cds::intrusive;
39 namespace co = cds::opt;
42 class IntrusiveFeldmanHashSet : public cds_test::intrusive_feldman_hashset
44 typedef cds_test::intrusive_feldman_hashset base_class;
47 typedef cds::urcu::gc<RCU> rcu_type;
52 // Precondition: set is empty
53 // Postcondition: set is empty
55 base_class::test( s );
57 ASSERT_TRUE( s.empty());
58 ASSERT_CONTAINER_SIZE( s, 0 );
60 typedef typename Set::value_type value_type;
61 size_t const nSetSize = std::max( s.head_size() * 2, static_cast<size_t>(100));
63 std::vector< value_type > data;
64 std::vector< size_t> indices;
65 data.reserve( nSetSize );
66 indices.reserve( nSetSize );
67 for ( size_t key = 0; key < nSetSize; ++key ) {
68 data.push_back( value_type( static_cast<int>(key)));
69 indices.push_back( key );
71 shuffle( indices.begin(), indices.end());
73 typename Set::exempt_ptr xp;
75 typedef typename Set::rcu_lock rcu_lock;
77 // get/extract from empty set
78 for ( auto idx : indices ) {
87 xp = s.extract( i.key());
92 for ( auto& i : data ) {
94 ASSERT_TRUE( s.insert( i ));
98 for ( auto idx : indices ) {
103 EXPECT_EQ( i.nFindCount, 0u );
104 rp = s.get( i.key());
107 EXPECT_EQ( i.nFindCount, 1u );
110 EXPECT_EQ( i.nEraseCount, 0u );
111 xp = s.extract( i.key());
114 EXPECT_EQ( i.nEraseCount, 1u );
116 xp = s.extract( i.key());
120 ASSERT_TRUE( s.empty());
121 ASSERT_CONTAINER_SIZE( s, 0 );
123 // Force retiring cycle
124 Set::gc::force_dispose();
125 for ( auto& i : data ) {
126 EXPECT_EQ( i.nDisposeCount, 1u );
133 cds::threading::Manager::attachThread();
138 cds::threading::Manager::detachThread();
143 TYPED_TEST_CASE_P( IntrusiveFeldmanHashSet );
145 TYPED_TEST_P( IntrusiveFeldmanHashSet, compare )
147 typedef typename TestFixture::rcu_type rcu_type;
149 struct traits : public ci::feldman_hashset::traits
151 typedef typename TestFixture::hash_accessor hash_accessor;
152 typedef typename TestFixture::cmp compare;
153 typedef typename TestFixture::mock_disposer disposer;
156 typedef ci::FeldmanHashSet< rcu_type, typename TestFixture::int_item, traits > set_type;
162 TYPED_TEST_P( IntrusiveFeldmanHashSet, less )
164 typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item,
165 typename ci::feldman_hashset::make_traits<
166 ci::feldman_hashset::hash_accessor< typename TestFixture::hash_accessor >
167 , ci::opt::less< std::less<int>>
168 , ci::opt::disposer< typename TestFixture::mock_disposer>
176 TYPED_TEST_P( IntrusiveFeldmanHashSet, cmpmix )
178 struct traits : public ci::feldman_hashset::traits
180 typedef typename TestFixture::hash_accessor hash_accessor;
181 typedef typename TestFixture::cmp compare;
182 typedef std::less<int> less;
183 typedef typename TestFixture::mock_disposer disposer;
184 typedef typename TestFixture::simple_item_counter item_counter;
187 typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item, traits > set_type;
193 TYPED_TEST_P( IntrusiveFeldmanHashSet, backoff )
195 struct traits : public ci::feldman_hashset::traits
197 typedef typename TestFixture::hash_accessor hash_accessor;
198 typedef typename TestFixture::cmp compare;
199 typedef typename TestFixture::mock_disposer disposer;
200 typedef cds::backoff::empty back_off;
201 typedef ci::opt::v::sequential_consistent memory_model;
204 typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item, traits > set_type;
210 TYPED_TEST_P( IntrusiveFeldmanHashSet, stat )
212 struct traits : public ci::feldman_hashset::traits
214 typedef typename TestFixture::hash_accessor hash_accessor;
215 typedef typename TestFixture::cmp compare;
216 typedef typename TestFixture::mock_disposer disposer;
217 typedef ci::feldman_hashset::stat<> stat;
220 typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item, traits > set_type;
226 TYPED_TEST_P( IntrusiveFeldmanHashSet, explicit_hash_size )
228 struct traits: public ci::feldman_hashset::traits
230 typedef typename TestFixture::hash_accessor2 hash_accessor;
232 hash_size = sizeof( std::declval<typename TestFixture::key_val>().nKey )
234 typedef typename TestFixture::cmp2 compare;
235 typedef typename TestFixture::mock_disposer disposer;
236 typedef ci::feldman_hashset::stat<> stat;
239 typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item2, traits > set_type;
245 // GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as
246 // "No test named <test_name> can be found in this test case"
247 REGISTER_TYPED_TEST_CASE_P( IntrusiveFeldmanHashSet,
248 compare, less, cmpmix, backoff, stat, explicit_hash_size
252 #endif // #ifndef CDSUNIT_SET_TEST_INTRUSIVE_FELDMAN_HASHSET_RCU_H