Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / test / unit / intrusive-set / intrusive_split_michael_dhp.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-2017
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/michael_list_dhp.h>
34 #include <cds/intrusive/split_list.h>
35 #include <cds/intrusive/free_list.h>
36
37 namespace {
38     namespace ci = cds::intrusive;
39     typedef cds::gc::DHP gc_type;
40
41     class IntrusiveSplitListSet_DHP : public cds_test::intrusive_set_hp
42     {
43     protected:
44         typedef cds_test::intrusive_set_hp base_class;
45
46     protected:
47         typedef typename base_class::base_int_item< ci::split_list::node< ci::michael_list::node<gc_type>>>   base_item_type;
48         typedef typename base_class::member_int_item< ci::split_list::node< ci::michael_list::node<gc_type>>> member_item_type;
49
50         void SetUp()
51         {
52             struct list_traits : public ci::michael_list::traits
53             {
54                 typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
55             };
56             typedef ci::MichaelList< gc_type, base_item_type, list_traits > list_type;
57             typedef ci::SplitListSet< gc_type, list_type >   set_type;
58
59             cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount );
60             cds::threading::Manager::attachThread();
61         }
62
63         void TearDown()
64         {
65             cds::threading::Manager::detachThread();
66             cds::gc::dhp::smr::destruct();
67         }
68     };
69
70
71     TEST_F( IntrusiveSplitListSet_DHP, base_cmp )
72     {
73         typedef ci::MichaelList< gc_type
74             , base_item_type
75             ,ci::michael_list::make_traits<
76                 ci::opt::hook< ci::michael_list::base_hook< ci::opt::gc< gc_type > > >
77                 ,ci::opt::compare< cmp<base_item_type> >
78                 ,ci::opt::disposer< mock_disposer >
79             >::type
80         > bucket_type;
81
82         typedef ci::SplitListSet< gc_type, bucket_type,
83             ci::split_list::make_traits<
84                 ci::opt::hash< hash_int >
85             >::type
86         > set_type;
87
88         set_type s( kSize, 2 );
89         test( s );
90     }
91
92     TEST_F( IntrusiveSplitListSet_DHP, base_less )
93     {
94         typedef ci::MichaelList< gc_type
95             , base_item_type
96             ,ci::michael_list::make_traits<
97                 ci::opt::hook< ci::michael_list::base_hook< ci::opt::gc< gc_type >>>
98                 ,ci::opt::less< less<base_item_type> >
99                 ,ci::opt::disposer< mock_disposer >
100             >::type
101         > bucket_type;
102
103         typedef ci::SplitListSet< gc_type, bucket_type,
104             ci::split_list::make_traits<
105                 ci::opt::hash< hash_int >
106                 ,ci::opt::item_counter< cds::atomicity::item_counter >
107             >::type
108         > set_type;
109
110         set_type s( kSize, 2 );
111         test( s );
112     }
113
114     TEST_F( IntrusiveSplitListSet_DHP, base_cmpmix )
115     {
116         struct list_traits : public ci::michael_list::traits
117         {
118             typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
119             typedef base_class::less<base_item_type> less;
120             typedef cmp<base_item_type> compare;
121             typedef mock_disposer disposer;
122         };
123         typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
124
125         struct set_traits : public ci::split_list::traits
126         {
127             typedef hash_int hash;
128             typedef simple_item_counter item_counter;
129             typedef ci::split_list::stat<> stat;
130         };
131         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
132
133         set_type s( kSize, 2 );
134         test( s );
135     }
136
137     TEST_F( IntrusiveSplitListSet_DHP, base_static_bucket_table )
138     {
139         struct list_traits: public ci::michael_list::traits
140         {
141             typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
142             typedef base_class::less<base_item_type> less;
143             typedef cmp<base_item_type> compare;
144             typedef mock_disposer disposer;
145         };
146         typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
147
148         struct set_traits: public ci::split_list::traits
149         {
150             typedef hash_int hash;
151             typedef simple_item_counter item_counter;
152             typedef ci::split_list::stat<> stat;
153             enum {
154                 dynamic_bucket_table = false
155             };
156         };
157         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
158
159         set_type s( kSize, 2 );
160         test( s );
161     }
162
163     TEST_F( IntrusiveSplitListSet_DHP, base_static_bucket_table_free_list )
164     {
165         struct list_traits: public ci::michael_list::traits
166         {
167             typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
168             typedef cmp<base_item_type> compare;
169             typedef mock_disposer disposer;
170         };
171         typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
172
173         struct set_traits: public ci::split_list::traits
174         {
175             typedef hash_int hash;
176             typedef simple_item_counter item_counter;
177             typedef ci::split_list::stat<> stat;
178             enum {
179                 dynamic_bucket_table = false
180             };
181             typedef ci::FreeList free_list;
182         };
183         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
184
185         set_type s( kSize, 2 );
186         test( s );
187     }
188
189     TEST_F( IntrusiveSplitListSet_DHP, base_free_list )
190     {
191         struct list_traits: public ci::michael_list::traits
192         {
193             typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
194             typedef base_class::less<base_item_type> less;
195             typedef mock_disposer disposer;
196         };
197         typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
198
199         struct set_traits: public ci::split_list::traits
200         {
201             typedef hash_int hash;
202             typedef simple_item_counter item_counter;
203             typedef ci::split_list::stat<> stat;
204             typedef ci::FreeList free_list;
205         };
206         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
207
208         set_type s( kSize, 2 );
209         test( s );
210     }
211
212     TEST_F( IntrusiveSplitListSet_DHP, member_cmp )
213     {
214         typedef ci::MichaelList< gc_type
215             ,member_item_type
216             ,ci::michael_list::make_traits<
217                 ci::opt::hook< ci::michael_list::member_hook<
218                     offsetof( member_item_type, hMember ),
219                     ci::opt::gc<gc_type>
220                 > >
221                 ,ci::opt::compare< cmp<member_item_type> >
222                 ,ci::opt::disposer< mock_disposer >
223             >::type
224         >    bucket_type;
225
226         typedef ci::SplitListSet< gc_type, bucket_type,
227             ci::split_list::make_traits<
228                 ci::opt::hash< hash_int >
229             >::type
230         > set_type;
231
232         set_type s( kSize, 2 );
233         test( s );
234     }
235
236     TEST_F( IntrusiveSplitListSet_DHP, member_less )
237     {
238         typedef ci::MichaelList< gc_type
239             , member_item_type
240             ,ci::michael_list::make_traits<
241                 ci::opt::hook< ci::michael_list::member_hook<
242                     offsetof( member_item_type, hMember ),
243                     ci::opt::gc<gc_type>
244                 > >
245                 ,ci::opt::less< less<member_item_type> >
246                 ,ci::opt::disposer< mock_disposer >
247             >::type
248         > bucket_type;
249
250         typedef ci::SplitListSet< gc_type, bucket_type,
251             ci::split_list::make_traits<
252                 ci::opt::hash< hash_int >
253                 ,ci::opt::back_off< cds::backoff::pause >
254             >::type
255         > set_type;
256
257         set_type s( kSize, 2 );
258         test( s );
259     }
260
261     TEST_F( IntrusiveSplitListSet_DHP, member_cmpmix )
262     {
263         struct list_traits : public ci::michael_list::traits
264         {
265             typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
266             typedef base_class::less<member_item_type> less;
267             typedef cmp<member_item_type> compare;
268             typedef mock_disposer disposer;
269         };
270         typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
271
272         struct set_traits : public ci::split_list::traits
273         {
274             typedef hash_int hash;
275             typedef simple_item_counter item_counter;
276         };
277         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
278
279         set_type s( kSize, 2 );
280         test( s );
281     }
282
283     TEST_F( IntrusiveSplitListSet_DHP, member_static_bucket_table )
284     {
285         struct list_traits: public ci::michael_list::traits
286         {
287             typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
288             typedef base_class::less<member_item_type> less;
289             typedef cmp<member_item_type> compare;
290             typedef mock_disposer disposer;
291         };
292         typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
293
294         struct set_traits: public ci::split_list::traits
295         {
296             typedef hash_int hash;
297             typedef simple_item_counter item_counter;
298             enum {
299                 dynami_bucket_table = false
300             };
301         };
302         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
303
304         set_type s( kSize, 2 );
305         test( s );
306     }
307
308     TEST_F( IntrusiveSplitListSet_DHP, member_static_bucket_table_free_list )
309     {
310         struct list_traits: public ci::michael_list::traits
311         {
312             typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
313             typedef base_class::less<member_item_type> less;
314             typedef mock_disposer disposer;
315         };
316         typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
317
318         struct set_traits: public ci::split_list::traits
319         {
320             typedef hash_int hash;
321             typedef simple_item_counter item_counter;
322             enum {
323                 dynami_bucket_table = false
324             };
325             typedef ci::FreeList free_list;
326         };
327         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
328
329         set_type s( kSize, 2 );
330         test( s );
331     }
332
333     TEST_F( IntrusiveSplitListSet_DHP, member_free_list )
334     {
335         struct list_traits: public ci::michael_list::traits
336         {
337             typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
338             typedef base_class::less<member_item_type> less;
339             typedef mock_disposer disposer;
340         };
341         typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
342
343         struct set_traits: public ci::split_list::traits
344         {
345             typedef hash_int hash;
346             typedef simple_item_counter item_counter;
347             typedef ci::FreeList free_list;
348         };
349         typedef ci::SplitListSet< gc_type, bucket_type, set_traits > set_type;
350
351         set_type s( kSize, 2 );
352         test( s );
353     }
354
355 } // namespace