3 #ifndef __CDSHDR_QUEUE_SEGMENTED_QUEUE_H
4 #define __CDSHDR_QUEUE_SEGMENTED_QUEUE_H
6 #include "cppunit/cppunit_proxy.h"
7 #include <cds/intrusive/details/base.h>
8 #include "size_check.h"
12 class HdrSegmentedQueue: public CppUnitMini::TestCase
18 item( size_t v ): nVal(v) {}
19 item( size_t nMajor, size_t nMinor ): nVal( nMajor * 16 + nMinor ) {}
26 template <typename Queue>
29 for ( size_t nQuasiFactor = 2; nQuasiFactor <= 256; ++nQuasiFactor ) {
30 CPPUNIT_MSG( "QuasiFactor=" << nQuasiFactor << "..." );
31 test_qf<Queue>( nQuasiFactor );
35 template <typename Queue>
36 void test_qf( size_t nQuasiFactor )
38 typedef typename Queue::value_type value_type;
40 static size_t const c_nItemCount = 1000;
43 Queue q( nQuasiFactor );
44 CPPUNIT_CHECK( q.quasi_factor() == cds::beans::ceil2(nQuasiFactor) );
45 CPPUNIT_CHECK( q.empty() );
46 CPPUNIT_CHECK( misc::check_size( q, 0 ));
49 for ( size_t i = 0; i < c_nItemCount; ++i ) {
51 CPPUNIT_ASSERT( q.push(item(i)) );
54 CPPUNIT_ASSERT( q.enqueue(item(i)) );
56 CPPUNIT_CHECK( misc::check_size( q, i + 1 ));
57 CPPUNIT_CHECK( !q.empty() );
62 while ( !q.empty() ) {
65 CPPUNIT_ASSERT( q.pop( v ) );
68 CPPUNIT_ASSERT( q.dequeue( v ));
71 int nSegment = int( nCount / q.quasi_factor() );
72 int nMin = nSegment * int(q.quasi_factor());
73 int nMax = nMin + int(q.quasi_factor()) - 1;
74 CPPUNIT_CHECK_EX( nMin <= static_cast<int>(v.nVal) && static_cast<int>( v.nVal ) <= nMax, nMin << " <= " << v.nVal << " <= " << nMax );
77 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount - nCount ));
79 CPPUNIT_CHECK( nCount == c_nItemCount );
80 CPPUNIT_CHECK( q.empty() );
81 CPPUNIT_CHECK( misc::check_size( q, 0 ));
84 // push/pop with functor
85 for ( size_t i = 0; i < c_nItemCount; ++i ) {
89 CPPUNIT_ASSERT( q.push_with( [&itm]( item& dest ) { dest.nVal = itm.nVal; } ));
92 CPPUNIT_ASSERT( q.enqueue_with( [&itm]( item& dest ) { dest.nVal = itm.nVal; } ));
94 CPPUNIT_CHECK( misc::check_size( q, i + 1 ));
95 CPPUNIT_CHECK( !q.empty() );
102 while ( !q.empty() ) {
104 CPPUNIT_ASSERT( q.pop_with( [&v, &nCount]( item& src ) {v.nVal = src.nVal; ++nCount; } ));
107 CPPUNIT_ASSERT( q.dequeue_with( [&v, &nCount]( item& src ) {v.nVal = src.nVal; ++nCount; } ));
110 // It is possible c_nItemCount % quasi_factor() != 0
111 // In this case the segment cannot be calculated here
112 size_t nMin = nCount > q.quasi_factor() ? nCount - q.quasi_factor() : 0;
113 size_t nMax = nCount + q.quasi_factor();
114 CPPUNIT_CHECK_EX( nMin <= v.nVal && v.nVal <= nMax, nMin << " <= " << v.nVal << " <= " << nMax );
117 CPPUNIT_CHECK( pf.nCount == nCount );
118 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount - nCount ));
120 CPPUNIT_CHECK( nCount == c_nItemCount );
121 CPPUNIT_CHECK( q.empty() );
122 CPPUNIT_CHECK( misc::check_size( q, 0 ));
129 for ( size_t i = 0; i < c_nItemCount; ++i ) {
130 CPPUNIT_CHECK( q.emplace( nMajor, nMinor ));
131 if ( nMinor == 15 ) {
137 CPPUNIT_CHECK( !q.empty() );
139 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount ));
142 while ( !q.empty() ) {
145 CPPUNIT_ASSERT( q.pop( v ) );
148 CPPUNIT_ASSERT( q.dequeue( v ));
151 size_t nMin = nCount > q.quasi_factor() ? nCount - q.quasi_factor() : 0;
152 size_t nMax = nCount + q.quasi_factor();
153 CPPUNIT_CHECK_EX( nMin <= v.nVal && v.nVal <= nMax, nMin << " <= " << v.nVal << " <= " << nMax );
156 CPPUNIT_CHECK( misc::check_size( q, c_nItemCount - nCount ));
158 CPPUNIT_CHECK( nCount == c_nItemCount );
159 CPPUNIT_CHECK( q.empty() );
160 CPPUNIT_CHECK( misc::check_size( q, 0 ));
163 // pop from empty queue
166 v.nVal = c_nItemCount + 1;
167 CPPUNIT_CHECK( q.empty() );
168 CPPUNIT_ASSERT( !q.pop( v ));
169 CPPUNIT_CHECK( q.empty() );
170 CPPUNIT_CHECK( misc::check_size( q, 0 ));
171 CPPUNIT_CHECK( v.nVal == c_nItemCount + 1 );
175 for ( size_t i = 0; i < c_nItemCount; ++i ) {
177 CPPUNIT_ASSERT( q.push(item(i)) );
180 CPPUNIT_ASSERT( q.enqueue(item(i)) );
182 CPPUNIT_CHECK( misc::check_size( q, i + 1 ));
183 CPPUNIT_CHECK( !q.empty() );
187 CPPUNIT_CHECK( misc::check_size( q, 0 ));
188 CPPUNIT_CHECK( q.empty() );
193 void SegmQueue_HP_mutex();
194 void SegmQueue_HP_shuffle();
195 void SegmQueue_HP_stat();
197 void SegmQueue_DHP();
198 void SegmQueue_DHP_mutex();
199 void SegmQueue_DHP_shuffle();
200 void SegmQueue_DHP_stat();
202 CPPUNIT_TEST_SUITE(HdrSegmentedQueue)
203 CPPUNIT_TEST( SegmQueue_HP )
204 CPPUNIT_TEST( SegmQueue_HP_mutex )
205 CPPUNIT_TEST( SegmQueue_HP_shuffle )
206 CPPUNIT_TEST( SegmQueue_HP_stat )
208 CPPUNIT_TEST( SegmQueue_DHP )
209 CPPUNIT_TEST( SegmQueue_DHP_mutex )
210 CPPUNIT_TEST( SegmQueue_DHP_shuffle )
211 CPPUNIT_TEST( SegmQueue_DHP_stat )
212 CPPUNIT_TEST_SUITE_END()
217 #endif //#ifndef __CDSHDR_QUEUE_SEGMENTED_QUEUE_H