2c524ed500734cceb029828f744e9d107cc5376c
[libcds.git] / test / stress / set / set_type.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_SET_TYPE_H
32 #define CDSUNIT_SET_TYPE_H
33
34 #include <cds/urcu/general_instant.h>
35 #include <cds/urcu/general_buffered.h>
36 #include <cds/urcu/general_threaded.h>
37 #include <cds/urcu/signal_buffered.h>
38 #include <cds/urcu/signal_threaded.h>
39
40 #include <cds/opt/hash.h>
41 #include <cds/sync/spinlock.h>
42
43 #include <cds_test/stress_test.h>
44 #include "framework/michael_alloc.h"
45
46 namespace set {
47     namespace cc = cds::container;
48     namespace co = cds::opt;
49
50     typedef cds::urcu::gc< cds::urcu::general_instant<> >   rcu_gpi;
51     typedef cds::urcu::gc< cds::urcu::general_buffered<> >  rcu_gpb;
52     typedef cds::urcu::gc< cds::urcu::general_threaded<> >  rcu_gpt;
53 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
54     typedef cds::urcu::gc< cds::urcu::signal_buffered<> >  rcu_shb;
55     typedef cds::urcu::gc< cds::urcu::signal_threaded<> >  rcu_sht;
56 #endif
57
58     template <typename Key>
59     struct less;
60
61     template <typename Key>
62     struct cmp 
63     {
64         int operator ()(Key const& k1, Key const& k2) const
65         {
66             if ( less<Key>( k1, k2 ) )
67                 return -1;
68             return less<Key>( k2, k1 ) ? 1 : 0;
69         }
70     };
71
72     template <typename Key>
73     struct hash;
74
75 #define CDSUNIT_INT_COMPARE(t)  template <> struct cmp<t> { int operator()( t k1, t k2 ){ return (int)(k1 - k2); } }
76     CDSUNIT_INT_COMPARE(char);
77     CDSUNIT_INT_COMPARE(unsigned char);
78     CDSUNIT_INT_COMPARE(int);
79     CDSUNIT_INT_COMPARE(unsigned int);
80     CDSUNIT_INT_COMPARE(long);
81     CDSUNIT_INT_COMPARE(unsigned long);
82     CDSUNIT_INT_COMPARE(long long);
83     CDSUNIT_INT_COMPARE(unsigned long long);
84 #undef CDSUNIT_INT_COMPARE
85
86 #define CDSUNIT_INT_LESS(t)  template <> struct less<t> { bool operator()( t k1, t k2 ){ return k1 < k2; } }
87     CDSUNIT_INT_LESS( char );
88     CDSUNIT_INT_LESS( unsigned char );
89     CDSUNIT_INT_LESS( int );
90     CDSUNIT_INT_LESS( unsigned int );
91     CDSUNIT_INT_LESS( long );
92     CDSUNIT_INT_LESS( unsigned long );
93     CDSUNIT_INT_LESS( long long );
94     CDSUNIT_INT_LESS( unsigned long long );
95 #undef CDSUNIT_INT_LESS
96
97     template <>
98     struct cmp<std::string>
99     {
100         int operator()(std::string const& s1, std::string const& s2)
101         {
102             return s1.compare( s2 );
103         }
104         int operator()(std::string const& s1, char const * s2)
105         {
106             return s1.compare( s2 );
107         }
108         int operator()(char const * s1, std::string const& s2)
109         {
110             return -s2.compare( s1 );
111         }
112     };
113
114     template <typename T>
115     struct hash
116     {
117         typedef size_t result_type;
118         typedef T      argument_type;
119
120         size_t operator()( T const& k ) const
121         {
122             return std::hash<size_t>()(k.nKey);
123         }
124
125         size_t operator()( size_t k ) const
126         {
127             return std::hash<size_t>()(k);
128         }
129     };
130
131     template <>
132     struct hash<size_t>
133     {
134         typedef size_t result_type;
135         typedef size_t argument_type;
136
137         size_t operator()( size_t k ) const
138         {
139             return std::hash<size_t>()(k);
140         }
141     };
142
143
144     // forward
145     template <typename ImplSelector, typename Key, typename Value>
146     struct set_type;
147
148     template <typename Key, typename Value>
149     struct set_type_base
150     {
151         typedef Key     key_type;
152         typedef Value   value_type;
153
154         struct key_val {
155             key_type    key;
156             value_type  val;
157
158             /*explicit*/ key_val( key_type const& k ): key(k), val() {}
159             key_val( key_type const& k, value_type const& v ): key(k), val(v) {}
160
161             template <typename K>
162             explicit key_val( K const& k ): key(k) {}
163
164             template <typename K, typename T>
165             key_val( K const& k, T const& v ): key(k), val(v) {}
166         };
167
168         typedef set::hash<key_type>   key_hash;
169         typedef set::less<key_type>   key_less;
170         typedef set::cmp<key_type>    key_compare;
171
172         struct less {
173             bool operator()( key_val const& k1, key_val const& k2 ) const
174             {
175                 return key_less()( k1.key, k2.key );
176             }
177             bool operator()( key_type const& k1, key_val const& k2 ) const
178             {
179                 return key_less()( k1, k2.key );
180             }
181             bool operator()( key_val const& k1, key_type const& k2 ) const
182             {
183                 return key_less()( k1.key, k2 );
184             }
185         };
186
187         struct compare {
188             int operator()( key_val const& k1, key_val const& k2 ) const
189             {
190                 return key_compare()( k1.key, k2.key );
191             }
192             int operator()( key_type const& k1, key_val const& k2 ) const
193             {
194                 return key_compare()( k1, k2.key );
195             }
196             int operator()( key_val const& k1, key_type const& k2 ) const
197             {
198                 return key_compare()( k1.key, k2 );
199             }
200         };
201
202         struct equal_to {
203             bool operator()( key_val const& k1, key_val const& k2 ) const
204             {
205                 return key_compare()( k1.key, k2.key ) == 0;
206             }
207             bool operator()( key_type const& k1, key_val const& k2 ) const
208             {
209                 return key_compare()( k1, k2.key ) == 0;
210             }
211             bool operator()( key_val const& k1, key_type const& k2 ) const
212             {
213                 return key_compare()( k1.key, k2 ) == 0;
214             }
215         };
216
217
218         struct hash: public key_hash
219         {
220             size_t operator()( key_val const& v ) const
221             {
222                 return key_hash::operator()( v.key );
223             }
224             size_t operator()( key_type const& key ) const
225             {
226                 return key_hash::operator()( key );
227             }
228             template <typename Q>
229             size_t operator()( Q const& k ) const
230             {
231                 return key_hash::operator()( k );
232             }
233         };
234
235         struct hash2: public hash
236         {
237             size_t operator()( key_val const& k ) const
238             {
239                 size_t h = hash::operator ()( k.key );
240                 size_t seed = ~h;
241                 seed ^= h + 0x9e3779b9 + (seed << 6) + (seed >> 2);
242                 return seed;
243             }
244             size_t operator()( key_type const& k ) const
245             {
246                 size_t h = hash::operator ()( k );
247                 size_t seed = ~h;
248                 seed ^= h + 0x9e3779b9 + (seed << 6) + (seed >> 2);
249                 return seed;
250             }
251             template <typename Q>
252             size_t operator()( Q const& k ) const
253             {
254                 return key_hash::operator()( k );
255             }
256         };
257     };
258
259
260     // *************************************************
261     // print_stat
262     // *************************************************
263
264     template <typename Set>
265     static inline void print_stat( cds_test::property_stream&, Set const& /*s*/ )
266     {}
267
268
269     //*******************************************************
270     // additional_check
271     //*******************************************************
272
273     template <typename Set>
274     static inline void additional_check( Set& /*set*/ )
275     {}
276
277     template <typename Set>
278     static inline void additional_cleanup( Set& /*set*/ )
279     {}
280
281     //*******************************************************
282     // check_before_clear
283     //*******************************************************
284
285     template <typename Set>
286     static inline void check_before_clear( Set& /*s*/ )
287     {}
288
289 } // namespace set
290
291
292 #endif // ifndef CDSUNIT_SET_TYPE_H