3 #ifndef __CDSHDR_QUEUE_SEGMENTED_QUEUE_H
4 #define __CDSHDR_QUEUE_SEGMENTED_QUEUE_H
6 #include "cppunit/cppunit_proxy.h"
7 #include <cds/intrusive/base.h>
9 #include "size_check.h"
13 class HdrSegmentedQueue: public CppUnitMini::TestCase
19 item( size_t v ): nVal(v) {}
20 item( size_t nMajor, size_t nMinor ): nVal( nMajor * 16 + nMinor ) {}
28 void operator()( item& dest, other_item const& src ) const
37 void operator()( other_item& dest, item const& src )
48 template <typename Queue>
51 for ( size_t nQuasiFactor = 2; nQuasiFactor <= 256; ++nQuasiFactor ) {
52 CPPUNIT_MSG( "QuasiFactor=" << nQuasiFactor << "..." );
53 test_qf<Queue>( nQuasiFactor );
57 template <typename Queue>
58 void test_qf( size_t nQuasiFactor )
60 typedef typename Queue::value_type value_type;
62 static size_t const c_nItemCount = 1000;
65 Queue q( nQuasiFactor );
66 CPPUNIT_CHECK( q.quasi_factor() == cds::beans::ceil2(nQuasiFactor) );
67 CPPUNIT_CHECK( q.empty() );
68 CPPUNIT_CHECK( misc::check_size( q, 0 ));
71 for ( size_t i = 0; i < c_nItemCount; ++i ) {
73 CPPUNIT_ASSERT( q.push(item(i)) );
76 CPPUNIT_ASSERT( q.enqueue(item(i)) );
78 CPPUNIT_CHECK( misc::check_size( q, i + 1 ));
79 CPPUNIT_CHECK( !q.empty() );
84 while ( !q.empty() ) {
87 CPPUNIT_ASSERT( q.pop( v ) );
90 CPPUNIT_ASSERT( q.dequeue( v ));
93 int nSegment = int( nCount / q.quasi_factor() );
94 int nMin = nSegment * int(q.quasi_factor());
95 int nMax = nMin + int(q.quasi_factor()) - 1;
96 CPPUNIT_CHECK_EX( nMin <= static_cast<int>(v.nVal) && static_cast<int>( v.nVal ) <= nMax, nMin << " <= " << v.nVal << " <= " << nMax );
99 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount - nCount ));
101 CPPUNIT_CHECK( nCount == c_nItemCount );
102 CPPUNIT_CHECK( q.empty() );
103 CPPUNIT_CHECK( misc::check_size( q, 0 ));
106 // push/pop with functor
107 for ( size_t i = 0; i < c_nItemCount; ++i ) {
111 CPPUNIT_ASSERT( q.push( itm, push_functor() ));
114 CPPUNIT_ASSERT( q.enqueue( itm, push_functor() ));
116 CPPUNIT_CHECK( misc::check_size( q, i + 1 ));
117 CPPUNIT_CHECK( !q.empty() );
125 while ( !q.empty() ) {
127 CPPUNIT_ASSERT( q.pop( v, cds::ref(pf) ));
130 CPPUNIT_ASSERT( q.dequeue( v, cds::ref(pf) ));
133 // It is possible c_nItemCount % quasi_factor() != 0
134 // In this case the segment cannot be calculated here
135 size_t nMin = nCount > q.quasi_factor() ? nCount - q.quasi_factor() : 0;
136 size_t nMax = nCount + q.quasi_factor();
137 CPPUNIT_CHECK_EX( nMin <= v.nVal && v.nVal <= nMax, nMin << " <= " << v.nVal << " <= " << nMax );
140 CPPUNIT_CHECK( pf.nCount == nCount );
141 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount - nCount ));
143 CPPUNIT_CHECK( nCount == c_nItemCount );
144 CPPUNIT_CHECK( q.empty() );
145 CPPUNIT_CHECK( misc::check_size( q, 0 ));
149 # ifdef CDS_EMPLACE_SUPPORT
153 for ( size_t i = 0; i < c_nItemCount; ++i ) {
154 CPPUNIT_CHECK( q.emplace( nMajor, nMinor ));
155 if ( nMinor == 15 ) {
161 CPPUNIT_CHECK( !q.empty() );
163 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount ));
166 while ( !q.empty() ) {
169 CPPUNIT_ASSERT( q.pop( v ) );
172 CPPUNIT_ASSERT( q.dequeue( v ));
175 size_t nMin = nCount > q.quasi_factor() ? nCount - q.quasi_factor() : 0;
176 size_t nMax = nCount + q.quasi_factor();
177 CPPUNIT_CHECK_EX( nMin <= v.nVal && v.nVal <= nMax, nMin << " <= " << v.nVal << " <= " << nMax );
180 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount - nCount ));
182 CPPUNIT_CHECK( nCount == c_nItemCount );
183 CPPUNIT_CHECK( q.empty() );
184 CPPUNIT_CHECK( misc::check_size( q, 0 ));
188 // pop from empty queue
191 v.nVal = c_nItemCount + 1;
192 CPPUNIT_CHECK( q.empty() );
193 CPPUNIT_ASSERT( !q.pop( v ));
194 CPPUNIT_CHECK( q.empty() );
195 CPPUNIT_CHECK( misc::check_size( q, 0 ));
196 CPPUNIT_CHECK( v.nVal == c_nItemCount + 1 );
200 for ( size_t i = 0; i < c_nItemCount; ++i ) {
202 CPPUNIT_ASSERT( q.push(item(i)) );
205 CPPUNIT_ASSERT( q.enqueue(item(i)) );
207 CPPUNIT_CHECK( misc::check_size( q, i + 1 ));
208 CPPUNIT_CHECK( !q.empty() );
212 CPPUNIT_CHECK( misc::check_size( q, 0 ));
213 CPPUNIT_CHECK( q.empty() );
218 void SegmQueue_HP_mutex();
219 void SegmQueue_HP_shuffle();
220 void SegmQueue_HP_stat();
222 void SegmQueue_PTB();
223 void SegmQueue_PTB_mutex();
224 void SegmQueue_PTB_shuffle();
225 void SegmQueue_PTB_stat();
227 CPPUNIT_TEST_SUITE(HdrSegmentedQueue)
228 CPPUNIT_TEST( SegmQueue_HP )
229 CPPUNIT_TEST( SegmQueue_HP_mutex )
230 CPPUNIT_TEST( SegmQueue_HP_shuffle )
231 CPPUNIT_TEST( SegmQueue_HP_stat )
233 CPPUNIT_TEST( SegmQueue_PTB )
234 CPPUNIT_TEST( SegmQueue_PTB_mutex )
235 CPPUNIT_TEST( SegmQueue_PTB_shuffle )
236 CPPUNIT_TEST( SegmQueue_PTB_stat )
237 CPPUNIT_TEST_SUITE_END()
242 #endif //#ifndef __CDSHDR_QUEUE_SEGMENTED_QUEUE_H