mspqueue.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Copyright (c) 2006-2018 Maxim Khizhinsky
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include "test_data.h"
  6. #include <cds/container/mspriority_queue.h>
  7. namespace {
  8. struct disposer {
  9. size_t m_nCallCount;
  10. disposer()
  11. : m_nCallCount( 0 )
  12. {}
  13. template <typename T>
  14. void operator()( T& )
  15. {
  16. ++m_nCallCount;
  17. }
  18. };
  19. class MSPQueue : public cds_test::PQueueTest
  20. {
  21. typedef cds_test::PQueueTest base_class;
  22. protected:
  23. template <class PQueue>
  24. void test( PQueue& pq )
  25. {
  26. data_array<value_type> arr( pq.capacity());
  27. value_type * pFirst = arr.begin();
  28. value_type * pLast = pFirst + pq.capacity();
  29. ASSERT_TRUE( pq.empty());
  30. ASSERT_EQ( pq.size(), 0u );
  31. ASSERT_EQ( pq.capacity(), size_t( base_class::c_nCapacity - 1 ));
  32. size_t nSize = 0;
  33. // Push test
  34. for ( value_type * p = pFirst; p < pLast; ++p ) {
  35. switch ( pq.size() & 3 ) {
  36. case 0:
  37. ASSERT_TRUE( pq.push_with( [p]( value_type& dest ) { dest = *p; } ));
  38. break;
  39. case 1:
  40. ASSERT_TRUE( pq.emplace( p->k, p->v ));
  41. break;
  42. case 2:
  43. ASSERT_TRUE( pq.emplace( std::make_pair( p->k, p->v )));
  44. break;
  45. default:
  46. ASSERT_TRUE( pq.push( *p ));
  47. }
  48. ASSERT_TRUE( !pq.empty());
  49. ASSERT_TRUE( pq.size() == ++nSize );
  50. }
  51. ASSERT_TRUE( pq.full());
  52. ASSERT_EQ( pq.size(), pq.capacity());
  53. // The queue is full
  54. key_type k = base_class::c_nMinValue + key_type( base_class::c_nCapacity );
  55. ASSERT_TRUE( !pq.push( k ));
  56. ASSERT_TRUE( pq.full());
  57. ASSERT_EQ( pq.size(), pq.capacity());
  58. // Pop test
  59. key_type nPrev = base_class::c_nMinValue + key_type( pq.capacity()) - 1;
  60. value_type kv( 0 );
  61. key_type key;
  62. ASSERT_TRUE( pq.pop( kv ));
  63. EXPECT_EQ( kv.k, nPrev );
  64. ASSERT_EQ( pq.size(), pq.capacity() - 1 );
  65. ASSERT_TRUE( !pq.full());
  66. ASSERT_TRUE( !pq.empty());
  67. nSize = pq.size();
  68. while ( pq.size() > 1 ) {
  69. if ( pq.size() & 1 ) {
  70. ASSERT_TRUE( pq.pop( kv ));
  71. EXPECT_EQ( kv.k, nPrev - 1 );
  72. nPrev = kv.k;
  73. }
  74. else {
  75. ASSERT_TRUE( pq.pop_with( [&key]( value_type& src ) { key = src.k; } ));
  76. EXPECT_EQ( key, nPrev - 1 );
  77. nPrev = key;
  78. }
  79. --nSize;
  80. ASSERT_EQ( pq.size(), nSize );
  81. }
  82. ASSERT_TRUE( !pq.full());
  83. ASSERT_TRUE( !pq.empty());
  84. ASSERT_EQ( pq.size(), 1u );
  85. ASSERT_TRUE( pq.pop( kv ));
  86. EXPECT_EQ( kv.k, base_class::c_nMinValue );
  87. ASSERT_TRUE( !pq.full());
  88. ASSERT_TRUE( pq.empty());
  89. ASSERT_EQ( pq.size(), 0u );
  90. // Clear test
  91. for ( value_type * p = pFirst; p < pLast; ++p ) {
  92. ASSERT_TRUE( pq.push( *p ));
  93. }
  94. ASSERT_TRUE( !pq.empty());
  95. ASSERT_TRUE( pq.full());
  96. ASSERT_EQ( pq.size(), pq.capacity());
  97. pq.clear();
  98. ASSERT_TRUE( pq.empty());
  99. ASSERT_TRUE( !pq.full());
  100. ASSERT_EQ( pq.size(), 0u );
  101. // clear_with test
  102. for ( value_type * p = pFirst; p < pLast; ++p ) {
  103. ASSERT_TRUE( pq.push( *p ));
  104. }
  105. ASSERT_TRUE( !pq.empty());
  106. ASSERT_TRUE( pq.full());
  107. ASSERT_EQ( pq.size(), pq.capacity());
  108. {
  109. disposer disp;
  110. pq.clear_with( std::ref( disp ));
  111. ASSERT_TRUE( pq.empty());
  112. ASSERT_TRUE( !pq.full());
  113. ASSERT_EQ( pq.size(), 0u );
  114. ASSERT_EQ( disp.m_nCallCount, pq.capacity());
  115. }
  116. }
  117. };
  118. typedef cds::opt::v::initialized_dynamic_buffer< char > dyn_buffer_type;
  119. typedef cds::opt::v::initialized_static_buffer< char, MSPQueue::c_nCapacity > static_buffer_type;
  120. TEST_F( MSPQueue, dynamic )
  121. {
  122. typedef cds::container::MSPriorityQueue< MSPQueue::value_type,
  123. cds::container::mspriority_queue::make_traits<
  124. cds::opt::buffer< dyn_buffer_type >
  125. >::type
  126. > pqueue;
  127. pqueue pq( c_nCapacity );
  128. test( pq );
  129. }
  130. TEST_F( MSPQueue, dynamic_cmp )
  131. {
  132. typedef cds::container::MSPriorityQueue< value_type,
  133. cds::container::mspriority_queue::make_traits<
  134. cds::opt::buffer< dyn_buffer_type >
  135. , cds::opt::compare< compare >
  136. >::type
  137. > pqueue;
  138. pqueue pq( c_nCapacity );
  139. test( pq );
  140. }
  141. TEST_F( MSPQueue, dynamic_less )
  142. {
  143. typedef cds::container::MSPriorityQueue< value_type,
  144. cds::container::mspriority_queue::make_traits<
  145. cds::opt::buffer< dyn_buffer_type >
  146. ,cds::opt::less< less >
  147. >::type
  148. > pqueue;
  149. pqueue pq( c_nCapacity );
  150. test( pq );
  151. }
  152. TEST_F( MSPQueue, dynamic_cmp_less )
  153. {
  154. struct pqueue_traits : public cds::container::mspriority_queue::traits
  155. {
  156. typedef dyn_buffer_type buffer;
  157. typedef MSPQueue::less less;
  158. typedef MSPQueue::compare compare;
  159. };
  160. typedef cds::container::MSPriorityQueue< value_type, pqueue_traits > pqueue;
  161. pqueue pq( c_nCapacity );
  162. test( pq );
  163. }
  164. TEST_F( MSPQueue, dynamic_mutex )
  165. {
  166. typedef cds::container::MSPriorityQueue< value_type,
  167. cds::container::mspriority_queue::make_traits<
  168. cds::opt::buffer< dyn_buffer_type >
  169. ,cds::opt::compare< compare >
  170. ,cds::opt::lock_type<std::mutex>
  171. >::type
  172. > pqueue;
  173. pqueue pq( c_nCapacity );
  174. test( pq );
  175. }
  176. TEST_F( MSPQueue, stat )
  177. {
  178. typedef cds::container::MSPriorityQueue< MSPQueue::value_type,
  179. cds::container::mspriority_queue::make_traits<
  180. cds::opt::buffer< static_buffer_type >
  181. >::type
  182. > pqueue;
  183. std::unique_ptr< pqueue > pq( new pqueue(0));
  184. test( *pq );
  185. }
  186. TEST_F( MSPQueue, stat_cmp )
  187. {
  188. typedef cds::container::MSPriorityQueue< value_type,
  189. cds::container::mspriority_queue::make_traits<
  190. cds::opt::buffer< static_buffer_type >
  191. ,cds::opt::compare< compare >
  192. >::type
  193. > pqueue;
  194. std::unique_ptr< pqueue > pq( new pqueue(0));
  195. test( *pq );
  196. }
  197. TEST_F( MSPQueue, stat_less )
  198. {
  199. typedef cds::container::MSPriorityQueue< value_type,
  200. cds::container::mspriority_queue::make_traits<
  201. cds::opt::buffer< static_buffer_type >
  202. ,cds::opt::less< less >
  203. >::type
  204. > pqueue;
  205. std::unique_ptr< pqueue > pq( new pqueue(0));
  206. test( *pq );
  207. }
  208. TEST_F( MSPQueue, stat_mutex )
  209. {
  210. typedef cds::container::MSPriorityQueue< value_type,
  211. cds::container::mspriority_queue::make_traits<
  212. cds::opt::buffer< static_buffer_type >
  213. ,cds::opt::less< less >
  214. ,cds::opt::lock_type<std::mutex>
  215. >::type
  216. > pqueue;
  217. std::unique_ptr< pqueue > pq( new pqueue(0));
  218. test( *pq );
  219. }
  220. } // namespace