2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSTEST_HDR_CUCKOO_SET_H
32 #define CDSTEST_HDR_CUCKOO_SET_H
34 #include "cppunit/cppunit_proxy.h"
35 #include "size_check.h"
37 #include <cds/opt/hash.h>
38 #include <cds/os/timer.h>
39 #include <functional> // ref
41 // forward namespace declaration
43 namespace container {}
48 using misc::check_size;
50 namespace cc = cds::container;
51 namespace co = cds::opt;
54 class CuckooSetHdrTest: public CppUnitMini::TestCase
59 unsigned int nFindCount ; // count of find-functor calling
60 unsigned int nUpdateNewCount;
61 unsigned int nUpdateCount;
65 memset( this, 0, sizeof(*this));
68 void copy( stat const& s )
70 nFindCount = s.nFindCount;
71 nUpdateCount = s.nUpdateCount;
72 nUpdateNewCount = s.nUpdateNewCount;
76 struct item: public stat
89 item (int key, int val )
94 item( std::pair<int,int> const& p )
104 item& operator=(item const& i)
130 size_t operator()( int i ) const
132 return co::v::hash<int>()( i );
135 size_t operator()( std::pair<int,int> const& i ) const
137 return co::v::hash<int>()( i.first );
140 template <typename Item>
141 size_t operator()( Item const& i ) const
143 return (*this)( i.key() );
147 struct hash2: private hash1
149 typedef hash1 base_class;
151 size_t operator()( int i ) const
153 return ~( base_class::operator()(i));
155 template <typename Item>
156 size_t operator()( const Item& i ) const
158 return ~( base_class::operator()(i));
160 size_t operator()( std::pair<int,int> const& i ) const
162 return ~( base_class::operator()(i));
166 struct simple_item_counter {
169 simple_item_counter()
188 operator size_t() const
194 template <typename T>
197 bool operator ()(const T& v1, const T& v2 ) const
199 return v1.key() < v2.key();
202 template <typename Q>
203 bool operator ()(const T& v1, const Q& v2 ) const
205 return v1.key() < v2;
208 template <typename Q>
209 bool operator ()(const Q& v1, const T& v2 ) const
211 return v1 < v2.key();
214 bool operator ()( std::pair<int, int> const& v1, const T& v2 ) const
216 return v1.first < v2.key();
219 bool operator ()(const T& v1, std::pair<int, int> const& v2 ) const
221 return v1.key() < v2.first;
225 template <typename T>
227 int operator ()(const T& v1, const T& v2 ) const
229 if ( v1.key() < v2.key() )
231 return v1.key() > v2.key() ? 1 : 0;
234 template <typename Q>
235 int operator ()(const T& v1, const Q& v2 ) const
239 return v1.key() > v2 ? 1 : 0;
242 template <typename Q>
243 int operator ()(const Q& v1, const T& v2 ) const
247 return v1 > v2.key() ? 1 : 0;
250 int operator()( std::pair<int,int> const& v1, T const& v2 ) const
252 if ( v1.first < v2.key() )
254 return v1.first > v2.key() ? 1 : 0;
257 int operator()( T const& v1, std::pair<int,int> const& v2 ) const
259 if ( v1.key() < v2.first )
261 return v1.key() > v2.first ? 1 : 0;
265 template <typename T>
268 bool operator ()(const T& v1, const T& v2 ) const
270 return v1.key() == v2.key();
273 template <typename Q>
274 bool operator ()(const T& v1, const Q& v2 ) const
276 return v1.key() == v2;
279 template <typename Q>
280 bool operator ()(const Q& v1, const T& v2 ) const
282 return v1 == v2.key();
285 bool operator ()( std::pair<int, int> const& v1, const T& v2 ) const
287 return v1.first == v2.key();
290 bool operator ()(const T& v1, std::pair<int, int> const& v2 ) const
292 return v1.key() == v2.first;
298 template <typename Item, typename T>
299 void operator()( Item& i, T& /*val*/ )
303 template <typename Item, typename T>
304 void operator()( Item& i, T const& /*val*/ )
310 template <typename Item>
315 template <typename T>
316 void operator()( Item& i, T& /*val*/ )
321 void operator()( Item const& i )
327 struct insert_functor
329 template <typename Item>
330 void operator()(Item& i )
332 i.nVal = i.nKey * 100;
336 template <typename Item, typename Q>
337 static void update_func( bool bNew, Item& i, Q& /*val*/ )
345 struct update_functor
347 template <typename Item, typename Q>
348 void operator()( bool bNew, Item& i, Q& val )
350 update_func( bNew, i, val );
354 template <class Set, typename Predicate>
355 void test_int_with( Set& s, Predicate pred )
357 typedef typename Set::value_type value_type;
363 CPPUNIT_ASSERT( !s.contains( 10 ) );
364 CPPUNIT_ASSERT( s.insert( 10 ));
365 CPPUNIT_ASSERT( !s.empty() );
366 CPPUNIT_ASSERT( check_size( s, 1 ));
367 CPPUNIT_ASSERT( s.contains( 10 ) );
369 CPPUNIT_ASSERT( !s.insert( 10 ));
370 CPPUNIT_ASSERT( !s.empty() );
371 CPPUNIT_ASSERT( check_size( s, 1 ));
373 CPPUNIT_ASSERT( !s.contains( 20, pred ) );
374 CPPUNIT_ASSERT( s.insert( std::make_pair(20, 25) ));
375 CPPUNIT_ASSERT( !s.empty() );
376 CPPUNIT_ASSERT( check_size( s, 2 ));
377 CPPUNIT_ASSERT( s.contains( 10, pred ) );
378 CPPUNIT_ASSERT( s.contains( key = 20 ) );
379 CPPUNIT_ASSERT( s.find_with( key, pred, find_functor() ) );
383 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
384 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
385 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
386 CPPUNIT_ASSERT( f.m_found.nFindCount == 1 );
391 CPPUNIT_ASSERT( s.find_with( key, pred, std::ref( f ) ) );
392 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
393 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
394 CPPUNIT_ASSERT( f.m_found.nFindCount == 1 );
396 CPPUNIT_ASSERT( !s.empty() );
397 CPPUNIT_ASSERT( check_size( s, 2 ));
399 CPPUNIT_ASSERT( !s.contains( 25 ) );
400 CPPUNIT_ASSERT( s.insert( std::make_pair(25, -1), insert_functor() ));
401 CPPUNIT_ASSERT( !s.empty() );
402 CPPUNIT_ASSERT( check_size( s, 3 ));
406 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
407 CPPUNIT_ASSERT( f.m_found.nKey == 25 );
408 CPPUNIT_ASSERT( f.m_found.nVal == 2500 );
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.nUpdateCount == 0 );
419 CPPUNIT_ASSERT( f.m_found.nUpdateNewCount == 0 );
421 std::pair<bool, bool> updateResult = s.update( key, update_functor() );
422 CPPUNIT_ASSERT( updateResult.first && !updateResult.second );
423 CPPUNIT_ASSERT( !s.empty() );
424 CPPUNIT_ASSERT( check_size( s, 3 ));
427 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
428 CPPUNIT_ASSERT( f.m_found.nKey == 10 );
429 CPPUNIT_ASSERT( f.m_found.nVal == 10 );
430 CPPUNIT_ASSERT( f.m_found.nUpdateCount == 1 );
431 CPPUNIT_ASSERT( f.m_found.nUpdateNewCount == 0 );
434 updateResult = s.update(std::make_pair(13, 1300), update_functor(), false);
435 CPPUNIT_ASSERT(!updateResult.first && !updateResult.second);
437 updateResult = s.update( std::make_pair(13, 1300), update_functor() );
438 CPPUNIT_ASSERT( updateResult.first && updateResult.second );
439 CPPUNIT_ASSERT( !s.empty() );
440 CPPUNIT_ASSERT( check_size( s, 4 ));
444 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
445 CPPUNIT_ASSERT( f.m_found.nKey == 13 );
446 CPPUNIT_ASSERT( f.m_found.nVal == 1300 );
447 CPPUNIT_ASSERT( f.m_found.nUpdateCount == 0 );
448 CPPUNIT_ASSERT( f.m_found.nUpdateNewCount == 1 );
452 CPPUNIT_ASSERT( s.erase(13) );
453 CPPUNIT_ASSERT( !s.contains( 13 ));
454 CPPUNIT_ASSERT( !s.empty() );
455 CPPUNIT_ASSERT( check_size( s, 3 ));
456 CPPUNIT_ASSERT( !s.erase(13) );
457 CPPUNIT_ASSERT( !s.empty() );
458 CPPUNIT_ASSERT( check_size( s, 3 ));
460 CPPUNIT_ASSERT( s.contains( 10 ));
461 CPPUNIT_ASSERT( s.erase_with( 10, pred ));
462 CPPUNIT_ASSERT( !s.contains( 10 ));
463 CPPUNIT_ASSERT( !s.empty() );
464 CPPUNIT_ASSERT( check_size( s, 2 ));
465 CPPUNIT_ASSERT( !s.erase_with(10, pred) );
466 CPPUNIT_ASSERT( !s.empty() );
467 CPPUNIT_ASSERT( check_size( s, 2 ));
469 CPPUNIT_ASSERT( s.contains(20) );
472 CPPUNIT_ASSERT( s.erase( 20, std::ref( f ) ) );
473 CPPUNIT_ASSERT( f.m_found.nKey == 20 );
474 CPPUNIT_ASSERT( f.m_found.nVal == 25 );
476 CPPUNIT_ASSERT( s.insert(235))
477 CPPUNIT_ASSERT( s.erase_with( 235, pred, std::ref( f ) ) );
478 CPPUNIT_ASSERT( f.m_found.nKey == 235 );
479 CPPUNIT_ASSERT( f.m_found.nVal == 235 );
481 CPPUNIT_ASSERT( !s.contains( 20 ));
482 CPPUNIT_ASSERT( !s.empty() );
483 CPPUNIT_ASSERT( check_size( s, 1 ));
486 CPPUNIT_ASSERT( s.empty() );
487 CPPUNIT_ASSERT( check_size( s, 0 ));
490 CPPUNIT_ASSERT( s.emplace( 151 )) ; // key = 151, val = 151
491 CPPUNIT_ASSERT( s.emplace( 174, 471 )) ; // key = 174, val = 471
492 CPPUNIT_ASSERT( s.emplace( std::make_pair( 190, 91 ) )) ; // key == 190, val = 91
493 CPPUNIT_ASSERT( !s.empty() );
494 CPPUNIT_ASSERT( check_size( s, 3 ));
496 CPPUNIT_ASSERT( s.contains(151));
497 CPPUNIT_ASSERT( s.contains(174, pred ));
498 CPPUNIT_ASSERT( s.contains(190));
503 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
504 CPPUNIT_ASSERT( f.m_found.nKey == 151 );
505 CPPUNIT_ASSERT( f.m_found.nVal == 151 );
508 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
509 CPPUNIT_ASSERT( f.m_found.nKey == 174 );
510 CPPUNIT_ASSERT( f.m_found.nVal == 471 );
513 CPPUNIT_ASSERT( s.find( key, std::ref( f ) ) );
514 CPPUNIT_ASSERT( f.m_found.nKey == 190 );
515 CPPUNIT_ASSERT( f.m_found.nVal == 91 );
519 CPPUNIT_ASSERT( s.empty() );
520 CPPUNIT_ASSERT( check_size( s, 0 ));
523 template <class Set, class Predicate>
527 CPPUNIT_ASSERT( s.bucket_count() == 32 );
528 CPPUNIT_ASSERT( s.lock_count() == 32 );
530 cds::OS::Timer timer;
532 test_int_with( s, Predicate() );
535 for ( int i = 0; i < 10000; i++ ) {
539 CPPUNIT_MSG( " Duration=" << timer.duration() );
543 void Cuckoo_Striped_list_unord();
544 void Cuckoo_Striped_list_unord_storehash();
545 void Cuckoo_Striped_list_cmp();
546 void Cuckoo_Striped_list_cmp_storehash();
547 void Cuckoo_Striped_list_less();
548 void Cuckoo_Striped_list_less_storehash();
549 void Cuckoo_Striped_list_less_cmp();
550 void Cuckoo_Striped_list_less_cmp_storehash();
551 void Cuckoo_Striped_list_less_cmp_eq();
552 void Cuckoo_Striped_list_less_cmp_eq_storehash();
554 void Cuckoo_Striped_vector_unord();
555 void Cuckoo_Striped_vector_unord_storehash();
556 void Cuckoo_Striped_vector_cmp();
557 void Cuckoo_Striped_vector_cmp_storehash();
558 void Cuckoo_Striped_vector_less();
559 void Cuckoo_Striped_vector_less_storehash();
560 void Cuckoo_Striped_vector_less_cmp();
561 void Cuckoo_Striped_vector_less_cmp_storehash();
562 void Cuckoo_Striped_vector_less_cmp_eq();
563 void Cuckoo_Striped_vector_less_cmp_eq_storehash();
565 void Cuckoo_Refinable_list_unord();
566 void Cuckoo_Refinable_list_unord_storehash();
567 void Cuckoo_Refinable_list_cmp();
568 void Cuckoo_Refinable_list_cmp_storehash();
569 void Cuckoo_Refinable_list_less();
570 void Cuckoo_Refinable_list_less_storehash();
571 void Cuckoo_Refinable_list_less_cmp();
572 void Cuckoo_Refinable_list_less_cmp_storehash();
573 void Cuckoo_Refinable_list_less_cmp_eq();
574 void Cuckoo_Refinable_list_less_cmp_eq_storehash();
576 void Cuckoo_Refinable_vector_unord();
577 void Cuckoo_Refinable_vector_unord_storehash();
578 void Cuckoo_Refinable_vector_cmp();
579 void Cuckoo_Refinable_vector_cmp_storehash();
580 void Cuckoo_Refinable_vector_less();
581 void Cuckoo_Refinable_vector_less_storehash();
582 void Cuckoo_Refinable_vector_less_cmp();
583 void Cuckoo_Refinable_vector_less_cmp_storehash();
584 void Cuckoo_Refinable_vector_less_cmp_eq();
585 void Cuckoo_Refinable_vector_less_cmp_eq_storehash();
587 CPPUNIT_TEST_SUITE(CuckooSetHdrTest)
588 CPPUNIT_TEST( Cuckoo_Striped_list_unord)
589 CPPUNIT_TEST( Cuckoo_Striped_list_unord_storehash)
590 CPPUNIT_TEST( Cuckoo_Striped_list_cmp)
591 CPPUNIT_TEST( Cuckoo_Striped_list_cmp_storehash)
592 CPPUNIT_TEST( Cuckoo_Striped_list_less)
593 CPPUNIT_TEST( Cuckoo_Striped_list_less_storehash)
594 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp)
595 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp_storehash)
596 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp_eq)
597 CPPUNIT_TEST( Cuckoo_Striped_list_less_cmp_eq_storehash)
599 CPPUNIT_TEST( Cuckoo_Striped_vector_unord)
600 CPPUNIT_TEST( Cuckoo_Striped_vector_unord_storehash)
601 CPPUNIT_TEST( Cuckoo_Striped_vector_cmp)
602 CPPUNIT_TEST( Cuckoo_Striped_vector_cmp_storehash)
603 CPPUNIT_TEST( Cuckoo_Striped_vector_less)
604 CPPUNIT_TEST( Cuckoo_Striped_vector_less_storehash)
605 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp)
606 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp_storehash)
607 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp_eq)
608 CPPUNIT_TEST( Cuckoo_Striped_vector_less_cmp_eq_storehash)
610 CPPUNIT_TEST( Cuckoo_Refinable_list_unord)
611 CPPUNIT_TEST( Cuckoo_Refinable_list_unord_storehash)
612 CPPUNIT_TEST( Cuckoo_Refinable_list_cmp)
613 CPPUNIT_TEST( Cuckoo_Refinable_list_cmp_storehash)
614 CPPUNIT_TEST( Cuckoo_Refinable_list_less)
615 CPPUNIT_TEST( Cuckoo_Refinable_list_less_storehash)
616 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp)
617 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp_storehash)
618 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp_eq)
619 CPPUNIT_TEST( Cuckoo_Refinable_list_less_cmp_eq_storehash)
621 CPPUNIT_TEST( Cuckoo_Refinable_vector_unord)
622 CPPUNIT_TEST( Cuckoo_Refinable_vector_unord_storehash)
623 CPPUNIT_TEST( Cuckoo_Refinable_vector_cmp)
624 CPPUNIT_TEST( Cuckoo_Refinable_vector_cmp_storehash)
625 CPPUNIT_TEST( Cuckoo_Refinable_vector_less)
626 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_storehash)
627 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp)
628 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp_storehash)
629 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp_eq)
630 CPPUNIT_TEST( Cuckoo_Refinable_vector_less_cmp_eq_storehash)
631 CPPUNIT_TEST_SUITE_END()
636 #endif // #ifndef CDSTEST_HDR_CUCKOO_SET_H