f9f00992a9eb2e2127af31a9425704995cf65b78
[libcds.git] / tests / unit / set2 / set_type_feldman_hashset.h
1 //$$CDS-header$$
2
3 #ifndef CDSUNIT_SET_TYPE_MICHAEL_H
4 #define CDSUNIT_SET_TYPE_MICHAEL_H
5
6 #include "set2/set_type.h"
7
8 #include <cds/container/feldman_hashset_hp.h>
9 #include <cds/container/feldman_hashset_dhp.h>
10 #include <cds/container/feldman_hashset_rcu.h>
11
12 #include "print_feldman_hashset_stat.h"
13 #include "hashing/hash_func.h"
14
15 namespace set2 {
16
17     template <class GC, typename T, typename Traits = cc::feldman_hashset::traits>
18     class FeldmanHashSet : public cc::FeldmanHashSet< GC, T, Traits >
19     {
20         typedef cc::FeldmanHashSet< GC, T, Traits > base_class;
21
22         template <typename G>
23         struct get_extracted_ptr
24         {
25             typedef typename base_class::guarded_ptr extracted_ptr;
26         };
27
28         template <typename RCU>
29         struct get_extracted_ptr<cds::urcu::gc<RCU>>
30         {
31             typedef typename base_class::exempt_ptr extracted_ptr;
32         };
33
34     public:
35         typedef typename T::hasher hasher ;
36         typedef typename get_extracted_ptr<GC>::extracted_ptr extracted_ptr;
37
38         template <class Config>
39         FeldmanHashSet( Config const& cfg )
40             : base_class( cfg.c_nFeldmanSet_HeadBits, cfg.c_nFeldmanSet_ArrayBits )
41         {}
42
43         template <typename Q>
44         bool erase( Q const& key )
45         {
46             return base_class::erase( hasher()( key ));
47         }
48
49         template <typename Q, typename Func>
50         bool erase( Q const& key, Func f )
51         {
52             return base_class::erase( hasher()( key ), f );
53         }
54
55         template <typename Q>
56         extracted_ptr extract(Q const& key)
57         {
58             return base_class::extract( hasher()(key) );
59         }
60
61         template <typename Q>
62         bool contains( Q const& key )
63         {
64             return base_class::contains( hasher()(key) );
65         }
66
67         // for testing
68         static CDS_CONSTEXPR bool const c_bExtractSupported = true;
69         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
70         static CDS_CONSTEXPR bool const c_bEraseExactKey = true;
71     };
72
73     struct tag_FeldmanHashSet;
74
75     template <typename Key, typename Val>
76     struct set_type< tag_FeldmanHashSet, Key, Val >: public set_type_base< Key, Val >
77     {
78         typedef set_type_base< Key, Val > base_class;
79         typedef typename base_class::compare compare;
80         typedef typename base_class::less less;
81         typedef typename base_class::hash hash;
82         typedef typename base_class::key_type   key_type;
83         typedef typename base_class::value_type value_type;
84
85         template <typename Hasher>
86         struct hash_type
87         {
88             typedef Hasher hasher;
89             typedef typename hasher::hash_type type;
90         };
91
92         template <typename TH>
93         struct hash_type<std::hash<TH>>
94         {
95             typedef std::hash<TH> hasher;
96             typedef size_t type;
97         };
98
99         template <typename Hasher>
100         struct key_val: base_class::key_val
101         {
102             typedef typename base_class::key_val base;
103             typedef Hasher hasher;
104             typedef typename hash_type<hasher>::type hash_type;
105
106             hash_type hash;
107
108             /*explicit*/ key_val( key_type const& k ): base(k), hash( hasher()( k )) {}
109             key_val( key_type const& k, value_type const& v ): base(k, v), hash( hasher()( k )) {}
110
111             template <typename K>
112             /*explicit*/ key_val( K const& k ): base(k), hash( hasher()( k )) {}
113
114             template <typename K, typename T>
115             key_val( K const& k, T const& v ): base(k, v), hash( hasher()( k )) {}
116         };
117
118         struct default_traits : public cc::feldman_hashset::traits
119         {
120             struct hash_accessor {
121                 template <typename Hasher>
122                 typename key_val<Hasher>::hash_type const& operator()( key_val<Hasher> const& kv )
123                 {
124                     return kv.hash;
125                 }
126             };
127         };
128
129         typedef FeldmanHashSet< cds::gc::HP,  key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_hp_stdhash;
130         typedef FeldmanHashSet< cds::gc::DHP, key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_dhp_stdhash;
131         typedef FeldmanHashSet< rcu_gpi, key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_rcu_gpi_stdhash;
132         typedef FeldmanHashSet< rcu_gpb, key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_rcu_gpb_stdhash;
133         typedef FeldmanHashSet< rcu_gpt, key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_rcu_gpt_stdhash;
134 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
135         typedef FeldmanHashSet< rcu_shb, key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_rcu_shb_stdhash;
136         typedef FeldmanHashSet< rcu_sht, key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_rcu_sht_stdhash;
137 #endif
138
139         struct traits_FeldmanHashSet_stat: public cc::feldman_hashset::make_traits<
140                 co::type_traits< default_traits >,
141                 co::stat< cc::feldman_hashset::stat<>>
142             >::type
143         {};
144
145         typedef FeldmanHashSet< cds::gc::HP,  key_val<std::hash<key_type>>, traits_FeldmanHashSet_stat >    FeldmanHashSet_hp_stdhash_stat;
146         typedef FeldmanHashSet< cds::gc::DHP, key_val<std::hash<key_type>>, traits_FeldmanHashSet_stat >    FeldmanHashSet_dhp_stdhash_stat;
147         typedef FeldmanHashSet< rcu_gpi, key_val<std::hash<key_type>>, traits_FeldmanHashSet_stat >    FeldmanHashSet_rcu_gpi_stdhash_stat;
148         typedef FeldmanHashSet< rcu_gpb, key_val<std::hash<key_type>>, traits_FeldmanHashSet_stat >    FeldmanHashSet_rcu_gpb_stdhash_stat;
149         typedef FeldmanHashSet< rcu_gpt, key_val<std::hash<key_type>>, traits_FeldmanHashSet_stat >    FeldmanHashSet_rcu_gpt_stdhash_stat;
150 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
151         typedef FeldmanHashSet< rcu_shb, key_val<std::hash<key_type>>, traits_FeldmanHashSet_stat >    FeldmanHashSet_rcu_shb_stdhash_stat;
152         typedef FeldmanHashSet< rcu_sht, key_val<std::hash<key_type>>, traits_FeldmanHashSet_stat >    FeldmanHashSet_rcu_sht_stdhash_stat;
153 #endif
154
155         // CityHash
156 #if CDS_BUILD_BITS == 64
157         struct traits_FeldmanHashSet_city64 : public default_traits
158         {
159             typedef ::hashing::city64::less less;
160         };
161         typedef FeldmanHashSet< cds::gc::HP,  key_val<::hashing::city64>, traits_FeldmanHashSet_city64 >    FeldmanHashSet_hp_city64;
162         typedef FeldmanHashSet< cds::gc::DHP, key_val<::hashing::city64>, traits_FeldmanHashSet_city64 >    FeldmanHashSet_dhp_city64;
163         typedef FeldmanHashSet< rcu_gpi, key_val<::hashing::city64>, traits_FeldmanHashSet_city64 >    FeldmanHashSet_rcu_gpi_city64;
164         typedef FeldmanHashSet< rcu_gpb, key_val<::hashing::city64>, traits_FeldmanHashSet_city64 >    FeldmanHashSet_rcu_gpb_city64;
165         typedef FeldmanHashSet< rcu_gpt, key_val<::hashing::city64>, traits_FeldmanHashSet_city64 >    FeldmanHashSet_rcu_gpt_city64;
166 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
167         typedef FeldmanHashSet< rcu_shb, key_val<::hashing::city64>, traits_FeldmanHashSet_city64 >    FeldmanHashSet_rcu_shb_city64;
168         typedef FeldmanHashSet< rcu_sht, key_val<::hashing::city64>, traits_FeldmanHashSet_city64 >    FeldmanHashSet_rcu_sht_city64;
169 #endif
170
171         struct traits_FeldmanHashSet_city64_stat : public traits_FeldmanHashSet_city64
172         {
173             typedef cc::feldman_hashset::stat<> stat;
174         };
175         typedef FeldmanHashSet< cds::gc::HP,  key_val<::hashing::city64>, traits_FeldmanHashSet_city64_stat >    FeldmanHashSet_hp_city64_stat;
176         typedef FeldmanHashSet< cds::gc::DHP, key_val<::hashing::city64>, traits_FeldmanHashSet_city64_stat >    FeldmanHashSet_dhp_city64_stat;
177         typedef FeldmanHashSet< rcu_gpi, key_val<::hashing::city64>, traits_FeldmanHashSet_city64_stat >    FeldmanHashSet_rcu_gpi_city64_stat;
178         typedef FeldmanHashSet< rcu_gpb, key_val<::hashing::city64>, traits_FeldmanHashSet_city64_stat >    FeldmanHashSet_rcu_gpb_city64_stat;
179         typedef FeldmanHashSet< rcu_gpt, key_val<::hashing::city64>, traits_FeldmanHashSet_city64_stat >    FeldmanHashSet_rcu_gpt_city64_stat;
180 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
181         typedef FeldmanHashSet< rcu_shb, key_val<::hashing::city64>, traits_FeldmanHashSet_city64_stat >    FeldmanHashSet_rcu_shb_city64_stat;
182         typedef FeldmanHashSet< rcu_sht, key_val<::hashing::city64>, traits_FeldmanHashSet_city64_stat >    FeldmanHashSet_rcu_sht_city64_stat;
183 #endif
184
185         struct traits_FeldmanHashSet_city128 : public default_traits
186         {
187             typedef ::hashing::city128::less less;
188         };
189         typedef FeldmanHashSet< cds::gc::HP,  key_val<::hashing::city128>, traits_FeldmanHashSet_city128 >    FeldmanHashSet_hp_city128;
190         typedef FeldmanHashSet< cds::gc::DHP, key_val<::hashing::city128>, traits_FeldmanHashSet_city128 >    FeldmanHashSet_dhp_city128;
191         typedef FeldmanHashSet< rcu_gpi, key_val<::hashing::city128>, traits_FeldmanHashSet_city128 >    FeldmanHashSet_rcu_gpi_city128;
192         typedef FeldmanHashSet< rcu_gpb, key_val<::hashing::city128>, traits_FeldmanHashSet_city128 >    FeldmanHashSet_rcu_gpb_city128;
193         typedef FeldmanHashSet< rcu_gpt, key_val<::hashing::city128>, traits_FeldmanHashSet_city128 >    FeldmanHashSet_rcu_gpt_city128;
194 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
195         typedef FeldmanHashSet< rcu_shb, key_val<::hashing::city128>, traits_FeldmanHashSet_city128 >    FeldmanHashSet_rcu_shb_city128;
196         typedef FeldmanHashSet< rcu_sht, key_val<::hashing::city128>, traits_FeldmanHashSet_city128 >    FeldmanHashSet_rcu_sht_city128;
197 #endif
198
199         struct traits_FeldmanHashSet_city128_stat : public traits_FeldmanHashSet_city128
200         {
201             typedef cc::feldman_hashset::stat<> stat;
202         };
203         typedef FeldmanHashSet< cds::gc::HP,  key_val<::hashing::city128>, traits_FeldmanHashSet_city128_stat >    FeldmanHashSet_hp_city128_stat;
204         typedef FeldmanHashSet< cds::gc::DHP, key_val<::hashing::city128>, traits_FeldmanHashSet_city128_stat >    FeldmanHashSet_dhp_city128_stat;
205         typedef FeldmanHashSet< rcu_gpi, key_val<::hashing::city128>, traits_FeldmanHashSet_city128_stat >    FeldmanHashSet_rcu_gpi_city128_stat;
206         typedef FeldmanHashSet< rcu_gpb, key_val<::hashing::city128>, traits_FeldmanHashSet_city128_stat >    FeldmanHashSet_rcu_gpb_city128_stat;
207         typedef FeldmanHashSet< rcu_gpt, key_val<::hashing::city128>, traits_FeldmanHashSet_city128_stat >    FeldmanHashSet_rcu_gpt_city128_stat;
208 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
209         typedef FeldmanHashSet< rcu_shb, key_val<::hashing::city128>, traits_FeldmanHashSet_city128_stat >    FeldmanHashSet_rcu_shb_city128_stat;
210         typedef FeldmanHashSet< rcu_sht, key_val<::hashing::city128>, traits_FeldmanHashSet_city128_stat >    FeldmanHashSet_rcu_sht_city128_stat;
211 #endif
212
213 #endif // #if CDS_BUILD_BITS == 64
214
215
216         // for fixed-sized key
217         // No hash function is necessary
218
219         struct fixed_sized_key
220         {
221             typedef typename set_type_base< Key, Val >::key_type key_type;
222             struct key_val : public set_type_base< Key, Val >::key_val
223             {
224                 typedef typename set_type_base< Key, Val >::key_val base_class;
225
226                 /*explicit*/ key_val(key_type const& k) : base_class(k) {}
227                 key_val(key_type const& k, value_type const& v) : base_class(k, v) {}
228
229                 template <typename K>
230                 /*explicit*/ key_val(K const& k) : base_class(k) {}
231
232                 template <typename K, typename T>
233                 key_val(K const& k, T const& v) : base_class(k, v) {}
234
235                 // mock hasher
236                 struct hasher {
237                 template <typename Q>
238                     key_type operator()( Q const& k ) const
239                     {
240                         return key_type( k );
241                     }
242                 };
243             };
244
245             struct traits : public cc::feldman_hashset::traits
246             {
247                 struct hash_accessor {
248                     key_type operator()(key_val const& kv)
249                     {
250                         return kv.key;
251                     }
252                 };
253             };
254
255             struct traits_stat : public traits
256             {
257                 typedef cc::feldman_hashset::stat<> stat;
258             };
259         };
260
261         typedef FeldmanHashSet< cds::gc::HP, typename fixed_sized_key::key_val, typename fixed_sized_key::traits >    FeldmanHashSet_hp_fixed;
262         typedef FeldmanHashSet< cds::gc::DHP, typename fixed_sized_key::key_val, typename fixed_sized_key::traits >    FeldmanHashSet_dhp_fixed;
263         typedef FeldmanHashSet< rcu_gpi, typename fixed_sized_key::key_val, typename fixed_sized_key::traits >    FeldmanHashSet_rcu_gpi_fixed;
264         typedef FeldmanHashSet< rcu_gpb, typename fixed_sized_key::key_val, typename fixed_sized_key::traits >    FeldmanHashSet_rcu_gpb_fixed;
265         typedef FeldmanHashSet< rcu_gpt, typename fixed_sized_key::key_val, typename fixed_sized_key::traits >    FeldmanHashSet_rcu_gpt_fixed;
266 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
267         typedef FeldmanHashSet< rcu_shb, typename fixed_sized_key::key_val, typename fixed_sized_key::traits >    FeldmanHashSet_rcu_shb_fixed;
268         typedef FeldmanHashSet< rcu_sht, typename fixed_sized_key::key_val, typename fixed_sized_key::traits >    FeldmanHashSet_rcu_sht_fixed;
269 #endif
270
271         typedef FeldmanHashSet< cds::gc::HP, typename fixed_sized_key::key_val, typename fixed_sized_key::traits_stat >    FeldmanHashSet_hp_fixed_stat;
272         typedef FeldmanHashSet< cds::gc::DHP, typename fixed_sized_key::key_val, typename fixed_sized_key::traits_stat >    FeldmanHashSet_dhp_fixed_stat;
273         typedef FeldmanHashSet< rcu_gpi, typename fixed_sized_key::key_val, typename fixed_sized_key::traits_stat >    FeldmanHashSet_rcu_gpi_fixed_stat;
274         typedef FeldmanHashSet< rcu_gpb, typename fixed_sized_key::key_val, typename fixed_sized_key::traits_stat >    FeldmanHashSet_rcu_gpb_fixed_stat;
275         typedef FeldmanHashSet< rcu_gpt, typename fixed_sized_key::key_val, typename fixed_sized_key::traits_stat >    FeldmanHashSet_rcu_gpt_fixed_stat;
276 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
277         typedef FeldmanHashSet< rcu_shb, typename fixed_sized_key::key_val, typename fixed_sized_key::traits_stat >    FeldmanHashSet_rcu_shb_fixed_stat;
278         typedef FeldmanHashSet< rcu_sht, typename fixed_sized_key::key_val, typename fixed_sized_key::traits_stat >    FeldmanHashSet_rcu_sht_fixed_stat;
279 #endif
280
281     };
282
283     template <typename GC, typename T, typename Traits >
284     static inline void print_stat( FeldmanHashSet< GC, T, Traits > const& s )
285     {
286         CPPUNIT_MSG( s.statistics() );
287
288         std::vector< cds::intrusive::feldman_hashset::level_statistics > level_stat;
289         s.get_level_statistics( level_stat );
290         CPPUNIT_MSG( level_stat );
291     }
292
293 } // namespace set2
294
295 #endif // #ifndef CDSUNIT_SET_TYPE_MICHAEL_H