Migrated map-insfind-int stress test to gtest
[libcds.git] / tests / unit / map2 / map_type_ellen_bintree.h
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 #ifndef CDSUNIT_MAP_TYPE_ELLEN_BINTREE_H
32 #define CDSUNIT_MAP_TYPE_ELLEN_BINTREE_H
33
34 #include "map2/map_type.h"
35
36 #include <cds/container/ellen_bintree_map_rcu.h>
37 #include <cds/container/ellen_bintree_map_hp.h>
38 #include <cds/container/ellen_bintree_map_dhp.h>
39
40 #include "ellen_bintree_update_desc_pool.h"
41 #include "print_ellenbintree_stat.h"
42
43 namespace map2 {
44
45     template <class GC, typename Key, typename T, typename Traits = cc::ellen_bintree::traits >
46     class EllenBinTreeMap : public cc::EllenBinTreeMap< GC, Key, T, Traits >
47     {
48         typedef cc::EllenBinTreeMap< GC, Key, T, Traits > base_class;
49     public:
50         template <typename Config>
51         EllenBinTreeMap( Config const& /*cfg*/)
52             : base_class()
53         {}
54
55         // for testing
56         static CDS_CONSTEXPR bool const c_bExtractSupported = true;
57         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
58         static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
59     };
60
61     struct tag_EllenBinTreeMap;
62
63     template <typename Key, typename Value>
64     struct map_type< tag_EllenBinTreeMap, Key, Value >: public map_type_base< Key, Value >
65     {
66         typedef map_type_base< Key, Value > base_class;
67         typedef typename base_class::compare    compare;
68         typedef typename base_class::less       less;
69
70         struct ellen_bintree_props {
71             struct hp_gc {
72                 typedef cc::ellen_bintree::map_node<cds::gc::HP, Key, Value>        leaf_node;
73                 typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
74                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
75             };
76             struct dhp_gc {
77                 typedef cc::ellen_bintree::map_node<cds::gc::DHP, Key, Value>       leaf_node;
78                 typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
79                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
80             };
81             struct gpi {
82                 typedef cc::ellen_bintree::map_node<rcu_gpi, Key, Value>            leaf_node;
83                 typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
84                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
85             };
86             struct gpb {
87                 typedef cc::ellen_bintree::map_node<rcu_gpb, Key, Value>            leaf_node;
88                 typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
89                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
90             };
91             struct gpt {
92                 typedef cc::ellen_bintree::map_node<rcu_gpt, Key, Value>            leaf_node;
93                 typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
94                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
95             };
96 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
97             struct shb {
98                 typedef cc::ellen_bintree::map_node<rcu_shb, Key, Value>            leaf_node;
99                 typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
100                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
101             };
102             struct sht {
103                 typedef cc::ellen_bintree::map_node<rcu_sht, Key, Value>            leaf_node;
104                 typedef cc::ellen_bintree::internal_node< Key, leaf_node >          internal_node;
105                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
106             };
107 #endif
108         };
109
110         struct traits_EllenBinTreeMap: public cc::ellen_bintree::make_set_traits<
111                 co::less< less >
112                 ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
113                 ,co::item_counter< cds::atomicity::item_counter >
114             >::type
115         {};
116         struct traits_EllenBinTreeMap_hp : traits_EllenBinTreeMap {
117             typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
118         };
119         typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_hp >EllenBinTreeMap_hp;
120
121         struct traits_EllenBinTreeMap_dhp : traits_EllenBinTreeMap {
122             typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
123         };
124         typedef EllenBinTreeMap< cds::gc::DHP, Key, Value, traits_EllenBinTreeMap_dhp >EllenBinTreeMap_dhp;
125
126         struct traits_EllenBinTreeMap_gpi : traits_EllenBinTreeMap {
127             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpi::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
128         };
129         typedef EllenBinTreeMap< rcu_gpi, Key, Value, traits_EllenBinTreeMap_gpi >EllenBinTreeMap_rcu_gpi;
130
131         struct traits_EllenBinTreeMap_gpb : traits_EllenBinTreeMap {
132             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
133         };
134         typedef EllenBinTreeMap< rcu_gpb, Key, Value, traits_EllenBinTreeMap_gpb >EllenBinTreeMap_rcu_gpb;
135
136         struct traits_EllenBinTreeMap_gpt : traits_EllenBinTreeMap {
137             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpt::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
138         };
139         typedef EllenBinTreeMap< rcu_gpt, Key, Value, traits_EllenBinTreeMap_gpt >EllenBinTreeMap_rcu_gpt;
140
141 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
142         struct traits_EllenBinTreeMap_shb : traits_EllenBinTreeMap {
143             typedef cds::memory::pool_allocator< typename ellen_bintree_props::shb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
144         };
145         typedef EllenBinTreeMap< rcu_shb, Key, Value, traits_EllenBinTreeMap_shb >EllenBinTreeMap_rcu_shb;
146
147         struct traits_EllenBinTreeMap_sht : traits_EllenBinTreeMap {
148             typedef cds::memory::pool_allocator< typename ellen_bintree_props::sht::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
149         };
150         typedef EllenBinTreeMap< rcu_sht, Key, Value, traits_EllenBinTreeMap_sht >EllenBinTreeMap_rcu_sht;
151 #endif
152
153         struct traits_EllenBinTreeMap_yield : public traits_EllenBinTreeMap
154         {
155             typedef cds::backoff::yield back_off;
156         };
157         struct traits_EllenBinTreeMap_hp_yield : traits_EllenBinTreeMap_yield {
158             typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
159         };
160         typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_hp_yield >EllenBinTreeMap_hp_yield;
161
162         struct traits_EllenBinTreeMap_dhp_yield : traits_EllenBinTreeMap_yield {
163             typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
164         };
165         typedef EllenBinTreeMap< cds::gc::DHP, Key, Value, traits_EllenBinTreeMap_dhp_yield >EllenBinTreeMap_dhp_yield;
166
167         struct traits_EllenBinTreeMap_gpb_yield : traits_EllenBinTreeMap_yield {
168             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
169         };
170         typedef EllenBinTreeMap< rcu_gpb, Key, Value, traits_EllenBinTreeMap_gpb_yield >EllenBinTreeMap_rcu_gpb_yield;
171
172
173         struct traits_EllenBinTreeMap_stat: public cc::ellen_bintree::make_set_traits<
174                 co::less< less >
175                 ,cc::ellen_bintree::update_desc_allocator<
176                     cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor >
177                 >
178                 ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
179                 ,co::stat< cc::ellen_bintree::stat<> >
180                 ,co::item_counter< cds::atomicity::item_counter >
181             >::type
182         {};
183
184         struct traits_EllenBinTreeMap_stat_hp : public traits_EllenBinTreeMap_stat
185         {
186             typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
187         };
188         typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_stat_hp > EllenBinTreeMap_hp_stat;
189
190         struct traits_EllenBinTreeMap_stat_dhp : public traits_EllenBinTreeMap_stat
191         {
192             typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
193         };
194         typedef EllenBinTreeMap< cds::gc::HP, Key, Value, traits_EllenBinTreeMap_stat_dhp > EllenBinTreeMap_dhp_stat;
195
196         struct traits_EllenBinTreeMap_stat_gpi : public traits_EllenBinTreeMap_stat
197         {
198             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpi::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
199         };
200         typedef EllenBinTreeMap< rcu_gpi, Key, Value, traits_EllenBinTreeMap_stat_gpi > EllenBinTreeMap_rcu_gpi_stat;
201
202         struct traits_EllenBinTreeMap_stat_gpb : public traits_EllenBinTreeMap_stat
203         {
204             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
205         };
206         typedef EllenBinTreeMap< rcu_gpb, Key, Value, traits_EllenBinTreeMap_stat_gpb > EllenBinTreeMap_rcu_gpb_stat;
207
208         struct traits_EllenBinTreeMap_stat_gpt : public traits_EllenBinTreeMap_stat
209         {
210             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpt::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
211         };
212         typedef EllenBinTreeMap< rcu_gpt, Key, Value, traits_EllenBinTreeMap_stat_gpt > EllenBinTreeMap_rcu_gpt_stat;
213
214 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
215         struct traits_EllenBinTreeMap_stat_shb : public traits_EllenBinTreeMap_stat
216         {
217             typedef cds::memory::pool_allocator< typename ellen_bintree_props::shb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
218         };
219         typedef EllenBinTreeMap< rcu_shb, Key, Value, traits_EllenBinTreeMap_stat_shb > EllenBinTreeMap_rcu_shb_stat;
220
221         struct traits_EllenBinTreeMap_stat_sht : public traits_EllenBinTreeMap_stat
222         {
223             typedef cds::memory::pool_allocator< typename ellen_bintree_props::sht::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
224         };
225         typedef EllenBinTreeMap< rcu_sht, Key, Value, traits_EllenBinTreeMap_stat_sht > EllenBinTreeMap_rcu_sht_stat;
226 #endif
227     };
228
229     template <typename GC, typename Key, typename T, typename Traits>
230     static inline void print_stat( EllenBinTreeMap<GC, Key, T, Traits> const& s )
231     {
232         CPPUNIT_MSG( s.statistics() );
233     }
234     template <typename GC, typename Key, typename T, typename Traits>
235     static inline void additional_cleanup( EllenBinTreeMap<GC, Key, T, Traits>& /*s*/ )
236     {
237         ellen_bintree_pool::internal_node_counter::reset();
238     }
239     namespace ellen_bintree_check {
240         static inline void check_stat( cds::intrusive::ellen_bintree::empty_stat const& /*s*/ )
241         {
242             // This check is not valid for thread-based RCU
243             /*
244             CPPUNIT_CHECK_CURRENT_EX( ellen_bintree_pool::internal_node_counter::m_nAlloc.get() == ellen_bintree_pool::internal_node_counter::m_nFree.get(),
245                 "m_nAlloc=" << ellen_bintree_pool::internal_node_counter::m_nAlloc.get()
246                 << ", m_nFree=" << ellen_bintree_pool::internal_node_counter::m_nFree.get()
247                 );
248             */
249         }
250
251         static inline void check_stat( cds::intrusive::ellen_bintree::stat<> const& stat )
252         {
253             CPPUNIT_CHECK_CURRENT_EX( stat.m_nInternalNodeCreated == stat.m_nInternalNodeDeleted,
254                 "m_nInternalNodeCreated=" << stat.m_nInternalNodeCreated
255                 << " m_nInternalNodeDeleted=" << stat.m_nInternalNodeDeleted );
256             CPPUNIT_CHECK_CURRENT_EX( stat.m_nUpdateDescCreated == stat.m_nUpdateDescDeleted,
257                 "m_nUpdateDescCreated=" << stat.m_nUpdateDescCreated
258                 << " m_nUpdateDescDeleted=" << stat.m_nUpdateDescDeleted );
259             CPPUNIT_CHECK_CURRENT_EX( ellen_bintree_pool::internal_node_counter::m_nAlloc.get() == stat.m_nInternalNodeCreated,
260                 "allocated=" << ellen_bintree_pool::internal_node_counter::m_nAlloc.get()
261                 << "m_nInternalNodeCreated=" << stat.m_nInternalNodeCreated );
262         }
263     }   // namespace ellen_bintree_check
264     template <typename GC, typename Key, typename T, typename Traits>
265     static inline void additional_check( EllenBinTreeMap<GC, Key, T, Traits>& s )
266     {
267         GC::force_dispose();
268         ellen_bintree_check::check_stat( s.statistics() );
269     }
270
271     template <typename GC, typename Key, typename T, typename Traits>
272     static inline void check_before_cleanup( EllenBinTreeMap<GC, Key, T, Traits>& m )
273     {
274         CPPUNIT_MSG( "  Check internal consistency (single-threaded)..." );
275         CPPUNIT_CHECK_CURRENT( m.check_consistency() );
276     }
277 }   // namespace map2
278
279 #endif // ifndef CDSUNIT_MAP_TYPE_ELLEN_BINTREE_H