2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
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.
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.
31 #ifndef CDSUNIT_PQUEUE_TYPES_H
32 #define CDSUNIT_PQUEUE_TYPES_H
34 #include <cds/container/mspriority_queue.h>
35 #include <cds/container/fcpriority_queue.h>
37 #include "pqueue/std_pqueue.h"
38 #include "pqueue/ellen_bintree_pqueue.h"
39 #include "pqueue/skiplist_pqueue.h"
43 #include <boost/container/stable_vector.hpp>
44 #include <boost/container/deque.hpp>
45 #include <cds/sync/spinlock.h>
47 #include "print_ellenbintree_stat.h"
48 #include "print_skip_list_stat.h"
49 #include "print_mspriorityqueue_stat.h"
52 namespace cc = cds::container;
53 namespace co = cds::opt;
55 template <typename Value>
58 static size_t const c_nBoundedCapacity = 1024 * 1024 * 16;
60 typedef std::less<Value> less;
63 int operator()( Value const& v1, Value const& v2 ) const
65 return less()( v1, v2 ) ? -1 : less()( v2, v1 ) ? 1 : 0;
69 typedef cds::urcu::gc< cds::urcu::general_instant<> > rcu_gpi;
70 typedef cds::urcu::gc< cds::urcu::general_buffered<> > rcu_gpb;
71 typedef cds::urcu::gc< cds::urcu::general_threaded<> > rcu_gpt;
72 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
73 typedef cds::urcu::gc< cds::urcu::signal_buffered<> > rcu_shb;
74 typedef cds::urcu::gc< cds::urcu::signal_threaded<> > rcu_sht;
79 struct traits_MSPriorityQueue_static_less : public
80 cc::mspriority_queue::make_traits <
81 co::buffer < co::v::static_buffer< char, c_nBoundedCapacity > >
84 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_less > MSPriorityQueue_static_less;
86 struct traits_MSPriorityQueue_static_less_stat : public cc::mspriority_queue::traits
88 typedef co::v::static_buffer< char, c_nBoundedCapacity > buffer;
89 typedef cc::mspriority_queue::stat<> stat;
91 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_less_stat > MSPriorityQueue_static_less_stat;
93 struct traits_MSPriorityQueue_static_cmp : public
94 cc::mspriority_queue::make_traits <
95 co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
99 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_cmp > MSPriorityQueue_static_cmp;
101 struct traits_MSPriorityQueue_static_mutex : public
102 cc::mspriority_queue::make_traits<
103 co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
104 , co::lock_type<std::mutex>
107 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_mutex > MSPriorityQueue_static_mutex;
109 struct traits_MSPriorityQueue_dyn_less : public
110 cc::mspriority_queue::make_traits<
111 co::buffer< co::v::dynamic_buffer< char > >
114 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_less > MSPriorityQueue_dyn_less;
116 struct traits_MSPriorityQueue_dyn_less_stat : public
117 cc::mspriority_queue::make_traits <
118 co::buffer< co::v::dynamic_buffer< char > >
119 , co::stat < cc::mspriority_queue::stat<> >
122 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_less_stat > MSPriorityQueue_dyn_less_stat;
124 struct traits_MSPriorityQueue_dyn_cmp : public
125 cc::mspriority_queue::make_traits <
126 co::buffer< co::v::dynamic_buffer< char > >
127 , co::compare < cmp >
130 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_cmp > MSPriorityQueue_dyn_cmp;
132 struct traits_MSPriorityQueue_dyn_mutex : public
133 cc::mspriority_queue::make_traits <
134 co::buffer< co::v::dynamic_buffer< char > >
135 , co::lock_type < std::mutex >
138 typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_mutex > MSPriorityQueue_dyn_mutex;
141 // Priority queue based on EllenBinTreeSet
142 struct traits_EllenBinTree_max :
143 public cc::ellen_bintree::make_set_traits<
144 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
145 ,cc::opt::less< std::less<Value> >
146 ,co::stat< cc::ellen_bintree::stat<> >
149 typedef EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_HP_max;
150 typedef EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_DHP_max;
151 typedef EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_gpi_max;
152 typedef EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_gpb_max;
153 typedef EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_gpt_max;
154 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
155 typedef EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_shb_max;
156 typedef EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_max > EllenBinTree_RCU_sht_max;
159 struct traits_EllenBinTree_max_stat :
160 public cc::ellen_bintree::make_set_traits<
161 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
162 ,cc::opt::less< std::less<Value> >
163 ,co::stat< cc::ellen_bintree::stat<> >
166 typedef EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_HP_max_stat;
167 typedef EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_DHP_max_stat;
168 typedef EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_gpi_max_stat;
169 typedef EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_gpb_max_stat;
170 typedef EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_gpt_max_stat;
171 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
172 typedef EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_shb_max_stat;
173 typedef EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_max_stat > EllenBinTree_RCU_sht_max_stat;
176 struct traits_EllenBinTree_min :
177 public cc::ellen_bintree::make_set_traits<
178 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
179 ,cc::opt::less< std::greater<Value> >
182 typedef EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_HP_min;
183 typedef EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_DHP_min;
184 typedef EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_gpi_min;
185 typedef EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_gpb_min;
186 typedef EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_gpt_min;
187 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
188 typedef EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_shb_min;
189 typedef EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_min, false > EllenBinTree_RCU_sht_min;
192 struct traits_EllenBinTree_min_stat :
193 public cc::ellen_bintree::make_set_traits<
194 cc::ellen_bintree::key_extractor< typename Value::key_extractor >
195 ,cc::opt::less< std::greater<Value> >
196 ,co::stat< cc::ellen_bintree::stat<> >
199 typedef EllenBinTreePQueue< cds::gc::HP, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_HP_min_stat;
200 typedef EllenBinTreePQueue< cds::gc::DHP, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_DHP_min_stat;
201 typedef EllenBinTreePQueue< rcu_gpi, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_gpi_min_stat;
202 typedef EllenBinTreePQueue< rcu_gpb, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_gpb_min_stat;
203 typedef EllenBinTreePQueue< rcu_gpt, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_gpt_min_stat;
204 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
205 typedef EllenBinTreePQueue< rcu_shb, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_shb_min_stat;
206 typedef EllenBinTreePQueue< rcu_sht, typename Value::key_type, Value, traits_EllenBinTree_min_stat, false > EllenBinTree_RCU_sht_min_stat;
209 // Priority queue based on SkipListSet
210 struct traits_SkipList_max :
211 public cc::skip_list::make_traits <
212 cc::opt::less < std::less<Value> >
215 typedef SkipListPQueue< cds::gc::HP, Value, traits_SkipList_max > SkipList_HP_max;
216 typedef SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_max > SkipList_DHP_max;
217 typedef SkipListPQueue< rcu_gpi, Value, traits_SkipList_max > SkipList_RCU_gpi_max;
218 typedef SkipListPQueue< rcu_gpb, Value, traits_SkipList_max > SkipList_RCU_gpb_max;
219 typedef SkipListPQueue< rcu_gpt, Value, traits_SkipList_max > SkipList_RCU_gpt_max;
220 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
221 typedef SkipListPQueue< rcu_shb, Value, traits_SkipList_max > SkipList_RCU_shb_max;
222 typedef SkipListPQueue< rcu_sht, Value, traits_SkipList_max > SkipList_RCU_sht_max;
225 struct traits_SkipList_max_stat :
226 public cc::skip_list::make_traits<
227 cc::opt::less< std::less<Value> >
228 ,co::stat< cc::skip_list::stat<> >
231 typedef SkipListPQueue< cds::gc::HP, Value, traits_SkipList_max_stat > SkipList_HP_max_stat;
232 typedef SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_max_stat > SkipList_DHP_max_stat;
233 typedef SkipListPQueue< rcu_gpi, Value, traits_SkipList_max_stat > SkipList_RCU_gpi_max_stat;
234 typedef SkipListPQueue< rcu_gpb, Value, traits_SkipList_max_stat > SkipList_RCU_gpb_max_stat;
235 typedef SkipListPQueue< rcu_gpt, Value, traits_SkipList_max_stat > SkipList_RCU_gpt_max_stat;
236 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
237 typedef SkipListPQueue< rcu_shb, Value, traits_SkipList_max_stat > SkipList_RCU_shb_max_stat;
238 typedef SkipListPQueue< rcu_sht, Value, traits_SkipList_max_stat > SkipList_RCU_sht_max_stat;
241 struct traits_SkipList_min :
242 public cc::skip_list::make_traits<
243 cc::opt::less< std::greater<Value> >
246 typedef SkipListPQueue< cds::gc::HP, Value, traits_SkipList_min, false > SkipList_HP_min;
247 typedef SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_min, false > SkipList_DHP_min;
248 typedef SkipListPQueue< rcu_gpi, Value, traits_SkipList_min, false > SkipList_RCU_gpi_min;
249 typedef SkipListPQueue< rcu_gpb, Value, traits_SkipList_min, false > SkipList_RCU_gpb_min;
250 typedef SkipListPQueue< rcu_gpt, Value, traits_SkipList_min, false > SkipList_RCU_gpt_min;
251 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
252 typedef SkipListPQueue< rcu_shb, Value, traits_SkipList_min, false > SkipList_RCU_shb_min;
253 typedef SkipListPQueue< rcu_sht, Value, traits_SkipList_min, false > SkipList_RCU_sht_min;
256 struct traits_SkipList_min_stat :
257 public cc::skip_list::make_traits<
258 cc::opt::less< std::greater<Value> >
259 ,co::stat< cc::skip_list::stat<> >
262 typedef SkipListPQueue< cds::gc::HP, Value, traits_SkipList_min_stat, false > SkipList_HP_min_stat;
263 typedef SkipListPQueue< cds::gc::DHP, Value, traits_SkipList_min_stat, false > SkipList_DHP_min_stat;
264 typedef SkipListPQueue< rcu_gpi, Value, traits_SkipList_min_stat, false > SkipList_RCU_gpi_min_stat;
265 typedef SkipListPQueue< rcu_gpb, Value, traits_SkipList_min_stat, false > SkipList_RCU_gpb_min_stat;
266 typedef SkipListPQueue< rcu_gpt, Value, traits_SkipList_min_stat, false > SkipList_RCU_gpt_min_stat;
267 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
268 typedef SkipListPQueue< rcu_shb, Value, traits_SkipList_min_stat, false > SkipList_RCU_shb_min_stat;
269 typedef SkipListPQueue< rcu_sht, Value, traits_SkipList_min_stat, false > SkipList_RCU_sht_min_stat;
274 struct traits_FCPQueue_stat : public
275 cds::container::fcpqueue::make_traits <
276 cds::opt::stat < cds::container::fcpqueue::stat<> >
280 typedef cds::container::FCPriorityQueue< Value > FCPQueue_vector;
281 typedef cds::container::FCPriorityQueue< Value
282 ,std::priority_queue<Value>
283 ,traits_FCPQueue_stat
284 > FCPQueue_vector_stat;
286 typedef cds::container::FCPriorityQueue< Value
287 ,std::priority_queue<Value, std::deque<Value> >
289 typedef cds::container::FCPriorityQueue< Value
290 ,std::priority_queue<Value, std::deque<Value> >
291 ,traits_FCPQueue_stat
292 > FCPQueue_deque_stat;
294 typedef cds::container::FCPriorityQueue< Value
295 ,std::priority_queue<Value, boost::container::deque<Value> >
296 > FCPQueue_boost_deque;
297 typedef cds::container::FCPriorityQueue< Value
298 ,std::priority_queue<Value, boost::container::deque<Value> >
299 ,traits_FCPQueue_stat
300 > FCPQueue_boost_deque_stat;
302 typedef cds::container::FCPriorityQueue< Value
303 ,std::priority_queue<Value, boost::container::stable_vector<Value> >
304 > FCPQueue_boost_stable_vector;
305 typedef cds::container::FCPriorityQueue< Value
306 ,std::priority_queue<Value, boost::container::stable_vector<Value> >
307 ,traits_FCPQueue_stat
308 > FCPQueue_boost_stable_vector_stat;
310 /// Standard priority_queue
311 typedef StdPQueue< Value, std::vector<Value>, cds::sync::spin> StdPQueue_vector_spin;
312 typedef StdPQueue< Value, std::vector<Value>, std::mutex > StdPQueue_vector_mutex;
313 typedef StdPQueue< Value, std::deque<Value>, cds::sync::spin> StdPQueue_deque_spin;
314 typedef StdPQueue< Value, std::deque<Value>, std::mutex > StdPQueue_deque_mutex;
318 template <typename Stat>
319 static inline void check_statistics( Stat const& /*s*/ )
322 static inline void check_statistics( cds::container::ellen_bintree::stat<> const& s )
324 CPPUNIT_CHECK_CURRENT( s.m_nInternalNodeCreated.get() == s.m_nInternalNodeDeleted.get() );
325 CPPUNIT_CHECK_CURRENT( s.m_nUpdateDescCreated.get() == s.m_nUpdateDescDeleted.get() );
327 } // namespace pqueue
331 static inline std::ostream& operator <<( std::ostream& o, cds::container::fcpqueue::empty_stat const& )
336 static inline std::ostream& operator <<( std::ostream& o, cds::container::fcpqueue::stat<> const& s )
338 return o << "\tStatistics:\n"
339 << "\t Push: " << s.m_nPush.get() << "\n"
340 << "\t Push move: " << s.m_nPushMove.get() << "\n"
341 << "\t Pop: " << s.m_nPop.get() << "\n"
342 << "\t Failed pop: " << s.m_nFailedPop.get() << "\n"
343 << "\tFlat combining statistics:\n"
344 << "\t Combining factor: " << s.combining_factor() << "\n"
345 << "\t Operation count: " << s.m_nOperationCount.get() << "\n"
346 << "\t Combine call count: " << s.m_nCombiningCount.get() << "\n"
347 << "\t Compact pub-list: " << s.m_nCompactPublicationList.get() << "\n"
348 << "\t Deactivate pub-record: " << s.m_nDeactivatePubRecord.get() << "\n"
349 << "\t Activate pub-record: " << s.m_nActivatePubRecord.get() << "\n"
350 << "\t Create pub-record: " << s.m_nPubRecordCreated.get() << "\n"
351 << "\t Delete pub-record: " << s.m_nPubRecordDeteted.get() << "\n"
352 << "\t Acquire pub-record: " << s.m_nAcquirePubRecCount.get()<< "\n"
353 << "\t Release pub-record: " << s.m_nReleasePubRecCount.get()<< "\n";
358 #endif // #ifndef CDSUNIT_PQUEUE_TYPES_H