3 #ifndef __CDSTEST_HDR_CUCKOO_SET_H
4 #define __CDSTEST_HDR_CUCKOO_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 CuckooSetHdrTest: 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)
87 #ifdef CDS_MOVE_SEMANTICS_SUPPORT
106 size_t operator()( int i ) const
108 return co::v::hash<int>()( i );
111 size_t operator()( std::pair<int,int> const& i ) const
113 return co::v::hash<int>()( i.first );
116 template <typename Item>
117 size_t operator()( Item const& i ) const
119 return (*this)( i.key() );
123 struct hash2: private hash1
125 typedef hash1 base_class;
127 size_t operator()( int i ) const
129 return ~( base_class::operator()(i));
131 template <typename Item>
132 size_t operator()( const Item& i ) const
134 return ~( base_class::operator()(i));
136 size_t operator()( std::pair<int,int> const& i ) const
138 return ~( base_class::operator()(i));
142 struct simple_item_counter {
145 simple_item_counter()
164 operator size_t() const
170 template <typename T>
173 bool operator ()(const T& v1, const T& v2 ) const
175 return v1.key() < v2.key();
178 template <typename Q>
179 bool operator ()(const T& v1, const Q& v2 ) const
181 return v1.key() < v2;
184 template <typename Q>
185 bool operator ()(const Q& v1, const T& v2 ) const
187 return v1 < v2.key();
190 bool operator ()( std::pair<int, int> const& v1, const T& v2 ) const
192 return v1.first < v2.key();
195 bool operator ()(const T& v1, std::pair<int, int> const& v2 ) const
197 return v1.key() < v2.first;
201 template <typename T>
203 int operator ()(const T& v1, const T& v2 ) const
205 if ( v1.key() < v2.key() )
207 return v1.key() > v2.key() ? 1 : 0;
210 template <typename Q>
211 int operator ()(const T& v1, const Q& v2 ) const
215 return v1.key() > v2 ? 1 : 0;
218 template <typename Q>
219 int operator ()(const Q& v1, const T& v2 ) const
223 return v1 > v2.key() ? 1 : 0;
226 int operator()( std::pair<int,int> const& v1, T const& v2 ) const
228 if ( v1.first < v2.key() )
230 return v1.first > v2.key() ? 1 : 0;
233 int operator()( T const& v1, std::pair<int,int> const& v2 ) const
235 if ( v1.key() < v2.first )
237 return v1.key() > v2.first ? 1 : 0;
241 template <typename T>
244 bool operator ()(const T& v1, const T& v2 ) const
246 return v1.key() == v2.key();
249 template <typename Q>
250 bool operator ()(const T& v1, const Q& v2 ) const
252 return v1.key() == v2;
255 template <typename Q>
256 bool operator ()(const Q& v1, const T& v2 ) const
258 return v1 == v2.key();
261 bool operator ()( std::pair<int, int> const& v1, const T& v2 ) const
263 return v1.first == v2.key();
266 bool operator ()(const T& v1, std::pair<int, int> const& v2 ) const
268 return v1.key() == v2.first;
274 template <typename Item, typename T>
275 void operator()( Item& i, T& val )
279 template <typename Item, typename T>
280 void operator()( Item& i, T const& val )
286 template <typename Item>
291 template <typename T>
292 void operator()( Item& i, T& /*val*/ )
297 void operator()( Item const& i )
303 struct insert_functor
305 template <typename Item>
306 void operator()(Item& i )
308 i.nVal = i.nKey * 100;
312 template <typename Item, typename Q>
313 static void ensure_func( bool bNew, Item& i, Q& /*val*/ )
321 struct ensure_functor
323 template <typename Item, typename Q>
324 void operator()( bool bNew, Item& i, Q& val )
326 ensure_func( bNew, i, val );
330 template <class Set, typename Predicate>
331 void test_int_with( Set& s, Predicate pred )
333 typedef typename Set::value_type value_type;
339 CPPUNIT_ASSERT( !s.find( 10 ) );
340 CPPUNIT_ASSERT( s.insert( 10 ));
341 CPPUNIT_ASSERT( !s.empty() );
342 CPPUNIT_ASSERT( check_size( s, 1 ));
343 CPPUNIT_ASSERT( s.find( 10 ) );
345 CPPUNIT_ASSERT( !s.insert( 10 ));
346 CPPUNIT_ASSERT( !s.empty() );
347 CPPUNIT_ASSERT( check_size( s, 1 ));
349 CPPUNIT_ASSERT( !s.find_with( 20, pred ) );
350 CPPUNIT_ASSERT( s.insert( std::make_pair(20, 25) ));
351 CPPUNIT_ASSERT( !s.empty() );
352 CPPUNIT_ASSERT( check_size( s, 2 ));
353 CPPUNIT_ASSERT( s.find_with( 10, pred ) );
354 CPPUNIT_ASSERT( s.find( key = 20 ) );
355 CPPUNIT_ASSERT( s.find_with( key, pred, find_functor() ) );
359 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
360 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
361 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
362 CPPUNIT_ASSERT( f.m_found.nFindCount == 1 );
367 CPPUNIT_ASSERT( s.find_with( key, pred, boost::ref(f) ) );
368 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
369 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
370 CPPUNIT_ASSERT( f.m_found.nFindCount == 1 );
372 CPPUNIT_ASSERT( !s.empty() );
373 CPPUNIT_ASSERT( check_size( s, 2 ));
375 CPPUNIT_ASSERT( !s.find( 25 ) );
376 CPPUNIT_ASSERT( s.insert( std::make_pair(25, -1), insert_functor() ));
377 CPPUNIT_ASSERT( !s.empty() );
378 CPPUNIT_ASSERT( check_size( s, 3 ));
382 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
383 CPPUNIT_ASSERT( f.m_found.nKey == 25 );
384 CPPUNIT_ASSERT( f.m_found.nVal == 2500 );
391 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
392 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
393 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
394 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
395 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
397 std::pair<bool, bool> ensureResult = s.ensure( key, ensure_functor() );
398 CPPUNIT_ASSERT( ensureResult.first && !ensureResult.second );
399 CPPUNIT_ASSERT( !s.empty() );
400 CPPUNIT_ASSERT( check_size( s, 3 ));
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 == 1 );
407 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 0 );
410 ensureResult = s.ensure( std::make_pair(13, 1300), ensure_functor() );
411 CPPUNIT_ASSERT( ensureResult.first && ensureResult.second );
412 CPPUNIT_ASSERT( !s.empty() );
413 CPPUNIT_ASSERT( check_size( s, 4 ));
417 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
418 CPPUNIT_ASSERT( f.m_found.nKey == 13 );
419 CPPUNIT_ASSERT( f.m_found.nVal == 1300 );
420 CPPUNIT_ASSERT( f.m_found.nEnsureCount == 0 );
421 CPPUNIT_ASSERT( f.m_found.nEnsureNewCount == 1 );
425 CPPUNIT_ASSERT( s.erase(13) );
426 CPPUNIT_ASSERT( !s.find( 13 ));
427 CPPUNIT_ASSERT( !s.empty() );
428 CPPUNIT_ASSERT( check_size( s, 3 ));
429 CPPUNIT_ASSERT( !s.erase(13) );
430 CPPUNIT_ASSERT( !s.empty() );
431 CPPUNIT_ASSERT( check_size( s, 3 ));
433 CPPUNIT_ASSERT( s.find( 10 ));
434 CPPUNIT_ASSERT( s.erase_with( 10, pred ));
435 CPPUNIT_ASSERT( !s.find( 10 ));
436 CPPUNIT_ASSERT( !s.empty() );
437 CPPUNIT_ASSERT( check_size( s, 2 ));
438 CPPUNIT_ASSERT( !s.erase_with(10, pred) );
439 CPPUNIT_ASSERT( !s.empty() );
440 CPPUNIT_ASSERT( check_size( s, 2 ));
442 CPPUNIT_ASSERT( s.find(20) );
445 CPPUNIT_ASSERT( s.erase( 20, boost::ref(f) ));
446 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
447 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
449 CPPUNIT_ASSERT( s.insert(235))
450 CPPUNIT_ASSERT( s.erase_with( 235, pred, boost::ref(f) ));
451 CPPUNIT_ASSERT( f.m_found.nKey == 235 );
452 CPPUNIT_ASSERT( f.m_found.nVal == 235 );
454 CPPUNIT_ASSERT( !s.find( 20 ));
455 CPPUNIT_ASSERT( !s.empty() );
456 CPPUNIT_ASSERT( check_size( s, 1 ));
459 CPPUNIT_ASSERT( s.empty() );
460 CPPUNIT_ASSERT( check_size( s, 0 ));
462 # ifdef CDS_EMPLACE_SUPPORT
464 CPPUNIT_ASSERT( s.emplace( 151 )) ; // key = 151, val = 151
465 CPPUNIT_ASSERT( s.emplace( 174, 471 )) ; // key = 174, val = 471
466 CPPUNIT_ASSERT( s.emplace( std::make_pair( 190, 91 ) )) ; // key == 190, val = 91
467 CPPUNIT_ASSERT( !s.empty() );
468 CPPUNIT_ASSERT( check_size( s, 3 ));
470 CPPUNIT_ASSERT( s.find(151));
471 CPPUNIT_ASSERT( s.find_with(174, pred ));
472 CPPUNIT_ASSERT( s.find(190));
477 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
478 CPPUNIT_ASSERT( f.m_found.nKey == 151 );
479 CPPUNIT_ASSERT( f.m_found.nVal == 151 );
482 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
483 CPPUNIT_ASSERT( f.m_found.nKey == 174 );
484 CPPUNIT_ASSERT( f.m_found.nVal == 471 );
487 CPPUNIT_ASSERT( s.find( key, boost::ref(f) ) );
488 CPPUNIT_ASSERT( f.m_found.nKey == 190 );
489 CPPUNIT_ASSERT( f.m_found.nVal == 91 );
493 CPPUNIT_ASSERT( s.empty() );
494 CPPUNIT_ASSERT( check_size( s, 0 ));
498 template <class Set, class Predicate>
502 CPPUNIT_ASSERT( s.bucket_count() == 32 );
503 CPPUNIT_ASSERT( s.lock_count() == 32 );
505 cds::OS::Timer timer;
507 test_int_with( s, Predicate() );
510 for ( int i = 0; i < 10000; i++ ) {
514 CPPUNIT_MSG( " Duration=" << timer.duration() );
518 void Cuckoo_Striped_list_unord();
519 void Cuckoo_Striped_list_unord_storehash();
520 void Cuckoo_Striped_list_cmp();
521 void Cuckoo_Striped_list_cmp_storehash();
522 void Cuckoo_Striped_list_less();
523 void Cuckoo_Striped_list_less_storehash();
524 void Cuckoo_Striped_list_less_cmp();
525 void Cuckoo_Striped_list_less_cmp_storehash();
526 void Cuckoo_Striped_list_less_cmp_eq();
527 void Cuckoo_Striped_list_less_cmp_eq_storehash();
529 void Cuckoo_Striped_vector_unord();
530 void Cuckoo_Striped_vector_unord_storehash();
531 void Cuckoo_Striped_vector_cmp();
532 void Cuckoo_Striped_vector_cmp_storehash();
533 void Cuckoo_Striped_vector_less();
534 void Cuckoo_Striped_vector_less_storehash();
535 void Cuckoo_Striped_vector_less_cmp();
536 void Cuckoo_Striped_vector_less_cmp_storehash();
537 void Cuckoo_Striped_vector_less_cmp_eq();
538 void Cuckoo_Striped_vector_less_cmp_eq_storehash();
540 void Cuckoo_Refinable_list_unord();
541 void Cuckoo_Refinable_list_unord_storehash();
542 void Cuckoo_Refinable_list_cmp();
543 void Cuckoo_Refinable_list_cmp_storehash();
544 void Cuckoo_Refinable_list_less();
545 void Cuckoo_Refinable_list_less_storehash();
546 void Cuckoo_Refinable_list_less_cmp();
547 void Cuckoo_Refinable_list_less_cmp_storehash();
548 void Cuckoo_Refinable_list_less_cmp_eq();
549 void Cuckoo_Refinable_list_less_cmp_eq_storehash();
551 void Cuckoo_Refinable_vector_unord();
552 void Cuckoo_Refinable_vector_unord_storehash();
553 void Cuckoo_Refinable_vector_cmp();
554 void Cuckoo_Refinable_vector_cmp_storehash();
555 void Cuckoo_Refinable_vector_less();
556 void Cuckoo_Refinable_vector_less_storehash();
557 void Cuckoo_Refinable_vector_less_cmp();
558 void Cuckoo_Refinable_vector_less_cmp_storehash();
559 void Cuckoo_Refinable_vector_less_cmp_eq();
560 void Cuckoo_Refinable_vector_less_cmp_eq_storehash();
562 CPPUNIT_TEST_SUITE(CuckooSetHdrTest)
563 CPPUNIT_TEST( Cuckoo_Striped_list_unord)
564 CPPUNIT_TEST( Cuckoo_Striped_list_unord_storehash)
565 CPPUNIT_TEST( Cuckoo_Striped_list_cmp)
566 CPPUNIT_TEST( Cuckoo_Striped_list_cmp_storehash)
567 CPPUNIT_TEST( Cuckoo_Striped_list_less)
568 CPPUNIT_TEST( Cuckoo_Striped_list_less_storehash)
569 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp)
570 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp_storehash)
571 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp_eq)
572 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp_eq_storehash)
574 CPPUNIT_TEST( Cuckoo_Striped_vector_unord)
575 CPPUNIT_TEST( Cuckoo_Striped_vector_unord_storehash)
576 CPPUNIT_TEST( Cuckoo_Striped_vector_cmp)
577 CPPUNIT_TEST( Cuckoo_Striped_vector_cmp_storehash)
578 CPPUNIT_TEST( Cuckoo_Striped_vector_less)
579 CPPUNIT_TEST( Cuckoo_Striped_vector_less_storehash)
580 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp)
581 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp_storehash)
582 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp_eq)
583 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp_eq_storehash)
585 CPPUNIT_TEST( Cuckoo_Refinable_list_unord)
586 CPPUNIT_TEST( Cuckoo_Refinable_list_unord_storehash)
587 CPPUNIT_TEST( Cuckoo_Refinable_list_cmp)
588 CPPUNIT_TEST( Cuckoo_Refinable_list_cmp_storehash)
589 CPPUNIT_TEST( Cuckoo_Refinable_list_less)
590 CPPUNIT_TEST( Cuckoo_Refinable_list_less_storehash)
591 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp)
592 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp_storehash)
593 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp_eq)
594 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp_eq_storehash)
596 CPPUNIT_TEST( Cuckoo_Refinable_vector_unord)
597 CPPUNIT_TEST( Cuckoo_Refinable_vector_unord_storehash)
598 CPPUNIT_TEST( Cuckoo_Refinable_vector_cmp)
599 CPPUNIT_TEST( Cuckoo_Refinable_vector_cmp_storehash)
600 CPPUNIT_TEST( Cuckoo_Refinable_vector_less)
601 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_storehash)
602 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp)
603 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp_storehash)
604 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp_eq)
605 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp_eq_storehash)
606 CPPUNIT_TEST_SUITE_END()
611 #endif // #ifndef __CDSTEST_HDR_CUCKOO_SET_H