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>
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 )
264 template <typename Item, typename T>
265 void operator()( Item& i, T const& val )
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, boost::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, boost::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, boost::ref(f) ) );
395 CPPUNIT_ASSERT( f.m_found.nKey == 25 );
396 CPPUNIT_ASSERT( f.m_found.nVal == 2500 );
403 CPPUNIT_ASSERT( s.find( key, boost::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, boost::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, boost::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, boost::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, boost::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 ));
474 # ifdef CDS_EMPLACE_SUPPORT
476 CPPUNIT_ASSERT( s.emplace( 151 )) ; // key = 151, val = 151
477 CPPUNIT_ASSERT( s.emplace( 174, 471 )) ; // key = 174, val = 471
478 CPPUNIT_ASSERT( s.emplace( std::make_pair( 190, 91 ) )) ; // key == 190, val = 91
479 CPPUNIT_ASSERT( !s.empty() );
480 CPPUNIT_ASSERT( check_size( s, 3 ));
482 CPPUNIT_ASSERT( s.find(151));
483 CPPUNIT_ASSERT( s.find(174));
484 CPPUNIT_ASSERT( s.find(190));
489 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
490 CPPUNIT_ASSERT( f.m_found.nKey == 151 );
491 CPPUNIT_ASSERT( f.m_found.nVal == 151 );
494 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
495 CPPUNIT_ASSERT( f.m_found.nKey == 174 );
496 CPPUNIT_ASSERT( f.m_found.nVal == 471 );
499 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
500 CPPUNIT_ASSERT( f.m_found.nKey == 190 );
501 CPPUNIT_ASSERT( f.m_found.nVal == 91 );
505 CPPUNIT_ASSERT( s.empty() );
506 CPPUNIT_ASSERT( check_size( s, 0 ));
514 CPPUNIT_ASSERT( s.bucket_count() == 32 );
515 CPPUNIT_ASSERT( s.lock_count() == 32 );
517 test_striped_with2( s );
521 void test_striped_with2( Set& s )
523 cds::OS::Timer timer;
528 for ( int i = 0; i < 10000; i++ ) {
532 CPPUNIT_MSG( " Duration=" << timer.duration() );
536 void test_int_with2( Set& s)
538 typedef typename Set::value_type value_type;
544 CPPUNIT_ASSERT( !s.find( 10 ) );
545 CPPUNIT_ASSERT( s.insert( 10 ));
546 CPPUNIT_ASSERT( !s.empty() );
547 CPPUNIT_ASSERT( check_size( s, 1 ));
548 CPPUNIT_ASSERT( s.find( 10 ) );
550 CPPUNIT_ASSERT( !s.insert( 10 ));
551 CPPUNIT_ASSERT( !s.empty() );
552 CPPUNIT_ASSERT( check_size( s, 1 ));
554 CPPUNIT_ASSERT( !s.find_with( 20, less<value_type>() ) );
555 CPPUNIT_ASSERT( s.insert( std::make_pair(20, 25) ));
556 CPPUNIT_ASSERT( !s.empty() );
557 CPPUNIT_ASSERT( check_size( s, 2 ));
558 CPPUNIT_ASSERT( s.find( 10 ) );
559 CPPUNIT_ASSERT( s.find_with( key = 20, less<value_type>() ) );
560 CPPUNIT_ASSERT( s.find_with( key, less<value_type>(), find_functor() ) );
564 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
565 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
566 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
567 CPPUNIT_ASSERT( f.m_found.nFindCount == 1 );
572 CPPUNIT_ASSERT( s.find_with( 20, less<value_type>(), find_functor() ) );
573 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
574 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
575 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
576 CPPUNIT_ASSERT( f.m_found.nFindCount == 2 );
578 CPPUNIT_ASSERT( !s.empty() );
579 CPPUNIT_ASSERT( check_size( s, 2 ));
581 CPPUNIT_ASSERT( !s.find( 25 ) );
582 CPPUNIT_ASSERT( s.insert( std::make_pair(25, -1), insert_functor() ));
583 CPPUNIT_ASSERT( !s.empty() );
584 CPPUNIT_ASSERT( check_size( s, 3 ));
588 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
589 CPPUNIT_ASSERT( f.m_found.nKey == 25 );
590 CPPUNIT_ASSERT( f.m_found.nVal == 2500 );
597 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
598 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
599 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
600 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
601 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
603 std::pair<bool, bool> ensureResult = s.ensure( key, ensure_functor() );
604 CPPUNIT_ASSERT( ensureResult.first && !ensureResult.second );
605 CPPUNIT_ASSERT( !s.empty() );
606 CPPUNIT_ASSERT( check_size( s, 3 ));
609 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
610 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
611 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
612 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 1 );
613 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
616 ensureResult = s.ensure( std::make_pair(13, 1300), ensure_functor() );
617 CPPUNIT_ASSERT( ensureResult.first && ensureResult.second );
618 CPPUNIT_ASSERT( !s.empty() );
619 CPPUNIT_ASSERT( check_size( s, 4 ));
623 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
624 CPPUNIT_ASSERT( f.m_found.nKey == 13 );
625 CPPUNIT_ASSERT( f.m_found.nVal == 1300 );
626 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
627 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 1 );
631 CPPUNIT_ASSERT( s.erase(13) );
632 CPPUNIT_ASSERT( !s.find( 13 ));
633 CPPUNIT_ASSERT( !s.empty() );
634 CPPUNIT_ASSERT( check_size( s, 3 ));
635 CPPUNIT_ASSERT( !s.erase(13) );
636 CPPUNIT_ASSERT( !s.empty() );
637 CPPUNIT_ASSERT( check_size( s, 3 ));
639 CPPUNIT_ASSERT( s.find( 10 ));
640 CPPUNIT_ASSERT( s.erase_with( 10, less<value_type>() ));
641 CPPUNIT_ASSERT( !s.find( 10 ));
642 CPPUNIT_ASSERT( !s.empty() );
643 CPPUNIT_ASSERT( check_size( s, 2 ));
644 CPPUNIT_ASSERT( !s.erase_with( 10, less<value_type>() ) );
645 CPPUNIT_ASSERT( !s.empty() );
646 CPPUNIT_ASSERT( check_size( s, 2 ));
648 CPPUNIT_ASSERT( s.find(20) );
651 CPPUNIT_ASSERT( s.erase( 20, boost::ref(f) ));
652 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
653 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
655 CPPUNIT_ASSERT( s.insert(235))
656 CPPUNIT_ASSERT( s.erase_with( 235, less<value_type>(), boost::ref(f) ));
657 CPPUNIT_ASSERT( f.m_found.nKey == 235 );
658 CPPUNIT_ASSERT( f.m_found.nVal == 235 );
660 CPPUNIT_ASSERT( !s.find( 20 ));
661 CPPUNIT_ASSERT( !s.empty() );
662 CPPUNIT_ASSERT( check_size( s, 1 ));
665 CPPUNIT_ASSERT( s.empty() );
666 CPPUNIT_ASSERT( check_size( s, 0 ));
668 # ifdef CDS_EMPLACE_SUPPORT
670 CPPUNIT_ASSERT( s.emplace( 151 )) ; // key = 151, val = 151
671 CPPUNIT_ASSERT( s.emplace( 174, 471 )) ; // key = 174, val = 471
672 CPPUNIT_ASSERT( s.emplace( std::make_pair( 190, 91 ) )) ; // key == 190, val = 91
673 CPPUNIT_ASSERT( !s.empty() );
674 CPPUNIT_ASSERT( check_size( s, 3 ));
676 CPPUNIT_ASSERT( s.find(151));
677 CPPUNIT_ASSERT( s.find(174));
678 CPPUNIT_ASSERT( s.find(190));
683 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
684 CPPUNIT_ASSERT( f.m_found.nKey == 151 );
685 CPPUNIT_ASSERT( f.m_found.nVal == 151 );
688 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
689 CPPUNIT_ASSERT( f.m_found.nKey == 174 );
690 CPPUNIT_ASSERT( f.m_found.nVal == 471 );
693 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
694 CPPUNIT_ASSERT( f.m_found.nKey == 190 );
695 CPPUNIT_ASSERT( f.m_found.nVal == 91 );
699 CPPUNIT_ASSERT( s.empty() );
700 CPPUNIT_ASSERT( check_size( s, 0 ));
705 void Striped_vector();
707 void Striped_hashset();
708 void Striped_slist();
709 void Striped_boost_list();
710 void Striped_boost_vector();
711 void Striped_boost_stable_vector();
712 void Striped_boost_flat_set();
713 void Striped_boost_set();
714 void Striped_boost_unordered_set();
716 void Refinable_list();
717 void Refinable_vector();
718 void Refinable_set();
719 void Refinable_hashset();
720 void Refinable_slist();
721 void Refinable_boost_list();
722 void Refinable_boost_vector();
723 void Refinable_boost_stable_vector();
724 void Refinable_boost_flat_set();
725 void Refinable_boost_set();
726 void Refinable_boost_unordered_set();
728 CPPUNIT_TEST_SUITE(StripedSetHdrTest)
729 CPPUNIT_TEST(Striped_list)
730 CPPUNIT_TEST(Striped_vector)
731 CPPUNIT_TEST(Striped_set)
732 CPPUNIT_TEST(Striped_hashset)
733 CPPUNIT_TEST(Striped_slist)
734 CPPUNIT_TEST(Striped_boost_list)
735 CPPUNIT_TEST(Striped_boost_vector)
736 CPPUNIT_TEST(Striped_boost_stable_vector)
737 CPPUNIT_TEST(Striped_boost_flat_set)
738 CPPUNIT_TEST(Striped_boost_set)
739 CPPUNIT_TEST(Striped_boost_unordered_set)
741 CPPUNIT_TEST(Refinable_list)
742 CPPUNIT_TEST(Refinable_vector)
743 CPPUNIT_TEST(Refinable_set)
744 CPPUNIT_TEST(Refinable_hashset)
745 CPPUNIT_TEST(Refinable_slist)
746 CPPUNIT_TEST(Refinable_boost_list)
747 CPPUNIT_TEST(Refinable_boost_vector)
748 CPPUNIT_TEST(Refinable_boost_stable_vector)
749 CPPUNIT_TEST(Refinable_boost_flat_set)
750 CPPUNIT_TEST(Refinable_boost_set)
751 CPPUNIT_TEST(Refinable_boost_unordered_set)
753 CPPUNIT_TEST_SUITE_END()
757 #endif // #ifndef __CDSTEST_HDR_STRIPED_SET_H