Merge branch 'dev'
[libcds.git] / test / unit / intrusive-set / intrusive_michael_lazy_hp.cpp
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
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.
18
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.     
29 */
30
31 #include "test_intrusive_set_hp.h"
32
33 #include <cds/intrusive/lazy_list_hp.h>
34 #include <cds/intrusive/michael_set.h>
35
36 #include <mutex>
37
38 namespace {
39     namespace ci = cds::intrusive;
40     typedef cds::gc::HP gc_type;
41
42     class IntrusiveMichaelLazySet_HP : public cds_test::intrusive_set_hp
43     {
44     protected:
45         typedef cds_test::intrusive_set_hp base_class;
46
47     protected:
48         typedef typename base_class::base_int_item< ci::lazy_list::node<gc_type>>   base_item_type;
49         typedef typename base_class::base_int_item< ci::lazy_list::node<gc_type, std::mutex>>   base_mutex_item_type;
50         typedef typename base_class::member_int_item< ci::lazy_list::node<gc_type>> member_item_type;
51         typedef typename base_class::member_int_item< ci::lazy_list::node<gc_type, std::mutex>> member_mutex_item_type;
52
53         void SetUp()
54         {
55             struct list_traits : public ci::lazy_list::traits
56             {
57                 typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>> hook;
58             };
59             typedef ci::LazyList< gc_type, base_item_type, list_traits > list_type;
60             typedef ci::MichaelHashSet< gc_type, list_type >   set_type;
61
62             // +1 - for guarded_ptr
63             cds::gc::hp::GarbageCollector::Construct( set_type::c_nHazardPtrCount + 1, 1, 16 );
64             cds::threading::Manager::attachThread();
65         }
66
67         void TearDown()
68         {
69             cds::threading::Manager::detachThread();
70             cds::gc::hp::GarbageCollector::Destruct( true );
71         }
72     };
73
74
75     TEST_F( IntrusiveMichaelLazySet_HP, base_cmp )
76     {
77         typedef ci::LazyList< gc_type
78             , base_item_type
79             ,ci::lazy_list::make_traits<
80                 ci::opt::hook< ci::lazy_list::base_hook< ci::opt::gc< gc_type > > >
81                 ,ci::opt::compare< cmp<base_item_type> >
82                 ,ci::opt::disposer< mock_disposer >
83                 ,ci::opt::back_off< cds::backoff::pause >
84             >::type
85         > bucket_type;
86
87         typedef ci::MichaelHashSet< gc_type, bucket_type,
88             ci::michael_set::make_traits<
89                 ci::opt::hash< hash_int >
90             >::type
91         > set_type;
92
93         set_type s( kSize, 2 );
94         test( s );
95     }
96
97     TEST_F( IntrusiveMichaelLazySet_HP, base_less )
98     {
99         typedef ci::LazyList< gc_type
100             , base_item_type
101             ,ci::lazy_list::make_traits<
102                 ci::opt::hook< ci::lazy_list::base_hook< ci::opt::gc< gc_type >>>
103                 ,ci::opt::less< less<base_item_type> >
104                 ,ci::opt::disposer< mock_disposer >
105             >::type
106         > bucket_type;
107
108         typedef ci::MichaelHashSet< gc_type, bucket_type,
109             ci::michael_set::make_traits<
110                 ci::opt::hash< hash_int >
111             >::type
112         > set_type;
113
114         set_type s( kSize, 2 );
115         test( s );
116     }
117
118     TEST_F( IntrusiveMichaelLazySet_HP, base_cmpmix )
119     {
120         struct list_traits : public ci::lazy_list::traits
121         {
122             typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>> hook;
123             typedef base_class::less<base_item_type> less;
124             typedef cmp<base_item_type> compare;
125             typedef mock_disposer disposer;
126         };
127         typedef ci::LazyList< gc_type, base_item_type, list_traits > bucket_type;
128
129         struct set_traits : public ci::michael_set::traits
130         {
131             typedef hash_int hash;
132             typedef simple_item_counter item_counter;
133         };
134         typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
135
136         set_type s( kSize, 2 );
137         test( s );
138     }
139
140     TEST_F( IntrusiveMichaelLazySet_HP, base_mutex )
141     {
142         struct list_traits : public ci::lazy_list::traits
143         {
144             typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>, ci::opt::lock_type<std::mutex>> hook;
145             typedef base_class::less<base_mutex_item_type> less;
146             typedef cmp<base_mutex_item_type> compare;
147             typedef mock_disposer disposer;
148         };
149         typedef ci::LazyList< gc_type, base_mutex_item_type, list_traits > bucket_type;
150
151         struct set_traits : public ci::michael_set::traits
152         {
153             typedef hash_int hash;
154             typedef simple_item_counter item_counter;
155         };
156         typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
157
158         set_type s( kSize, 2 );
159         test( s );
160     }
161
162
163     TEST_F( IntrusiveMichaelLazySet_HP, member_cmp )
164     {
165         typedef ci::LazyList< gc_type
166             ,member_item_type
167             ,ci::lazy_list::make_traits<
168                 ci::opt::hook< ci::lazy_list::member_hook<
169                     offsetof( member_item_type, hMember ),
170                     ci::opt::gc<gc_type>
171                 > >
172                 ,ci::opt::compare< cmp<member_item_type> >
173                 ,ci::opt::disposer< mock_disposer >
174             >::type
175         >    bucket_type;
176
177         typedef ci::MichaelHashSet< gc_type, bucket_type,
178             ci::michael_set::make_traits<
179                 ci::opt::hash< hash_int >
180             >::type
181         > set_type;
182
183         set_type s( kSize, 2 );
184         test( s );
185     }
186
187     TEST_F( IntrusiveMichaelLazySet_HP, member_less )
188     {
189         typedef ci::LazyList< gc_type
190             , member_item_type
191             ,ci::lazy_list::make_traits<
192                 ci::opt::hook< ci::lazy_list::member_hook<
193                     offsetof( member_item_type, hMember ),
194                     ci::opt::gc<gc_type>
195                 > >
196                 ,ci::opt::less< less<member_item_type> >
197                 ,ci::opt::disposer< mock_disposer >
198             >::type
199         > bucket_type;
200
201         typedef ci::MichaelHashSet< gc_type, bucket_type,
202             ci::michael_set::make_traits<
203                 ci::opt::hash< hash_int >
204             >::type
205         > set_type;
206
207         set_type s( kSize, 2 );
208         test( s );
209     }
210
211     TEST_F( IntrusiveMichaelLazySet_HP, member_cmpmix )
212     {
213         struct list_traits : public ci::lazy_list::traits
214         {
215             typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
216             typedef base_class::less<member_item_type> less;
217             typedef cmp<member_item_type> compare;
218             typedef mock_disposer disposer;
219         };
220         typedef ci::LazyList< gc_type, member_item_type, list_traits > bucket_type;
221
222         struct set_traits : public ci::michael_set::traits
223         {
224             typedef hash_int hash;
225             typedef simple_item_counter item_counter;
226         };
227         typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
228
229         set_type s( kSize, 2 );
230         test( s );
231     }
232
233     TEST_F( IntrusiveMichaelLazySet_HP, member_mutex )
234     {
235         struct list_traits : public ci::lazy_list::traits
236         {
237             typedef ci::lazy_list::member_hook< offsetof( member_mutex_item_type, hMember ), ci::opt::gc<gc_type>, ci::opt::lock_type<std::mutex>> hook;
238             typedef base_class::less<member_mutex_item_type> less;
239             typedef cmp<member_mutex_item_type> compare;
240             typedef mock_disposer disposer;
241         };
242         typedef ci::LazyList< gc_type, member_mutex_item_type, list_traits > bucket_type;
243
244         struct set_traits : public ci::michael_set::traits
245         {
246             typedef hash_int hash;
247             typedef simple_item_counter item_counter;
248         };
249         typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
250
251         set_type s( kSize, 2 );
252         test( s );
253     }
254
255 } // namespace