3 #ifndef CDSTEST_HDR_STRIPED_SET_H
4 #define CDSTEST_HDR_STRIPED_SET_H
6 #include "cppunit/cppunit_proxy.h"
7 #include "size_check.h"
9 #include <cds/opt/hash.h>
10 #include <cds/os/timer.h>
11 #include <functional> // ref
12 #include <algorithm> // random_shuffle
14 // forward namespace declaration
16 namespace container {}
21 using misc::check_size;
23 namespace cc = cds::container;
24 namespace co = cds::opt;
27 class StripedSetHdrTest: public CppUnitMini::TestCase
32 unsigned int nFindCount ; // count of find-functor calling
33 unsigned int nEnsureNewCount;
34 unsigned int nEnsureCount;
38 memset( this, 0, sizeof(*this));
41 void copy( stat const& s )
43 nFindCount = s.nFindCount;
44 nEnsureCount = s.nEnsureCount;
45 nEnsureNewCount = s.nEnsureNewCount;
49 struct item: public stat
62 item (int key, int val )
67 item( std::pair<int,int> const& p )
77 item& operator=(item const& i)
91 //item& operator=(item&& i)
110 size_t operator()( int i ) const
112 return co::v::hash<int>()( i );
115 size_t operator()( std::pair<int,int> const& i ) const
117 return co::v::hash<int>()( i.first );
120 template <typename Item>
121 size_t operator()( Item const& i ) const
123 return (*this)( i.key() );
127 struct simple_item_counter {
130 simple_item_counter()
149 operator size_t() const
155 template <typename T>
158 bool operator ()(const T& v1, const T& v2 ) const
160 return v1.key() < v2.key();
163 template <typename Q>
164 bool operator ()(const T& v1, const Q& v2 ) const
166 return v1.key() < v2;
169 template <typename Q>
170 bool operator ()(const Q& v1, const T& v2 ) const
172 return v1 < v2.key();
175 bool operator ()( std::pair<int, int> const& v1, const T& v2 ) const
177 return v1.first < v2.key();
180 bool operator ()(const T& v1, std::pair<int, int> const& v2 ) const
182 return v1.key() < v2.first;
186 template <typename T>
188 int operator ()(const T& v1, const T& v2 ) const
190 if ( v1.key() < v2.key() )
192 return v1.key() > v2.key() ? 1 : 0;
195 template <typename Q>
196 int operator ()(const T& v1, const Q& v2 ) const
200 return v1.key() > v2 ? 1 : 0;
203 template <typename Q>
204 int operator ()(const Q& v1, const T& v2 ) const
208 return v1 > v2.key() ? 1 : 0;
211 int operator()( std::pair<int,int> const& v1, T const& v2 ) const
213 if ( v1.first < v2.key() )
215 return v1.first > v2.key() ? 1 : 0;
218 int operator()( T const& v1, std::pair<int,int> const& v2 ) const
220 if ( v1.key() < v2.first )
222 return v1.key() > v2.first ? 1 : 0;
226 template <typename T>
229 bool operator ()(const T& v1, const T& v2 ) const
231 return v1.key() == v2.key();
234 template <typename Q>
235 bool operator ()(const T& v1, const Q& v2 ) const
237 return v1.key() == v2;
240 template <typename Q>
241 bool operator ()(const Q& v1, const T& v2 ) const
243 return v1 == v2.key();
246 bool operator ()( std::pair<int, int> const& v1, const T& v2 ) const
248 return v1.first == v2.key();
251 bool operator ()(const T& v1, std::pair<int, int> const& v2 ) const
253 return v1.key() == v2.first;
259 template <typename Item, typename T>
260 void operator()( Item& i, T& /*val*/ ) const
264 template <typename Item, typename T>
265 void operator()( Item& i, T const& /*val*/ ) const
271 template <typename Item>
276 template <typename T>
277 void operator()( Item& i, T& /*val*/ )
282 void operator()( Item const& i )
288 struct insert_functor
290 template <typename Item>
291 void operator()(Item& i )
293 i.nVal = i.nKey * 100;
297 template <typename Item, typename Q>
298 static void ensure_func( bool bNew, Item& i, Q& /*val*/ )
306 struct ensure_functor
308 template <typename Item, typename Q>
309 void operator()( bool bNew, Item& i, Q& val )
311 ensure_func( bNew, i, val );
320 CPPUNIT_ASSERT( s.bucket_count() == 32 );
321 CPPUNIT_ASSERT( s.lock_count() == 32 );
323 test_striped_with( s );
327 void test_striped_with( Set& s )
329 cds::OS::Timer timer;
334 for ( int i = 0; i < 10000; i++ ) {
338 CPPUNIT_MSG( " Duration=" << timer.duration() );
342 void test_int_with( Set& s)
344 typedef typename Set::value_type value_type;
350 CPPUNIT_ASSERT( !s.find( 10 ) );
351 CPPUNIT_ASSERT( s.insert( 10 ));
352 CPPUNIT_ASSERT( !s.empty() );
353 CPPUNIT_ASSERT( check_size( s, 1 ));
354 CPPUNIT_ASSERT( s.find( 10 ) );
356 CPPUNIT_ASSERT( !s.insert( 10 ));
357 CPPUNIT_ASSERT( !s.empty() );
358 CPPUNIT_ASSERT( check_size( s, 1 ));
360 CPPUNIT_ASSERT( !s.find( 20 ) );
361 CPPUNIT_ASSERT( s.insert( std::make_pair(20, 25) ));
362 CPPUNIT_ASSERT( !s.empty() );
363 CPPUNIT_ASSERT( check_size( s, 2 ));
364 CPPUNIT_ASSERT( s.find( 10 ) );
365 CPPUNIT_ASSERT( s.find( key = 20 ) );
366 CPPUNIT_ASSERT( s.find( key, find_functor() ) );
370 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
371 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
372 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
373 CPPUNIT_ASSERT( f.m_found.nFindCount == 1 );
378 CPPUNIT_ASSERT( s.find( key, find_functor() ) );
379 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
380 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
381 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
382 CPPUNIT_ASSERT( f.m_found.nFindCount == 2 );
384 CPPUNIT_ASSERT( !s.empty() );
385 CPPUNIT_ASSERT( check_size( s, 2 ));
387 CPPUNIT_ASSERT( !s.find( 25 ) );
388 CPPUNIT_ASSERT( s.insert( std::make_pair(25, -1), insert_functor() ));
389 CPPUNIT_ASSERT( !s.empty() );
390 CPPUNIT_ASSERT( check_size( s, 3 ));
394 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
395 CPPUNIT_ASSERT( f.m_found.nKey == 25 );
396 CPPUNIT_ASSERT( f.m_found.nVal == 2500 );
403 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
404 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
405 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
406 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
407 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
409 std::pair<bool, bool> ensureResult = s.ensure( key, ensure_functor() );
410 CPPUNIT_ASSERT( ensureResult.first && !ensureResult.second );
411 CPPUNIT_ASSERT( !s.empty() );
412 CPPUNIT_ASSERT( check_size( s, 3 ));
415 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
416 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
417 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
418 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 1 );
419 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
422 ensureResult = s.ensure( std::make_pair(13, 1300), ensure_functor() );
423 CPPUNIT_ASSERT( ensureResult.first && ensureResult.second );
424 CPPUNIT_ASSERT( !s.empty() );
425 CPPUNIT_ASSERT( check_size( s, 4 ));
429 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
430 CPPUNIT_ASSERT( f.m_found.nKey == 13 );
431 CPPUNIT_ASSERT( f.m_found.nVal == 1300 );
432 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
433 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 1 );
437 CPPUNIT_ASSERT( s.erase(13) );
438 CPPUNIT_ASSERT( !s.find( 13 ));
439 CPPUNIT_ASSERT( !s.empty() );
440 CPPUNIT_ASSERT( check_size( s, 3 ));
441 CPPUNIT_ASSERT( !s.erase(13) );
442 CPPUNIT_ASSERT( !s.empty() );
443 CPPUNIT_ASSERT( check_size( s, 3 ));
445 CPPUNIT_ASSERT( s.find( 10 ));
446 CPPUNIT_ASSERT( s.erase( 10 ));
447 CPPUNIT_ASSERT( !s.find( 10 ));
448 CPPUNIT_ASSERT( !s.empty() );
449 CPPUNIT_ASSERT( check_size( s, 2 ));
450 CPPUNIT_ASSERT( !s.erase(10) );
451 CPPUNIT_ASSERT( !s.empty() );
452 CPPUNIT_ASSERT( check_size( s, 2 ));
454 CPPUNIT_ASSERT( s.find(20) );
457 CPPUNIT_ASSERT( s.erase( 20, std::ref( f ) ) );
458 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
459 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
461 CPPUNIT_ASSERT( s.insert(235))
462 CPPUNIT_ASSERT( s.erase( 235, std::ref( f ) ) );
463 CPPUNIT_ASSERT( f.m_found.nKey == 235 );
464 CPPUNIT_ASSERT( f.m_found.nVal == 235 );
466 CPPUNIT_ASSERT( !s.find( 20 ));
467 CPPUNIT_ASSERT( !s.empty() );
468 CPPUNIT_ASSERT( check_size( s, 1 ));
471 CPPUNIT_ASSERT( s.empty() );
472 CPPUNIT_ASSERT( check_size( s, 0 ));
475 CPPUNIT_ASSERT( s.emplace( 151 )) ; // key = 151, val = 151
476 CPPUNIT_ASSERT( s.emplace( 174, 471 )) ; // key = 174, val = 471
477 CPPUNIT_ASSERT( s.emplace( std::make_pair( 190, 91 ) )) ; // key == 190, val = 91
478 CPPUNIT_ASSERT( !s.empty() );
479 CPPUNIT_ASSERT( check_size( s, 3 ));
481 CPPUNIT_ASSERT( s.find(151));
482 CPPUNIT_ASSERT( s.find(174));
483 CPPUNIT_ASSERT( s.find(190));
488 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
489 CPPUNIT_ASSERT( f.m_found.nKey == 151 );
490 CPPUNIT_ASSERT( f.m_found.nVal == 151 );
493 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
494 CPPUNIT_ASSERT( f.m_found.nKey == 174 );
495 CPPUNIT_ASSERT( f.m_found.nVal == 471 );
498 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
499 CPPUNIT_ASSERT( f.m_found.nKey == 190 );
500 CPPUNIT_ASSERT( f.m_found.nVal == 91 );
504 CPPUNIT_ASSERT( s.empty() );
505 CPPUNIT_ASSERT( check_size( s, 0 ));
512 CPPUNIT_ASSERT( s.bucket_count() == 32 );
513 CPPUNIT_ASSERT( s.lock_count() == 32 );
515 test_striped_with2( s );
519 void test_striped_with2( Set& s )
521 cds::OS::Timer timer;
526 for ( int i = 0; i < 10000; i++ ) {
530 CPPUNIT_MSG( " Duration=" << timer.duration() );
534 void test_int_with2( Set& s)
536 typedef typename Set::value_type value_type;
542 CPPUNIT_ASSERT( !s.find( 10 ) );
543 CPPUNIT_ASSERT( s.insert( 10 ));
544 CPPUNIT_ASSERT( !s.empty() );
545 CPPUNIT_ASSERT( check_size( s, 1 ));
546 CPPUNIT_ASSERT( s.find( 10 ) );
548 CPPUNIT_ASSERT( !s.insert( 10 ));
549 CPPUNIT_ASSERT( !s.empty() );
550 CPPUNIT_ASSERT( check_size( s, 1 ));
552 CPPUNIT_ASSERT( !s.find_with( 20, less<value_type>() ) );
553 CPPUNIT_ASSERT( s.insert( std::make_pair(20, 25) ));
554 CPPUNIT_ASSERT( !s.empty() );
555 CPPUNIT_ASSERT( check_size( s, 2 ));
556 CPPUNIT_ASSERT( s.find( 10 ) );
557 CPPUNIT_ASSERT( s.find_with( key = 20, less<value_type>() ) );
558 CPPUNIT_ASSERT( s.find_with( key, less<value_type>(), find_functor() ) );
562 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
563 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
564 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
565 CPPUNIT_ASSERT( f.m_found.nFindCount == 1 );
570 CPPUNIT_ASSERT( s.find_with( 20, less<value_type>(), find_functor() ) );
571 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
572 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
573 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
574 CPPUNIT_ASSERT( f.m_found.nFindCount == 2 );
576 CPPUNIT_ASSERT( !s.empty() );
577 CPPUNIT_ASSERT( check_size( s, 2 ));
579 CPPUNIT_ASSERT( !s.find( 25 ) );
580 CPPUNIT_ASSERT( s.insert( std::make_pair(25, -1), insert_functor() ));
581 CPPUNIT_ASSERT( !s.empty() );
582 CPPUNIT_ASSERT( check_size( s, 3 ));
586 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
587 CPPUNIT_ASSERT( f.m_found.nKey == 25 );
588 CPPUNIT_ASSERT( f.m_found.nVal == 2500 );
595 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
596 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
597 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
598 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
599 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
601 std::pair<bool, bool> ensureResult = s.ensure( key, ensure_functor() );
602 CPPUNIT_ASSERT( ensureResult.first && !ensureResult.second );
603 CPPUNIT_ASSERT( !s.empty() );
604 CPPUNIT_ASSERT( check_size( s, 3 ));
607 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
608 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
609 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
610 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 1 );
611 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
614 ensureResult = s.ensure( std::make_pair(13, 1300), ensure_functor() );
615 CPPUNIT_ASSERT( ensureResult.first && ensureResult.second );
616 CPPUNIT_ASSERT( !s.empty() );
617 CPPUNIT_ASSERT( check_size( s, 4 ));
621 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
622 CPPUNIT_ASSERT( f.m_found.nKey == 13 );
623 CPPUNIT_ASSERT( f.m_found.nVal == 1300 );
624 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
625 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 1 );
629 CPPUNIT_ASSERT( s.erase(13) );
630 CPPUNIT_ASSERT( !s.find( 13 ));
631 CPPUNIT_ASSERT( !s.empty() );
632 CPPUNIT_ASSERT( check_size( s, 3 ));
633 CPPUNIT_ASSERT( !s.erase(13) );
634 CPPUNIT_ASSERT( !s.empty() );
635 CPPUNIT_ASSERT( check_size( s, 3 ));
637 CPPUNIT_ASSERT( s.find( 10 ));
638 CPPUNIT_ASSERT( s.erase_with( 10, less<value_type>() ));
639 CPPUNIT_ASSERT( !s.find( 10 ));
640 CPPUNIT_ASSERT( !s.empty() );
641 CPPUNIT_ASSERT( check_size( s, 2 ));
642 CPPUNIT_ASSERT( !s.erase_with( 10, less<value_type>() ) );
643 CPPUNIT_ASSERT( !s.empty() );
644 CPPUNIT_ASSERT( check_size( s, 2 ));
646 CPPUNIT_ASSERT( s.find(20) );
649 CPPUNIT_ASSERT( s.erase( 20, std::ref( f ) ) );
650 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
651 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
653 CPPUNIT_ASSERT( s.insert(235))
654 CPPUNIT_ASSERT( s.erase_with( 235, less<value_type>(), std::ref( f ) ) );
655 CPPUNIT_ASSERT( f.m_found.nKey == 235 );
656 CPPUNIT_ASSERT( f.m_found.nVal == 235 );
658 CPPUNIT_ASSERT( !s.find( 20 ));
659 CPPUNIT_ASSERT( !s.empty() );
660 CPPUNIT_ASSERT( check_size( s, 1 ));
663 CPPUNIT_ASSERT( s.empty() );
664 CPPUNIT_ASSERT( check_size( s, 0 ));
667 CPPUNIT_ASSERT( s.emplace( 151 )) ; // key = 151, val = 151
668 CPPUNIT_ASSERT( s.emplace( 174, 471 )) ; // key = 174, val = 471
669 CPPUNIT_ASSERT( s.emplace( std::make_pair( 190, 91 ) )) ; // key == 190, val = 91
670 CPPUNIT_ASSERT( !s.empty() );
671 CPPUNIT_ASSERT( check_size( s, 3 ));
673 CPPUNIT_ASSERT( s.find(151));
674 CPPUNIT_ASSERT( s.find(174));
675 CPPUNIT_ASSERT( s.find(190));
680 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
681 CPPUNIT_ASSERT( f.m_found.nKey == 151 );
682 CPPUNIT_ASSERT( f.m_found.nVal == 151 );
685 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
686 CPPUNIT_ASSERT( f.m_found.nKey == 174 );
687 CPPUNIT_ASSERT( f.m_found.nVal == 471 );
690 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
691 CPPUNIT_ASSERT( f.m_found.nKey == 190 );
692 CPPUNIT_ASSERT( f.m_found.nVal == 91 );
696 CPPUNIT_ASSERT( s.empty() );
697 CPPUNIT_ASSERT( check_size( s, 0 ));
701 void Striped_vector();
703 void Striped_hashset();
704 void Striped_slist();
705 void Striped_boost_list();
706 void Striped_boost_vector();
707 void Striped_boost_stable_vector();
708 void Striped_boost_flat_set();
709 void Striped_boost_set();
710 void Striped_boost_unordered_set();
712 void Refinable_list();
713 void Refinable_vector();
714 void Refinable_set();
715 void Refinable_hashset();
716 void Refinable_slist();
717 void Refinable_boost_list();
718 void Refinable_boost_vector();
719 void Refinable_boost_stable_vector();
720 void Refinable_boost_flat_set();
721 void Refinable_boost_set();
722 void Refinable_boost_unordered_set();
724 CPPUNIT_TEST_SUITE(StripedSetHdrTest)
725 CPPUNIT_TEST(Striped_list)
726 CPPUNIT_TEST(Striped_vector)
727 CPPUNIT_TEST(Striped_set)
728 CPPUNIT_TEST(Striped_hashset)
729 CPPUNIT_TEST(Striped_slist)
730 CPPUNIT_TEST(Striped_boost_list)
731 CPPUNIT_TEST(Striped_boost_vector)
732 CPPUNIT_TEST(Striped_boost_stable_vector)
733 CPPUNIT_TEST(Striped_boost_flat_set)
734 CPPUNIT_TEST(Striped_boost_set)
735 CPPUNIT_TEST(Striped_boost_unordered_set)
737 CPPUNIT_TEST(Refinable_list)
738 CPPUNIT_TEST(Refinable_vector)
739 CPPUNIT_TEST(Refinable_set)
740 CPPUNIT_TEST(Refinable_hashset)
741 CPPUNIT_TEST(Refinable_slist)
742 CPPUNIT_TEST(Refinable_boost_list)
743 CPPUNIT_TEST(Refinable_boost_vector)
744 CPPUNIT_TEST(Refinable_boost_stable_vector)
745 CPPUNIT_TEST(Refinable_boost_flat_set)
746 CPPUNIT_TEST(Refinable_boost_set)
747 CPPUNIT_TEST(Refinable_boost_unordered_set)
749 CPPUNIT_TEST_SUITE_END()
753 #endif // #ifndef CDSTEST_HDR_STRIPED_SET_H