3 #ifndef CDSTEST_HDR_BRONSON_AVLTREE_MAP_H
4 #define CDSTEST_HDR_BRONSON_AVLTREE_MAP_H
6 #include "cppunit/cppunit_proxy.h"
7 #include "size_check.h"
8 #include <functional> // ref
12 using misc::check_size;
14 class BronsonAVLTreeHdrTest : public CppUnitMini::TestCase
20 size_t nInsertFuncCall;
21 size_t nEnsureExistFuncCall;
22 size_t nEnsureNewFuncCall;
23 size_t nEraseFuncCall;
27 : nInsertFuncCall( 0 )
28 , nEnsureExistFuncCall( 0 )
29 , nEnsureNewFuncCall( 0 )
49 int operator()( key_type k1, key_type k2 )
51 return k1 < k2 ? -1 : k1 > k2 ? 1 : 0;
65 bool operator()( wrapped_int const& w, int n ) const
69 bool operator()( int n, wrapped_int const& w ) const
74 bool operator()( wrapped_int const& w, T const& v ) const
76 return w.nKey < v.nKey;
79 bool operator()( T const& v, wrapped_int const& w ) const
81 return v.nKey < w.nKey;
86 static const size_t c_nItemCount = 10000;
95 : pFirst( new int[c_nItemCount] )
96 , pLast( pFirst + c_nItemCount )
99 for ( int * p = pFirst; p != pLast; ++p, ++i )
102 std::random_shuffle( pFirst, pLast );
110 int operator[]( size_t i ) const
112 assert( i < size_t( pLast - pFirst ) );
119 void operator()( key_type, value_type& v ) const
121 ++v.stat.nFindFuncCall;
125 template <typename Item>
130 void operator()( key_type const&, Item& v )
135 void operator()( Item& v )
141 struct insert_functor
143 template <typename Item>
144 void operator()( key_type key, Item& i )
147 ++i.stat.nInsertFuncCall;
151 template <typename Q>
152 static void ensure_func( bool bNew, Q key, value_type& i )
156 ++i.stat.nEnsureNewFuncCall;
158 ++i.stat.nEnsureExistFuncCall;
161 struct ensure_functor
163 template <typename Q>
164 void operator()( bool bNew, Q key, value_type& i )
166 ensure_func( bNew, key, i );
172 void test_with( Set& s )
176 typedef typename Set::exempt_ptr exempt_ptr;
179 CPPUNIT_ASSERT( !s.find( 10 ) );
180 CPPUNIT_ASSERT( s.insert( 10 ) );
181 CPPUNIT_ASSERT( !s.empty() );
182 CPPUNIT_ASSERT( check_size( s, 1 ) );
183 CPPUNIT_ASSERT( s.find( 10 ) );
185 CPPUNIT_ASSERT( !s.insert( 10 ) );
186 CPPUNIT_ASSERT( !s.empty() );
187 CPPUNIT_ASSERT( check_size( s, 1 ) );
189 CPPUNIT_ASSERT( !s.find_with( 20, std::less<key_type>() ) );
190 CPPUNIT_ASSERT( s.insert( 20, 25 ) );
191 CPPUNIT_ASSERT( !s.empty() );
192 CPPUNIT_ASSERT( check_size( s, 2 ) );
193 CPPUNIT_ASSERT( s.find_with( 10, std::less<key_type>() ) );
194 CPPUNIT_ASSERT( s.find( key = 20 ) );
195 CPPUNIT_ASSERT( s.find_with( key, std::less<key_type>(), find_functor() ) );
197 copy_found<value_type> f;
199 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
200 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
201 CPPUNIT_ASSERT( f.m_found.stat.nFindFuncCall == 1 );
203 CPPUNIT_ASSERT( s.find( key, find_functor() ) );
205 copy_found<value_type> f;
207 CPPUNIT_ASSERT( s.find_with( key, std::less<key_type>(), std::ref( f ) ) );
208 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
209 CPPUNIT_ASSERT( f.m_found.stat.nFindFuncCall == 2 );
211 CPPUNIT_ASSERT( s.find( 20, find_functor() ) );
213 copy_found<value_type> f;
214 CPPUNIT_ASSERT( s.find_with( 20, std::less<key_type>(), std::ref( f ) ) );
215 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
216 CPPUNIT_ASSERT( f.m_found.stat.nFindFuncCall == 3 );
219 CPPUNIT_ASSERT( !s.empty() );
220 CPPUNIT_ASSERT( check_size( s, 2 ) );
222 CPPUNIT_ASSERT( !s.find( 25 ) );
223 CPPUNIT_ASSERT( s.insert_with( 25, insert_functor() ) );
224 CPPUNIT_ASSERT( !s.empty() );
225 CPPUNIT_ASSERT( check_size( s, 3 ) );
227 copy_found<value_type> f;
229 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
230 CPPUNIT_ASSERT( f.m_found.nVal == 2500 );
231 CPPUNIT_ASSERT( f.m_found.stat.nInsertFuncCall == 1 );
237 copy_found<value_type> f;
238 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
239 CPPUNIT_ASSERT( f.m_found.nVal == 0 );
240 CPPUNIT_ASSERT( f.m_found.stat.nEnsureExistFuncCall == 0 );
241 CPPUNIT_ASSERT( f.m_found.stat.nEnsureNewFuncCall == 0 );
243 std::pair<bool, bool> ensureResult = s.update( key, ensure_functor() );
244 CPPUNIT_ASSERT( ensureResult.first && !ensureResult.second );
245 CPPUNIT_ASSERT( !s.empty() );
246 CPPUNIT_ASSERT( check_size( s, 3 ) );
248 copy_found<value_type> f;
249 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
250 CPPUNIT_ASSERT( f.m_found.nVal == 1000 );
251 CPPUNIT_ASSERT( f.m_found.stat.nEnsureExistFuncCall == 1 );
252 CPPUNIT_ASSERT( f.m_found.stat.nEnsureNewFuncCall == 0 );
255 ensureResult = s.update( 13, []( bool /*bNew*/, key_type key, value_type& v )
258 ++v.stat.nEnsureNewFuncCall;
260 CPPUNIT_ASSERT( ensureResult.first && ensureResult.second );
261 CPPUNIT_ASSERT( !s.empty() );
262 CPPUNIT_ASSERT( check_size( s, 4 ) );
264 copy_found<value_type> f;
266 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
267 CPPUNIT_ASSERT( f.m_found.nVal == 13000 );
268 CPPUNIT_ASSERT( f.m_found.stat.nEnsureExistFuncCall == 0 );
269 CPPUNIT_ASSERT( f.m_found.stat.nEnsureNewFuncCall == 1 );
273 CPPUNIT_ASSERT( s.erase( 13 ) );
274 CPPUNIT_ASSERT( !s.find( 13 ) );
275 CPPUNIT_ASSERT( !s.empty() );
276 CPPUNIT_ASSERT( check_size( s, 3 ) );
277 CPPUNIT_ASSERT( !s.erase( 13 ) );
278 CPPUNIT_ASSERT( !s.empty() );
279 CPPUNIT_ASSERT( check_size( s, 3 ) );
281 CPPUNIT_ASSERT( s.find( 10 ) );
282 CPPUNIT_ASSERT( s.erase_with( 10, std::less<key_type>() ) );
283 CPPUNIT_ASSERT( !s.find( 10 ) );
284 CPPUNIT_ASSERT( !s.empty() );
285 CPPUNIT_ASSERT( check_size( s, 2 ) );
286 CPPUNIT_ASSERT( !s.erase_with( 10, std::less<key_type>() ) );
287 CPPUNIT_ASSERT( !s.empty() );
288 CPPUNIT_ASSERT( check_size( s, 2 ) );
290 CPPUNIT_ASSERT( s.find( 20 ) );
292 copy_found<value_type> f;
293 CPPUNIT_ASSERT( s.erase( 20, std::ref( f ) ) );
294 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
296 CPPUNIT_ASSERT( s.insert( 235, 2350 ) );
297 CPPUNIT_ASSERT( s.erase_with( 235, std::less<key_type>(), std::ref( f ) ) );
298 CPPUNIT_ASSERT( f.m_found.nVal == 2350 );
300 CPPUNIT_ASSERT( !s.find( 20 ) );
301 CPPUNIT_ASSERT( !s.empty() );
302 CPPUNIT_ASSERT( check_size( s, 1 ) );
305 CPPUNIT_ASSERT( s.empty() );
306 CPPUNIT_ASSERT( check_size( s, 0 ) );
309 CPPUNIT_ASSERT( s.emplace( 151 ) ); // key = 151, val=0
310 CPPUNIT_ASSERT( s.emplace( 174, 471 ) ); // key = 174, val = 471
311 CPPUNIT_ASSERT( !s.empty() );
312 CPPUNIT_ASSERT( check_size( s, 2 ) );
314 CPPUNIT_ASSERT( s.find( 151 ) );
315 CPPUNIT_ASSERT( s.find_with( 174, std::less<key_type>() ) );
316 CPPUNIT_ASSERT( !s.find( 190 ) );
319 copy_found<value_type> f;
321 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
322 CPPUNIT_ASSERT( f.m_found.nVal == 0 );
325 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
326 CPPUNIT_ASSERT( f.m_found.nVal == 471 );
330 CPPUNIT_ASSERT( s.empty() );
331 CPPUNIT_ASSERT( check_size( s, 0 ) );
333 const int c_nStep = 10;
335 for ( key_type i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
337 std::random_shuffle( keys, keys + sizeof(keys) / sizeof(keys[0]));
345 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
346 CPPUNIT_ASSERT( s.emplace( keys[i], keys[i] * c_nStep ));
348 xp = s.extract_min();
349 CPPUNIT_ASSERT( xp );
351 CPPUNIT_CHECK_EX( nPrev == 0, "Expected=0 real=" << nPrev );
352 while ( !s.empty() ) {
353 xp = s.extract_min();
354 CPPUNIT_ASSERT( xp );
355 CPPUNIT_CHECK_EX( nPrev + c_nStep == xp->nVal, "Expected=" << nPrev + c_nStep << " real=" << xp->nVal );
359 CPPUNIT_CHECK( nCount == sizeof(keys) / sizeof(keys[0]));
362 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
363 CPPUNIT_ASSERT( s.insert( keys[i], keys[i] * c_nStep ));
366 xp = s.extract_min( [&keyPrev]( key_type k ){ keyPrev = k; });
367 CPPUNIT_ASSERT( xp );
369 CPPUNIT_CHECK_EX( keyPrev == 0, "Expected=0 real=" << keyPrev );
370 CPPUNIT_CHECK_EX( nPrev == 0, "Expected=0 real=" << nPrev );
371 while ( !s.empty() ) {
372 xp = s.extract_min( [&key](key_type k){ key = k; } );
373 CPPUNIT_ASSERT( xp );
374 CPPUNIT_CHECK_EX( key == keyPrev + 1, "Expected=" << keyPrev + 1 << " real=" << key );
375 CPPUNIT_CHECK_EX( nPrev + c_nStep == xp->nVal, "Expected=" << nPrev + c_nStep << " real=" << xp->nVal );
380 CPPUNIT_CHECK( nCount == sizeof(keys) / sizeof(keys[0]));
383 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
384 CPPUNIT_ASSERT( s.insert( keys[i], keys[i] * c_nStep ));
387 xp = s.extract_min_key( keyPrev );
388 CPPUNIT_ASSERT( xp );
390 CPPUNIT_CHECK_EX( keyPrev == 0, "Expected=0 real=" << keyPrev );
391 CPPUNIT_CHECK_EX( nPrev == 0, "Expected=0 real=" << nPrev );
392 while ( !s.empty() ) {
393 xp = s.extract_min_key( key );
394 CPPUNIT_ASSERT( xp );
395 CPPUNIT_CHECK_EX( key == keyPrev + 1, "Expected=" << keyPrev + 1 << " real=" << key );
396 CPPUNIT_CHECK_EX( nPrev + c_nStep == xp->nVal, "Expected=" << nPrev + c_nStep << " real=" << xp->nVal );
401 CPPUNIT_CHECK( nCount == sizeof(keys) / sizeof(keys[0]));
404 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
405 CPPUNIT_ASSERT( s.emplace( keys[i], keys[i] * c_nStep ));
408 xp = s.extract_max();
409 CPPUNIT_ASSERT( xp );
411 CPPUNIT_CHECK_EX( nPrev == c_nStep * (sizeof(keys) / sizeof(keys[0]) - 1),
412 "Expected=" << c_nStep * (sizeof(keys) / sizeof(keys[0]) - 1) << " real=" << nPrev );
413 while ( !s.empty() ) {
414 xp = s.extract_max();
415 CPPUNIT_ASSERT( xp );
416 CPPUNIT_CHECK_EX( nPrev - c_nStep == xp->nVal, "Expected=" << nPrev - c_nStep << " real=" << xp->nVal );
420 CPPUNIT_CHECK( nCount == sizeof(keys) / sizeof(keys[0]));
423 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
424 CPPUNIT_ASSERT( s.emplace( keys[i], keys[i] * c_nStep ));
427 xp = s.extract_max( [&keyPrev]( key_type k ){ keyPrev = k; });
428 CPPUNIT_ASSERT( xp );
430 CPPUNIT_CHECK_EX( keyPrev == sizeof(keys) / sizeof(keys[0]) - 1,
431 "Expected=" << sizeof(keys) / sizeof(keys[0]) - 1 << " real=" << keyPrev );
432 CPPUNIT_CHECK_EX( nPrev == c_nStep * (sizeof(keys) / sizeof(keys[0]) - 1),
433 "Expected=" << c_nStep * (sizeof(keys) / sizeof(keys[0]) - 1) << " real=" << nPrev );
434 while ( !s.empty() ) {
435 xp = s.extract_max( [&key](key_type k){ key = k; });
436 CPPUNIT_ASSERT( xp );
437 CPPUNIT_CHECK_EX( key == keyPrev - 1, "Expected=" << keyPrev - 1 << " real=" << key );
438 CPPUNIT_CHECK_EX( nPrev - c_nStep == xp->nVal, "Expected=" << nPrev - c_nStep << " real=" << xp->nVal );
443 CPPUNIT_CHECK( nCount == sizeof(keys) / sizeof(keys[0]));
446 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
447 CPPUNIT_ASSERT( s.emplace( keys[i], keys[i] * c_nStep ));
450 xp = s.extract_max_key( keyPrev );
451 CPPUNIT_ASSERT( xp );
453 CPPUNIT_CHECK_EX( keyPrev == sizeof(keys) / sizeof(keys[0]) - 1,
454 "Expected=" << sizeof(keys) / sizeof(keys[0]) - 1 << " real=" << keyPrev );
455 CPPUNIT_CHECK_EX( nPrev == c_nStep * (sizeof(keys) / sizeof(keys[0]) - 1),
456 "Expected=" << c_nStep * (sizeof(keys) / sizeof(keys[0]) - 1) << " real=" << nPrev );
457 while ( !s.empty() ) {
458 xp = s.extract_max_key( key );
459 CPPUNIT_ASSERT( xp );
460 CPPUNIT_CHECK_EX( key == keyPrev - 1, "Expected=" << keyPrev - 1 << " real=" << key );
461 CPPUNIT_CHECK_EX( nPrev - c_nStep == xp->nVal, "Expected=" << nPrev - c_nStep << " real=" << xp->nVal );
466 CPPUNIT_CHECK( nCount == sizeof(keys) / sizeof(keys[0]));
469 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
470 CPPUNIT_ASSERT( s.emplace( keys[i], keys[i] * c_nStep ));
472 for ( int i = 0; i < sizeof( keys ) / sizeof( keys[0] ); ++i ) {
473 xp = s.extract(keys[i]);
474 CPPUNIT_CHECK_EX( xp->nVal == keys[i] * c_nStep, "Expected value=" << keys[i] * c_nStep << " real=" << xp->nVal );
476 CPPUNIT_ASSERT(s.empty());
480 for ( int i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i )
481 CPPUNIT_ASSERT( s.emplace( keys[i], keys[i] * c_nStep ));
483 for ( int i = 0; i < sizeof( keys ) / sizeof( keys[0] ); ++i ) {
484 xp = s.extract_with( wrapped_int(keys[i]), wrapped_less());
485 CPPUNIT_CHECK_EX( xp->nVal == keys[i] * c_nStep, "Expected value=" << keys[i] * c_nStep << " real=" << xp->nVal );
487 CPPUNIT_ASSERT(s.empty());
490 template <class Set, class PrintStat>
493 typedef Set set_type;
500 CPPUNIT_ASSERT( s.empty() );
501 CPPUNIT_ASSERT( check_size( s, 0 ) );
509 void BronsonAVLTree_rcu_gpb_less();
510 void BronsonAVLTree_rcu_gpb_less_stat();
511 void BronsonAVLTree_rcu_gpb_cmp();
512 void BronsonAVLTree_rcu_gpb_cmp_stat();
513 void BronsonAVLTree_rcu_gpb_cmpless();
514 void BronsonAVLTree_rcu_gpb_less_ic();
515 void BronsonAVLTree_rcu_gpb_cmp_ic();
516 void BronsonAVLTree_rcu_gpb_cmp_ic_stat();
517 void BronsonAVLTree_rcu_gpb_cmp_ic_stat_yield();
518 void BronsonAVLTree_rcu_gpb_less_relaxed_insert();
519 void BronsonAVLTree_rcu_gpb_less_relaxed_insert_stat();
520 void BronsonAVLTree_rcu_gpb_pool_monitor_less();
521 void BronsonAVLTree_rcu_gpb_pool_monitor_less_stat();
522 void BronsonAVLTree_rcu_gpb_pool_monitor_cmp_ic_stat();
523 void BronsonAVLTree_rcu_gpb_pool_monitor_cmp_ic_stat_yield();
524 void BronsonAVLTree_rcu_gpb_pool_monitor_less_relaxed_insert();
525 void BronsonAVLTree_rcu_gpb_pool_monitor_less_relaxed_insert_stat();
527 CPPUNIT_TEST_SUITE( BronsonAVLTreeHdrTest )
528 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_less )
529 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_less_stat )
530 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_cmp )
531 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_cmp_stat )
532 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_cmpless )
533 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_less_ic )
534 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_cmp_ic )
535 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_cmp_ic_stat )
536 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_cmp_ic_stat_yield )
537 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_less_relaxed_insert )
538 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_less_relaxed_insert_stat )
539 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_pool_monitor_less )
540 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_pool_monitor_less_stat )
541 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_pool_monitor_cmp_ic_stat )
542 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_pool_monitor_cmp_ic_stat_yield )
543 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_pool_monitor_less_relaxed_insert )
544 CPPUNIT_TEST( BronsonAVLTree_rcu_gpb_pool_monitor_less_relaxed_insert_stat )
545 CPPUNIT_TEST_SUITE_END()
549 #endif // #ifndef CDSTEST_HDR_BRONSON_AVLTREE_MAP_H