Added update desc pool to intrusive EllenBinTree unit test
[libcds.git] / test / unit / tree / intrusive_ellenbintree_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_tree_hp.h"
32
33 #include <cds/intrusive/ellen_bintree_hp.h>
34 #include <cds/memory/vyukov_queue_pool.h>
35 #include <cds/memory/pool_allocator.h>
36
37 namespace {
38     namespace ci = cds::intrusive;
39     typedef cds::gc::HP gc_type;
40
41     class IntrusiveEllenBinTree_HP : public cds_test::intrusive_tree_hp
42     {
43     protected:
44         typedef cds_test::intrusive_tree_hp base_class;
45
46     protected:
47         typedef base_class::key_type key_type;
48
49         typedef typename base_class::base_int_item< ci::ellen_bintree::node<gc_type>> base_item_type;
50         typedef ci::ellen_bintree::internal_node< key_type, base_item_type >          internal_base_node;
51         typedef ci::ellen_bintree::update_desc< base_item_type, internal_base_node >  update_base_desc;
52
53         typedef typename base_class::member_int_item< ci::ellen_bintree::node<gc_type>>  member_item_type;
54         typedef ci::ellen_bintree::internal_node< key_type, member_item_type >           internal_member_node;
55         typedef ci::ellen_bintree::update_desc< member_item_type, internal_member_node > update_member_desc;
56
57         // update_desc pools
58         struct pool_traits: public cds::memory::vyukov_queue_pool_traits
59         {
60             typedef cds::opt::v::static_buffer< update_base_desc, 256 > buffer;
61         };
62         typedef cds::memory::vyukov_queue_pool< update_base_desc, pool_traits > pool_type;
63         typedef cds::memory::lazy_vyukov_queue_pool< update_base_desc, pool_traits > lazy_pool_type;
64
65         static pool_type *         s_Pool;
66         static lazy_pool_type *    s_LazyPool;
67
68         struct pool_accessor
69         {
70             typedef pool_type::value_type value_type;
71
72             pool_type& operator()() const
73             {
74                 return *s_Pool;
75             }
76         };
77
78         struct lazy_pool_accessor
79         {
80             typedef lazy_pool_type::value_type value_type;
81
82             lazy_pool_type& operator()() const
83             {
84                 return *s_LazyPool;
85             }
86         };
87
88         static void SetUpTestCase()
89         {
90             ASSERT_TRUE( s_Pool == nullptr );
91             ASSERT_TRUE( s_LazyPool == nullptr );
92             s_Pool = new pool_type;
93             s_LazyPool = new lazy_pool_type;
94         }
95
96         static void TearDownTestCase()
97         {
98             ASSERT_TRUE( s_Pool != nullptr );
99             ASSERT_TRUE( s_LazyPool != nullptr );
100             delete s_LazyPool;
101             delete s_Pool;
102
103             s_LazyPool = nullptr;
104             s_Pool = nullptr;
105         }
106
107         void SetUp()
108         {
109             struct list_traits : public ci::ellen_bintree::traits
110             {
111                 typedef ci::ellen_bintree::base_hook< ci::opt::gc<gc_type>> hook;
112             };
113             typedef ci::EllenBinTree< gc_type, key_type, base_item_type > tree_type;
114
115             // +1 - for guarded_ptr
116             cds::gc::hp::GarbageCollector::Construct( tree_type::c_nHazardPtrCount + 1, 1, 16 );
117             cds::threading::Manager::attachThread();
118         }
119
120         void TearDown()
121         {
122             cds::threading::Manager::detachThread();
123             cds::gc::hp::GarbageCollector::Destruct( true );
124         }
125
126         struct generic_traits: public ci::ellen_bintree::traits
127         {
128             typedef base_class::key_extractor key_extractor;
129             typedef mock_disposer disposer;
130         };
131     };
132
133     /*static*/ IntrusiveEllenBinTree_HP::pool_type *         IntrusiveEllenBinTree_HP::s_Pool = nullptr;
134     /*static*/ IntrusiveEllenBinTree_HP::lazy_pool_type *    IntrusiveEllenBinTree_HP::s_LazyPool = nullptr;
135
136
137     TEST_F( IntrusiveEllenBinTree_HP, base_cmp )
138     {
139         typedef ci::EllenBinTree< gc_type, key_type, base_item_type,
140             ci::ellen_bintree::make_traits< 
141                 ci::opt::type_traits< generic_traits >
142                 ,ci::opt::hook< ci::ellen_bintree::base_hook< ci::opt::gc< gc_type >>>
143                 ,ci::opt::compare< cmp<base_item_type>>
144             >::type
145         > tree_type;
146
147         tree_type t;
148         test( t );
149     }
150
151     TEST_F( IntrusiveEllenBinTree_HP, base_less )
152     {
153         typedef ci::EllenBinTree< gc_type, key_type, base_item_type,
154             ci::ellen_bintree::make_traits< 
155                 ci::opt::type_traits< generic_traits >
156                 ,ci::opt::hook< ci::ellen_bintree::base_hook< ci::opt::gc< gc_type >>>
157                 ,ci::opt::less< less<base_item_type>>
158             >::type
159         > tree_type;
160
161         tree_type t;
162         test( t );
163     }
164
165     TEST_F( IntrusiveEllenBinTree_HP, base_item_counter )
166     {
167         typedef ci::EllenBinTree< gc_type, key_type, base_item_type,
168             ci::ellen_bintree::make_traits< 
169                 ci::opt::type_traits< generic_traits >
170                 ,ci::opt::hook< ci::ellen_bintree::base_hook< ci::opt::gc< gc_type >>>
171                 ,ci::opt::compare< cmp<base_item_type>>
172                 ,ci::opt::item_counter< simple_item_counter >
173             >::type
174         > tree_type;
175
176         tree_type t;
177         test( t );
178     }
179
180     TEST_F( IntrusiveEllenBinTree_HP, base_backoff )
181     {
182         struct tree_traits: public generic_traits
183         {
184             typedef ci::ellen_bintree::base_hook< ci::opt::gc< gc_type >> hook;
185             typedef cmp<base_item_type> compare;
186             typedef base_class::less<base_item_type> less;
187             typedef cds::atomicity::item_counter item_counter;
188             typedef cds::backoff::yield back_off;
189         };
190
191         typedef ci::EllenBinTree< gc_type, key_type, base_item_type, tree_traits > tree_type;
192
193         tree_type t;
194         test( t );
195     }
196
197     TEST_F( IntrusiveEllenBinTree_HP, base_seq_cst )
198     {
199         struct tree_traits: public generic_traits
200         {
201             typedef ci::ellen_bintree::base_hook< ci::opt::gc< gc_type >> hook;
202             typedef cmp<base_item_type> compare;
203             typedef base_class::less<base_item_type> less;
204             typedef cds::atomicity::item_counter item_counter;
205             typedef cds::backoff::pause back_off;
206             typedef ci::opt::v::sequential_consistent memory_model;
207         };
208
209         typedef ci::EllenBinTree< gc_type, key_type, base_item_type, tree_traits > tree_type;
210
211         tree_type t;
212         test( t );
213     }
214
215     TEST_F( IntrusiveEllenBinTree_HP, base_update_desc_pool )
216     {
217         struct tree_traits: public generic_traits
218         {
219             typedef ci::ellen_bintree::base_hook< ci::opt::gc< gc_type >> hook;
220             typedef base_class::less<base_item_type> less;
221             typedef cds::atomicity::item_counter item_counter;
222             typedef cds::memory::pool_allocator<update_base_desc, pool_accessor> update_desc_allocator;
223         };
224
225         typedef ci::EllenBinTree< gc_type, key_type, base_item_type, tree_traits > tree_type;
226
227         tree_type t;
228         test( t );
229     }
230
231     TEST_F( IntrusiveEllenBinTree_HP, base_update_desc_lazy_pool )
232     {
233         struct tree_traits: public generic_traits
234         {
235             typedef ci::ellen_bintree::base_hook< ci::opt::gc< gc_type >> hook;
236             typedef base_class::less<base_item_type> less;
237             typedef cds::atomicity::item_counter item_counter;
238             typedef cds::memory::pool_allocator<update_base_desc, lazy_pool_accessor> update_desc_allocator;
239         };
240
241         typedef ci::EllenBinTree< gc_type, key_type, base_item_type, tree_traits > tree_type;
242
243         tree_type t;
244         test( t );
245     }
246
247     // member hook
248     TEST_F( IntrusiveEllenBinTree_HP, member_cmp )
249     {
250         typedef ci::EllenBinTree< gc_type, key_type, member_item_type,
251             ci::ellen_bintree::make_traits< 
252                 ci::opt::type_traits< generic_traits >
253                 ,ci::opt::hook< ci::ellen_bintree::member_hook< offsetof( member_item_type, hMember), ci::opt::gc< gc_type >>>
254                 ,ci::opt::compare< cmp<member_item_type>>
255             >::type
256         > tree_type;
257
258         tree_type t;
259         test( t );
260     }
261
262     TEST_F( IntrusiveEllenBinTree_HP, member_less )
263     {
264         typedef ci::EllenBinTree< gc_type, key_type, member_item_type,
265             ci::ellen_bintree::make_traits< 
266                 ci::opt::type_traits< generic_traits >
267                 ,ci::opt::hook< ci::ellen_bintree::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc< gc_type >>>
268                 ,ci::opt::less< less<member_item_type>>
269             >::type
270         > tree_type;
271
272         tree_type t;
273         test( t );
274     }
275
276     TEST_F( IntrusiveEllenBinTree_HP, member_item_counter )
277     {
278         typedef ci::EllenBinTree< gc_type, key_type, member_item_type,
279             ci::ellen_bintree::make_traits< 
280                 ci::opt::type_traits< generic_traits >
281                 ,ci::opt::hook< ci::ellen_bintree::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc< gc_type >>>
282                 ,ci::opt::compare< cmp<member_item_type>>
283                 ,ci::opt::item_counter< simple_item_counter >
284             >::type
285         > tree_type;
286
287         tree_type t;
288         test( t );
289     }
290
291     TEST_F( IntrusiveEllenBinTree_HP, member_backoff )
292     {
293         struct tree_traits: public generic_traits
294         {
295             typedef ci::ellen_bintree::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc< gc_type >> hook;
296             typedef cmp<member_item_type> compare;
297             typedef base_class::less<member_item_type> less;
298             typedef cds::atomicity::item_counter item_counter;
299             typedef cds::backoff::yield back_off;
300         };
301
302         typedef ci::EllenBinTree< gc_type, key_type, member_item_type, tree_traits > tree_type;
303
304         tree_type t;
305         test( t );
306     }
307
308     TEST_F( IntrusiveEllenBinTree_HP, member_seq_cst )
309     {
310         struct tree_traits: public generic_traits
311         {
312             typedef ci::ellen_bintree::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc< gc_type >> hook;
313             typedef cmp<member_item_type> compare;
314             typedef base_class::less<member_item_type> less;
315             typedef cds::atomicity::item_counter item_counter;
316             typedef cds::backoff::pause back_off;
317             typedef ci::opt::v::sequential_consistent memory_model;
318         };
319
320         typedef ci::EllenBinTree< gc_type, key_type, member_item_type, tree_traits > tree_type;
321
322         tree_type t;
323         test( t );
324     }
325
326     TEST_F( IntrusiveEllenBinTree_HP, member_update_desc_pool )
327     {
328         struct tree_traits: public generic_traits
329         {
330             typedef ci::ellen_bintree::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc< gc_type >> hook;
331             typedef base_class::less<member_item_type> less;
332             typedef cds::atomicity::item_counter item_counter;
333             typedef cds::memory::pool_allocator<update_member_desc, pool_accessor> update_desc_allocator;
334         };
335
336         typedef ci::EllenBinTree< gc_type, key_type, member_item_type, tree_traits > tree_type;
337
338         tree_type t;
339         test( t );
340     }
341
342     TEST_F( IntrusiveEllenBinTree_HP, member_update_desc_lazy_pool )
343     {
344         struct tree_traits: public generic_traits
345         {
346             typedef ci::ellen_bintree::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc< gc_type >> hook;
347             typedef base_class::less<member_item_type> less;
348             typedef cds::atomicity::item_counter item_counter;
349             typedef cds::memory::pool_allocator<update_member_desc, lazy_pool_accessor> update_desc_allocator;
350         };
351
352         typedef ci::EllenBinTree< gc_type, key_type, member_item_type, tree_traits > tree_type;
353
354         tree_type t;
355         test( t );
356     }
357
358 } // namespace