Merge branch 'dev'
[libcds.git] / test / stress / pqueue / pqueue_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 CDSSTRESS_PQUEUE_TYPES_H
32 #define CDSSTRESS_PQUEUE_TYPES_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/container/mspriority_queue.h>
41 #include <cds/container/fcpriority_queue.h>
42
43 #include <cds/container/ellen_bintree_set_hp.h>
44 #include <cds/container/ellen_bintree_set_dhp.h>
45 #include <cds/container/ellen_bintree_set_rcu.h>
46
47 #include <cds/container/skip_list_set_hp.h>
48 #include <cds/container/skip_list_set_dhp.h>
49 #include <cds/container/skip_list_set_rcu.h>
50
51 #include <cds/sync/spinlock.h>
52
53 #include <queue>
54 #include <vector>
55 #include <deque>
56 #include <mutex> //unique_lock
57
58 #include <boost/container/stable_vector.hpp>
59 #include <boost/container/deque.hpp>
60
61 #include <cds_test/stress_test.h>
62 #include <cds_test/stat_ellenbintree_out.h>
63 #include <cds_test/stat_skiplist_out.h>
64
65 namespace pqueue {
66     namespace cc = cds::container;
67     namespace co = cds::opt;
68
69     namespace details {
70         template <typename T, typename Container, typename Lock, typename Less = std::less<typename Container::value_type> >
71         class StdPQueue
72         {
73         public:
74             typedef T value_type;
75             typedef std::priority_queue<value_type, Container, Less> pqueue_type;
76
77         private:
78             pqueue_type     m_PQueue;
79             mutable Lock    m_Lock;
80
81             typedef std::unique_lock<Lock> scoped_lock;
82
83         public:
84             bool push( value_type const& val )
85             {
86                 scoped_lock l( m_Lock );
87                 m_PQueue.push( val );
88                 return true;
89             }
90
91             bool pop( value_type& dest )
92             {
93                 scoped_lock l( m_Lock );
94                 if ( !m_PQueue.empty() ) {
95                     dest = m_PQueue.top();
96                     m_PQueue.pop();
97                     return true;
98                 }
99                 return false;
100             }
101
102             template <typename Q, typename MoveFunc>
103             bool pop_with( Q& dest, MoveFunc f )
104             {
105                 scoped_lock l( m_Lock );
106                 if ( !m_PQueue.empty() ) {
107                     f( dest, m_PQueue.top() );
108                     m_PQueue.pop();
109                     return true;
110                 }
111                 return false;
112             }
113
114             void clear()
115             {
116                 scoped_lock l( m_Lock );
117                 while ( !m_PQueue.empty() )
118                     m_PQueue.pop();
119             }
120
121             template <typename Func>
122             void clear_with( Func f )
123             {
124                 scoped_lock l( m_Lock );
125                 while ( !m_PQueue.empty() ) {
126                     f( m_PQueue.top() );
127                     m_PQueue.pop();
128                 }
129             }
130
131             bool empty() const
132             {
133                 return m_PQueue.empty();
134             }
135
136             size_t size() const
137             {
138                 return m_PQueue.size();
139             }
140
141             cds::opt::none statistics() const
142             {
143                 return cds::opt::none();
144             }
145         };
146
147         // EllenBinTree priority queue
148         template <typename GC>
149         struct EllenBinTreePQueue_pop_max
150         {
151             template <typename T, typename Tree>
152             bool operator()( T& dest, Tree& container ) const
153             {
154                 typename Tree::guarded_ptr gp( container.extract_max() );
155                 if ( gp )
156                     dest = *gp;
157                 return !gp.empty();
158             }
159         };
160
161         template <typename RCU>
162         struct EllenBinTreePQueue_pop_max< cds::urcu::gc<RCU> >
163         {
164             template <typename T, typename Tree>
165             bool operator()( T& dest, Tree& container ) const
166             {
167                 typename Tree::exempt_ptr ep( container.extract_max() );
168                 if ( ep )
169                     dest = *ep;
170                 return !ep.empty();
171             }
172         };
173
174         template <typename GC>
175         struct EllenBinTreePQueue_pop_min
176         {
177             template <typename T, typename Tree>
178             bool operator()( T& dest, Tree& container ) const
179             {
180                 typename Tree::guarded_ptr gp( container.extract_min() );
181                 if ( gp )
182                     dest = *gp;
183                 return !gp.empty();
184             }
185         };
186
187         template <typename RCU>
188         struct EllenBinTreePQueue_pop_min< cds::urcu::gc<RCU> >
189         {
190             template <typename T, typename Tree>
191             bool operator()( T& dest, Tree& container ) const
192             {
193                 typename Tree::exempt_ptr ep( container.extract_min() );
194                 if ( ep )
195                     dest = *ep;
196                 return !ep.empty();
197             }
198         };
199
200         template <typename GC, typename Key, typename T, typename Traits, bool Max = true>
201         class EllenBinTreePQueue : protected cds::container::EllenBinTreeSet< GC, Key, T, Traits >
202         {
203             typedef cds::container::EllenBinTreeSet< GC, Key, T, Traits > base_class;
204             template <typename GC2> friend struct EllenBinTreePQueue_pop_max;
205             template <typename GC2> friend struct EllenBinTreePQueue_pop_min;
206
207         public:
208             typedef T value_type;
209
210             bool push( value_type const& val )
211             {
212                 return base_class::insert( val );
213             }
214
215             bool pop( value_type& dest )
216             {
217                 return Max ? EllenBinTreePQueue_pop_max< typename base_class::gc >()(dest, *this)
218                     : EllenBinTreePQueue_pop_min< typename base_class::gc >()(dest, *this);
219             }
220
221             void clear()
222             {
223                 base_class::clear();
224             }
225
226             bool empty() const
227             {
228                 return base_class::empty();
229             }
230
231             size_t size() const
232             {
233                 return base_class::size();
234             }
235
236             typename base_class::stat const& statistics() const
237             {
238                 return base_class::statistics();
239             }
240         };
241
242
243         // SkipList property queue
244         template <typename GC>
245         struct SkipListPQueue_pop_max
246         {
247             template <typename T, typename Set>
248             bool operator()( T& dest, Set& container ) const
249             {
250                 typename Set::guarded_ptr gp( container.extract_max() );
251                 if ( gp )
252                     dest = *gp;
253                 return !gp.empty();
254             }
255         };
256
257         template <typename RCU>
258         struct SkipListPQueue_pop_max< cds::urcu::gc<RCU> >
259         {
260             template <typename T, typename Set>
261             bool operator()( T& dest, Set& container ) const
262             {
263                 typename Set::exempt_ptr ep( container.extract_max() );
264                 if ( ep )
265                     dest = *ep;
266                 return !ep.empty();
267             }
268         };
269
270         template <typename GC>
271         struct SkipListPQueue_pop_min
272         {
273             template <typename T, typename Set>
274             bool operator()( T& dest, Set& container ) const
275             {
276                 typename Set::guarded_ptr gp( container.extract_min() );
277                 if ( gp )
278                     dest = *gp;
279                 return !gp.empty();
280             }
281         };
282
283         template <typename RCU>
284         struct SkipListPQueue_pop_min< cds::urcu::gc<RCU> >
285         {
286             template <typename T, typename Set>
287             bool operator()( T& dest, Set& container ) const
288             {
289                 typename Set::exempt_ptr ep( container.extract_min() );
290                 if ( ep )
291                     dest = *ep;
292                 return !ep.empty();
293             }
294         };
295
296         template <typename GC, typename T, typename Traits, bool Max = true>
297         class SkipListPQueue : protected cds::container::SkipListSet< GC, T, Traits >
298         {
299             typedef cds::container::SkipListSet< GC, T, Traits > base_class;
300             template <typename GC2> friend struct SkipListPQueue_pop_max;
301             template <typename GC2> friend struct SkipListPQueue_pop_min;
302
303         public:
304             typedef T value_type;
305
306             bool push( value_type const& val )
307             {
308                 return base_class::insert( val );
309             }
310
311             bool pop( value_type& dest )
312             {
313                 return Max ? SkipListPQueue_pop_max< typename base_class::gc >()(dest, *this)
314                     : SkipListPQueue_pop_min< typename base_class::gc >()(dest, *this);
315             }
316
317             void clear()
318             {
319                 base_class::clear();
320             }
321
322             bool empty() const
323             {
324                 return base_class::empty();
325             }
326
327             size_t size() const
328             {
329                 return base_class::size();
330             }
331
332             typename base_class::stat const& statistics() const
333             {
334                 return base_class::statistics();
335             }
336         };
337
338     } // namespace details
339
340     template <typename Value>
341     struct Types
342     {
343         static size_t const c_nBoundedCapacity = 1024 * 1024 * 16;
344
345         typedef std::less<Value>    less;
346
347         struct cmp {
348             int operator()( Value const& v1, Value const& v2 ) const
349             {
350                 return less()( v1, v2 ) ? -1 : less()( v2, v1 ) ? 1 : 0;
351             }
352         };
353
354         typedef cds::urcu::gc< cds::urcu::general_instant<> >   rcu_gpi;
355         typedef cds::urcu::gc< cds::urcu::general_buffered<> >  rcu_gpb;
356         typedef cds::urcu::gc< cds::urcu::general_threaded<> >  rcu_gpt;
357 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
358         typedef cds::urcu::gc< cds::urcu::signal_buffered<> >  rcu_shb;
359         typedef cds::urcu::gc< cds::urcu::signal_threaded<> >  rcu_sht;
360 #endif
361
362
363         // MSPriorityQueue
364         struct traits_MSPriorityQueue_static_less : public
365             cc::mspriority_queue::make_traits <
366                 co::buffer < co::v::static_buffer< char, c_nBoundedCapacity > >
367             > ::type
368         {};
369         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_less > MSPriorityQueue_static_less;
370
371         struct traits_MSPriorityQueue_static_less_stat : public cc::mspriority_queue::traits
372         {
373             typedef co::v::static_buffer< char, c_nBoundedCapacity > buffer;
374             typedef cc::mspriority_queue::stat<> stat;
375         };
376         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_less_stat > MSPriorityQueue_static_less_stat;
377
378         struct traits_MSPriorityQueue_static_cmp : public
379             cc::mspriority_queue::make_traits <
380                 co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
381                 , co::compare < cmp >
382             > ::type
383         {};
384         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_cmp > MSPriorityQueue_static_cmp;
385
386         struct traits_MSPriorityQueue_static_mutex : public
387             cc::mspriority_queue::make_traits<
388                 co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
389                 , co::lock_type<std::mutex>
390             >::type
391         {};
392         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_mutex > MSPriorityQueue_static_mutex;
393
394         struct traits_MSPriorityQueue_dyn_less : public
395             cc::mspriority_queue::make_traits<
396                 co::buffer< co::v::dynamic_buffer< char > >
397             >::type
398         {};
399         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_less > MSPriorityQueue_dyn_less;
400
401         struct traits_MSPriorityQueue_dyn_less_stat : public
402             cc::mspriority_queue::make_traits <
403                 co::buffer< co::v::dynamic_buffer< char > >
404                 , co::stat < cc::mspriority_queue::stat<> >
405             > ::type
406         {};
407         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_less_stat > MSPriorityQueue_dyn_less_stat;
408
409         struct traits_MSPriorityQueue_dyn_cmp : public
410             cc::mspriority_queue::make_traits <
411                 co::buffer< co::v::dynamic_buffer< char > >
412                 , co::compare < cmp >
413             > ::type
414         {};
415         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_cmp > MSPriorityQueue_dyn_cmp;
416
417         struct traits_MSPriorityQueue_dyn_mutex : public
418             cc::mspriority_queue::make_traits <
419                 co::buffer< co::v::dynamic_buffer< char > >
420                 , co::lock_type < std::mutex >
421             > ::type
422         {};
423         typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_mutex > MSPriorityQueue_dyn_mutex;
424
425
426         // Priority queue based on EllenBinTreeSet
427         struct traits_EllenBinTree_max :
428             public cc::ellen_bintree::make_set_traits<
429                 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
430                 ,cc::opt::less< std::less<Value> >
431                 ,co::stat< cc::ellen_bintree::stat<> >
432             >::type
433         {};
434         typedef details::EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_HP_max;
435         typedef details::EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_DHP_max;
436         typedef details::EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_gpi_max;
437         typedef details::EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_gpb_max;
438         typedef details::EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_gpt_max;
439 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
440         typedef details::EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_shb_max;
441         typedef details::EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_sht_max;
442 #endif
443
444         struct traits_EllenBinTree_max_stat :
445             public cc::ellen_bintree::make_set_traits<
446                 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
447                 ,cc::opt::less< std::less<Value> >
448                 ,co::stat< cc::ellen_bintree::stat<> >
449             >::type
450         {};
451         typedef details::EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_HP_max_stat;
452         typedef details::EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_DHP_max_stat;
453         typedef details::EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_gpi_max_stat;
454         typedef details::EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_gpb_max_stat;
455         typedef details::EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_gpt_max_stat;
456 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
457         typedef details::EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_shb_max_stat;
458         typedef details::EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_sht_max_stat;
459 #endif
460
461         struct traits_EllenBinTree_min :
462             public cc::ellen_bintree::make_set_traits<
463                 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
464                 ,cc::opt::less< std::greater<Value> >
465             >::type
466         {};
467         typedef details::EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_HP_min;
468         typedef details::EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_DHP_min;
469         typedef details::EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_gpi_min;
470         typedef details::EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_gpb_min;
471         typedef details::EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_gpt_min;
472 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
473         typedef details::EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_shb_min;
474         typedef details::EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_sht_min;
475 #endif
476
477         struct traits_EllenBinTree_min_stat :
478             public cc::ellen_bintree::make_set_traits<
479                 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
480                 ,cc::opt::less< std::greater<Value> >
481                 ,co::stat< cc::ellen_bintree::stat<> >
482             >::type
483         {};
484         typedef details::EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_HP_min_stat;
485         typedef details::EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_DHP_min_stat;
486         typedef details::EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_gpi_min_stat;
487         typedef details::EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_gpb_min_stat;
488         typedef details::EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_gpt_min_stat;
489 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
490         typedef details::EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_shb_min_stat;
491         typedef details::EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_sht_min_stat;
492 #endif
493
494         // Priority queue based on SkipListSet
495         struct traits_SkipList_max :
496             public cc::skip_list::make_traits <
497             cc::opt::less < std::less<Value> >
498             > ::type
499         {};
500         typedef details::SkipListPQueue< cds::gc::HP, Value, traits_SkipList_max > SkipList_HP_max;
501         typedef details::SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_max > SkipList_DHP_max;
502         typedef details::SkipListPQueue< rcu_gpi, Value, traits_SkipList_max > SkipList_RCU_gpi_max;
503         typedef details::SkipListPQueue< rcu_gpb, Value, traits_SkipList_max > SkipList_RCU_gpb_max;
504         typedef details::SkipListPQueue< rcu_gpt, Value, traits_SkipList_max > SkipList_RCU_gpt_max;
505 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
506         typedef details::SkipListPQueue< rcu_shb, Value, traits_SkipList_max > SkipList_RCU_shb_max;
507         typedef details::SkipListPQueue< rcu_sht, Value, traits_SkipList_max > SkipList_RCU_sht_max;
508 #endif
509
510         struct traits_SkipList_max_stat :
511             public cc::skip_list::make_traits<
512                 cc::opt::less< std::less<Value> >
513                 ,co::stat< cc::skip_list::stat<> >
514             >::type
515         {};
516         typedef details::SkipListPQueue< cds::gc::HP, Value, traits_SkipList_max_stat > SkipList_HP_max_stat;
517         typedef details::SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_max_stat > SkipList_DHP_max_stat;
518         typedef details::SkipListPQueue< rcu_gpi, Value, traits_SkipList_max_stat > SkipList_RCU_gpi_max_stat;
519         typedef details::SkipListPQueue< rcu_gpb, Value, traits_SkipList_max_stat > SkipList_RCU_gpb_max_stat;
520         typedef details::SkipListPQueue< rcu_gpt, Value, traits_SkipList_max_stat > SkipList_RCU_gpt_max_stat;
521 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
522         typedef details::SkipListPQueue< rcu_shb, Value, traits_SkipList_max_stat > SkipList_RCU_shb_max_stat;
523         typedef details::SkipListPQueue< rcu_sht, Value, traits_SkipList_max_stat > SkipList_RCU_sht_max_stat;
524 #endif
525
526         struct traits_SkipList_min :
527             public cc::skip_list::make_traits<
528                 cc::opt::less< std::greater<Value> >
529             >::type
530         {};
531         typedef details::SkipListPQueue< cds::gc::HP, Value, traits_SkipList_min, false > SkipList_HP_min;
532         typedef details::SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_min, false > SkipList_DHP_min;
533         typedef details::SkipListPQueue< rcu_gpi, Value, traits_SkipList_min, false > SkipList_RCU_gpi_min;
534         typedef details::SkipListPQueue< rcu_gpb, Value, traits_SkipList_min, false > SkipList_RCU_gpb_min;
535         typedef details::SkipListPQueue< rcu_gpt, Value, traits_SkipList_min, false > SkipList_RCU_gpt_min;
536 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
537         typedef details::SkipListPQueue< rcu_shb, Value, traits_SkipList_min, false > SkipList_RCU_shb_min;
538         typedef details::SkipListPQueue< rcu_sht, Value, traits_SkipList_min, false > SkipList_RCU_sht_min;
539 #endif
540
541         struct traits_SkipList_min_stat :
542             public cc::skip_list::make_traits<
543                 cc::opt::less< std::greater<Value> >
544                 ,co::stat< cc::skip_list::stat<> >
545             >::type
546         {};
547         typedef details::SkipListPQueue< cds::gc::HP, Value, traits_SkipList_min_stat, false > SkipList_HP_min_stat;
548         typedef details::SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_min_stat, false > SkipList_DHP_min_stat;
549         typedef details::SkipListPQueue< rcu_gpi, Value, traits_SkipList_min_stat, false > SkipList_RCU_gpi_min_stat;
550         typedef details::SkipListPQueue< rcu_gpb, Value, traits_SkipList_min_stat, false > SkipList_RCU_gpb_min_stat;
551         typedef details::SkipListPQueue< rcu_gpt, Value, traits_SkipList_min_stat, false > SkipList_RCU_gpt_min_stat;
552 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
553         typedef details::SkipListPQueue< rcu_shb, Value, traits_SkipList_min_stat, false > SkipList_RCU_shb_min_stat;
554         typedef details::SkipListPQueue< rcu_sht, Value, traits_SkipList_min_stat, false > SkipList_RCU_sht_min_stat;
555 #endif
556
557
558         // FCPriorityQueue
559         struct traits_FCPQueue_stat : public
560             cds::container::fcpqueue::make_traits <
561             cds::opt::stat < cds::container::fcpqueue::stat<> >
562             > ::type
563         {};
564
565         typedef cds::container::FCPriorityQueue< Value >    FCPQueue_vector;
566         typedef cds::container::FCPriorityQueue< Value
567             ,std::priority_queue<Value>
568             ,traits_FCPQueue_stat
569         >    FCPQueue_vector_stat;
570
571         typedef cds::container::FCPriorityQueue< Value
572             ,std::priority_queue<Value, std::deque<Value> >
573         > FCPQueue_deque;
574         typedef cds::container::FCPriorityQueue< Value
575             ,std::priority_queue<Value, std::deque<Value> >
576             ,traits_FCPQueue_stat
577         > FCPQueue_deque_stat;
578
579         typedef cds::container::FCPriorityQueue< Value
580             ,std::priority_queue<Value, boost::container::deque<Value> >
581         > FCPQueue_boost_deque;
582         typedef cds::container::FCPriorityQueue< Value
583             ,std::priority_queue<Value, boost::container::deque<Value> >
584             ,traits_FCPQueue_stat
585         > FCPQueue_boost_deque_stat;
586
587         typedef cds::container::FCPriorityQueue< Value
588             ,std::priority_queue<Value, boost::container::stable_vector<Value> >
589         > FCPQueue_boost_stable_vector;
590         typedef cds::container::FCPriorityQueue< Value
591             ,std::priority_queue<Value, boost::container::stable_vector<Value> >
592             ,traits_FCPQueue_stat
593         > FCPQueue_boost_stable_vector_stat;
594
595         /// Standard priority_queue
596         typedef details::StdPQueue< Value, std::vector<Value>, cds::sync::spin> StdPQueue_vector_spin;
597         typedef details::StdPQueue< Value, std::vector<Value>, std::mutex >  StdPQueue_vector_mutex;
598         typedef details::StdPQueue< Value, std::deque<Value>, cds::sync::spin> StdPQueue_deque_spin;
599         typedef details::StdPQueue< Value, std::deque<Value>,  std::mutex >  StdPQueue_deque_mutex;
600     };
601
602
603     //template <typename Stat>
604     //static inline void check_statistics( Stat const& /*s*/ )
605     //{}
606
607     //static inline void check_statistics( cds::container::ellen_bintree::stat<> const& s )
608     //{
609     //    CPPUNIT_CHECK_CURRENT( s.m_nInternalNodeCreated.get() == s.m_nInternalNodeDeleted.get() );
610     //    CPPUNIT_CHECK_CURRENT( s.m_nUpdateDescCreated.get() == s.m_nUpdateDescDeleted.get() );
611     //}
612 }   // namespace pqueue
613
614
615 // *********************************************
616 // Priority queue statistics
617 namespace cds_test {
618
619     static inline property_stream& operator <<( property_stream& o, cds::opt::none )
620     {
621         return o;
622     }
623
624     static inline property_stream& operator <<( property_stream& o, cds::container::fcpqueue::empty_stat const& )
625     {
626         return o;
627     }
628
629     static inline property_stream& operator <<( property_stream& o, cds::container::fcpqueue::stat<> const& s )
630     {
631         return o 
632             << CDSSTRESS_STAT_OUT( s, m_nPush )
633             << CDSSTRESS_STAT_OUT( s, m_nPushMove )
634             << CDSSTRESS_STAT_OUT( s, m_nPop )
635             << CDSSTRESS_STAT_OUT( s, m_nFailedPop )
636             << CDSSTRESS_STAT_OUT_( "combining_factor", s.combining_factor() )
637             << CDSSTRESS_STAT_OUT( s, m_nOperationCount )
638             << CDSSTRESS_STAT_OUT( s, m_nCombiningCount )
639             << CDSSTRESS_STAT_OUT( s, m_nCompactPublicationList )
640             << CDSSTRESS_STAT_OUT( s, m_nDeactivatePubRecord )
641             << CDSSTRESS_STAT_OUT( s, m_nActivatePubRecord )
642             << CDSSTRESS_STAT_OUT( s, m_nPubRecordCreated )
643             << CDSSTRESS_STAT_OUT( s, m_nPubRecordDeteted )
644             << CDSSTRESS_STAT_OUT( s, m_nAcquirePubRecCount )
645             << CDSSTRESS_STAT_OUT( s, m_nReleasePubRecCount );
646     }
647
648     static inline property_stream& operator <<( property_stream& o, cds::container::mspriority_queue::empty_stat const& /*s*/ )
649     {
650         return o;
651     }
652
653     static inline property_stream& operator <<( property_stream& o, cds::container::mspriority_queue::stat<> const& s )
654     {
655         return o
656             << CDSSTRESS_STAT_OUT( s, m_nPushCount )
657             << CDSSTRESS_STAT_OUT( s, m_nPopCount )
658             << CDSSTRESS_STAT_OUT( s, m_nPushFailCount )
659             << CDSSTRESS_STAT_OUT( s, m_nPopFailCount )
660             << CDSSTRESS_STAT_OUT( s, m_nPushHeapifySwapCount )
661             << CDSSTRESS_STAT_OUT( s, m_nPopHeapifySwapCount );
662     }
663
664 } // namespace cds_test
665
666 #endif // #ifndef CDSSTRESS_PQUEUE_TYPES_H