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_FELDMAN_HASHMAP_H
32 #define CDSTEST_HDR_FELDMAN_HASHMAP_H
34 #include "cppunit/cppunit_proxy.h"
36 // forward declaration
38 namespace container {}
43 namespace cc = cds::container;
44 namespace co = cds::opt;
46 class FeldmanHashMapHdrTest : public CppUnitMini::TestCase
50 unsigned int nInsertCall;
51 unsigned int nFindCall;
52 unsigned int nEraseCall;
53 mutable unsigned int nIteratorCall;
62 explicit Item( unsigned int n )
76 hash128(size_t l, size_t h) : lo(l), hi(h) {}
77 hash128( hash128 const& h) : lo(h.lo), hi(h.hi) {}
80 hash128 operator()( size_t n ) const
82 return hash128( std::hash<size_t>()( n ), std::hash<size_t>()( ~n ));
84 hash128 operator()( hash128 const& n ) const
86 return hash128( std::hash<size_t>()( n.lo ), std::hash<size_t>()( ~n.hi ));
91 bool operator()( hash128 const& lhs, hash128 const& rhs ) const
93 if ( lhs.hi != rhs.hi )
94 return lhs.hi < rhs.hi;
95 return lhs.lo < rhs.lo;
100 int operator()( hash128 const& lhs, hash128 const& rhs ) const
102 if ( lhs.hi != rhs.hi )
103 return lhs.hi < rhs.hi ? -1 : 1;
104 return lhs.lo < rhs.lo ? -1 : lhs.lo == rhs.lo ? 0 : 1;
108 friend bool operator==( hash128 const& lhs, hash128 const& rhs )
110 return cmp()( lhs, rhs ) == 0;
112 friend bool operator!=(hash128 const& lhs, hash128 const& rhs)
114 return !( lhs == rhs );
118 template <typename Map>
119 void test_hp( size_t nHeadBits, size_t nArrayBits )
121 typedef typename Map::hash_type hash_type;
122 typedef typename Map::key_type key_type;
123 typedef typename Map::mapped_type mapped_type;
124 typedef typename Map::value_type value_type;
125 typedef typename Map::guarded_ptr guarded_ptr;
127 size_t const capacity = 1000;
129 Map m( nHeadBits, nArrayBits );
130 CPPUNIT_MSG("Array size: head=" << m.head_size() << ", array_node=" << m.array_node_size());
131 //CPPUNIT_ASSERT(m.head_size() >= (size_t(1) << nHeadBits));
132 //CPPUNIT_ASSERT(m.array_node_size() == (size_t(1) << nArrayBits));
134 CPPUNIT_ASSERT(m.empty());
135 CPPUNIT_ASSERT(m.size() == 0);
137 // insert( key )/update()/get()/find()
138 for ( size_t i = 0; i < capacity; ++i ) {
140 CPPUNIT_ASSERT(!m.contains( key ))
141 CPPUNIT_ASSERT(m.insert( key ));
142 CPPUNIT_ASSERT(m.contains( key ));
143 CPPUNIT_ASSERT(m.size() == i + 1);
145 auto ret = m.update(key, [] ( value_type& v, value_type * old ) {
146 CPPUNIT_ASSERT_CURRENT( old != nullptr );
147 ++v.second.nInsertCall;
149 CPPUNIT_ASSERT( ret.first );
150 CPPUNIT_ASSERT( !ret.second );
152 CPPUNIT_ASSERT(m.find(key, [](value_type& v) { ++v.second.nFindCall;} ));
154 guarded_ptr gp{ m.get( key ) };
155 CPPUNIT_ASSERT( gp );
156 CPPUNIT_ASSERT( gp->first == key );
157 CPPUNIT_ASSERT( gp->second.nInsertCall == 1 );
158 CPPUNIT_ASSERT( gp->second.nFindCall == 1 );
160 CPPUNIT_ASSERT(!m.empty());
161 CPPUNIT_ASSERT(m.size() == capacity);
165 for ( auto it = m.begin(), itEnd = m.end(); it != itEnd; ++it ) {
166 CPPUNIT_ASSERT( it->second.nIteratorCall == 0 );
167 CPPUNIT_ASSERT( it->second.nInsertCall == 1 );
168 CPPUNIT_ASSERT( (*it).second.nFindCall == 1 );
169 it->second.nIteratorCall += 1;
172 CPPUNIT_ASSERT( nCount == capacity );
175 for ( auto it = m.rbegin(), itEnd = m.rend(); it != itEnd; ++it ) {
176 CPPUNIT_ASSERT( it->second.nInsertCall == 1 );
177 CPPUNIT_ASSERT( (*it).second.nFindCall == 1 );
178 CPPUNIT_ASSERT( it->second.nIteratorCall == 1 );
179 (*it).second.nIteratorCall += 1;
182 CPPUNIT_ASSERT( nCount == capacity );
185 for ( auto it = m.cbegin(), itEnd = m.cend(); it != itEnd; ++it ) {
186 CPPUNIT_ASSERT( it->second.nInsertCall == 1 );
187 CPPUNIT_ASSERT( (*it).second.nFindCall == 1 );
188 CPPUNIT_ASSERT( it->second.nIteratorCall == 2 );
189 (*it).second.nIteratorCall += 1;
192 CPPUNIT_ASSERT( nCount == capacity );
195 for ( auto it = m.crbegin(), itEnd = m.crend(); it != itEnd; ++it ) {
196 CPPUNIT_ASSERT( it->second.nInsertCall == 1 );
197 CPPUNIT_ASSERT( (*it).second.nFindCall == 1 );
198 CPPUNIT_ASSERT( it->second.nIteratorCall == 3 );
199 (*it).second.nIteratorCall += 1;
202 CPPUNIT_ASSERT( nCount == capacity );
205 for ( size_t i = 0; i < capacity; i++ ) {
207 CPPUNIT_ASSERT( m.find( key, [key]( value_type& v ) {
208 CPPUNIT_ASSERT_CURRENT( v.first == key );
209 CPPUNIT_ASSERT_CURRENT( v.second.nInsertCall == 1 );
210 CPPUNIT_ASSERT_CURRENT( v.second.nFindCall == 1 );
211 CPPUNIT_ASSERT_CURRENT( v.second.nIteratorCall == 4 );
216 for ( size_t i = capacity; i > 0; --i ) {
217 size_t key = (i -1) * 57;
218 guarded_ptr gp = m.get( key );
219 CPPUNIT_ASSERT( gp );
220 CPPUNIT_ASSERT( gp->first == key );
221 CPPUNIT_ASSERT( gp->second.nInsertCall == 1 );
222 CPPUNIT_ASSERT( gp->second.nFindCall == 1 );
223 CPPUNIT_ASSERT( (*gp).second.nIteratorCall == 4 );
225 CPPUNIT_ASSERT(m.erase( key ));
228 CPPUNIT_ASSERT( !gp );
229 CPPUNIT_ASSERT(!m.contains( key ));
231 CPPUNIT_ASSERT( m.empty());
232 CPPUNIT_ASSERT(m.size() == 0);
234 // Iterators on empty map
235 CPPUNIT_ASSERT(m.begin() == m.end());
236 CPPUNIT_ASSERT(m.cbegin() == m.cend());
237 CPPUNIT_ASSERT(m.rbegin() == m.rend());
238 CPPUNIT_ASSERT(m.crbegin() == m.crend());
240 // insert( key, val )
241 for ( size_t i = 0; i < capacity; ++i ) {
242 CPPUNIT_ASSERT(!m.contains(i));
243 CPPUNIT_ASSERT(m.insert( i, (unsigned int) i * 100));
244 CPPUNIT_ASSERT( m.contains(i));
245 CPPUNIT_ASSERT( m.find( i, [i]( value_type& v ) {
246 CPPUNIT_ASSERT_CURRENT( v.first == i );
247 CPPUNIT_ASSERT_CURRENT( v.second.nInsertCall == i * 100 );
250 CPPUNIT_ASSERT( !m.empty());
251 CPPUNIT_ASSERT(m.size() == capacity);
253 // erase( key, func )
254 for ( size_t i = 0; i < capacity; ++i ) {
255 CPPUNIT_ASSERT( m.contains(i));
256 CPPUNIT_ASSERT( m.erase( i, [i]( value_type& v ) {
257 CPPUNIT_ASSERT_CURRENT( v.first == i );
258 CPPUNIT_ASSERT_CURRENT( v.second.nInsertCall == i * 100 );
259 v.second.nInsertCall = 0;
262 CPPUNIT_ASSERT( m.empty());
263 CPPUNIT_ASSERT(m.size() == 0 );
266 for ( size_t i = 0; i < capacity; ++i ) {
267 size_t key = i * 121;
268 CPPUNIT_ASSERT(!m.contains(key));
269 CPPUNIT_ASSERT( m.insert_with( key, [key]( value_type& v ) {
270 CPPUNIT_ASSERT_CURRENT( v.first == key );
271 CPPUNIT_ASSERT_CURRENT( v.second.nInsertCall == 0 );
272 v.second.nInsertCall = decltype(v.second.nInsertCall)( key );
274 CPPUNIT_ASSERT(m.find(key, [key] (value_type& v ) {
275 CPPUNIT_ASSERT_CURRENT( v.first == key );
276 CPPUNIT_ASSERT_CURRENT( v.second.nInsertCall == key );
278 CPPUNIT_ASSERT(m.size() == i + 1);
280 CPPUNIT_ASSERT( !m.empty());
281 CPPUNIT_ASSERT(m.size() == capacity);
284 for ( auto it = m.begin(), itEnd = m.end(); it != itEnd; ++it ) {
285 CPPUNIT_ASSERT( it->first == it->second.nInsertCall );
286 CPPUNIT_ASSERT( it->second.nIteratorCall == 0 );
287 it->second.nIteratorCall += 1;
290 CPPUNIT_ASSERT( nCount == capacity );
293 for ( auto it = m.rbegin(), itEnd = m.rend(); it != itEnd; ++it ) {
294 CPPUNIT_ASSERT( it->first == it->second.nInsertCall );
295 CPPUNIT_ASSERT( it->second.nIteratorCall == 1 );
296 it->second.nIteratorCall += 1;
299 CPPUNIT_ASSERT( nCount == capacity );
301 // erase_at( iterator )
303 for ( auto it = m.begin(), itEnd = m.end(); it != itEnd; ++it ) {
304 CPPUNIT_ASSERT( it->first == it->second.nInsertCall );
305 CPPUNIT_ASSERT( it->second.nIteratorCall == 2 );
306 CPPUNIT_ASSERT(m.erase_at( it ));
308 CPPUNIT_ASSERT(!m.contains( it->first ));
310 CPPUNIT_ASSERT( nCount == capacity );
311 CPPUNIT_ASSERT( m.empty());
312 CPPUNIT_ASSERT(m.size() == 0 );
315 for ( size_t i = 0; i < capacity; ++i ) {
316 size_t key = i * 1023;
317 CPPUNIT_ASSERT(!m.contains(key));
318 CPPUNIT_ASSERT( m.emplace( key, (unsigned int) i ));
319 CPPUNIT_ASSERT(m.find(key, [key] (value_type& v ) {
320 CPPUNIT_ASSERT_CURRENT( v.first == key );
321 CPPUNIT_ASSERT_CURRENT( v.second.nInsertCall * 1023 == key );
323 CPPUNIT_ASSERT(m.size() == i + 1);
325 CPPUNIT_ASSERT( !m.empty());
326 CPPUNIT_ASSERT(m.size() == capacity);
328 // erase_at( reverse_iterator )
330 for ( auto it = m.rbegin(), itEnd = m.rend(); it != itEnd; ++it ) {
331 CPPUNIT_ASSERT( it->first == it->second.nInsertCall * 1023 );
332 CPPUNIT_ASSERT(m.erase_at( it ));
334 CPPUNIT_ASSERT(!m.contains( it->first ));
336 CPPUNIT_ASSERT( nCount == capacity );
337 CPPUNIT_ASSERT( m.empty());
338 CPPUNIT_ASSERT(m.size() == 0 );
342 for ( size_t i = 0; i < capacity; ++i ) {
343 size_t key = i * 711;
344 CPPUNIT_ASSERT(!m.contains(key));
345 auto ret = m.update( key, [i]( value_type& v, value_type * old ) {
346 CPPUNIT_ASSERT_CURRENT( old == nullptr );
347 v.second.nInsertCall = (unsigned int) i;
349 CPPUNIT_ASSERT( ret.first );
350 CPPUNIT_ASSERT( ret.second );
351 CPPUNIT_ASSERT(m.find(key, [i, key] (value_type& v ) {
352 CPPUNIT_ASSERT_CURRENT( v.first == key );
353 CPPUNIT_ASSERT_CURRENT( v.second.nInsertCall == i );
355 CPPUNIT_ASSERT(m.size() == i + 1);
357 CPPUNIT_ASSERT( !m.empty());
358 CPPUNIT_ASSERT(m.size() == capacity);
360 for ( size_t i = capacity; i > 0; --i ) {
361 size_t key = (i-1) * 711;
362 guarded_ptr gp{ m.extract(key) };
363 CPPUNIT_ASSERT( gp );
364 CPPUNIT_ASSERT( gp->first == key );
365 CPPUNIT_ASSERT((*gp).second.nInsertCall == i - 1 );
367 CPPUNIT_ASSERT( !gp );
369 CPPUNIT_ASSERT( m.empty());
370 CPPUNIT_ASSERT(m.size() == 0 );
373 for ( size_t i = 0; i < capacity; ++i ) {
374 CPPUNIT_ASSERT(!m.contains( i ))
375 CPPUNIT_ASSERT(m.insert( i ));
376 CPPUNIT_ASSERT(m.contains( i ));
377 CPPUNIT_ASSERT(m.size() == i + 1);
379 CPPUNIT_ASSERT( !m.empty());
380 CPPUNIT_ASSERT(m.size() == capacity );
383 CPPUNIT_ASSERT( m.empty());
384 CPPUNIT_ASSERT(m.size() == 0 );
387 CPPUNIT_MSG( m.statistics() );
390 template <typename Map>
391 void test_rcu(size_t nHeadBits, size_t nArrayBits)
393 typedef typename Map::hash_type hash_type;
394 typedef typename Map::key_type key_type;
395 typedef typename Map::mapped_type mapped_type;
396 typedef typename Map::value_type value_type;
397 typedef typename Map::exempt_ptr exempt_ptr;
398 typedef typename Map::rcu_lock rcu_lock;
400 size_t const capacity = 1000;
402 Map m(nHeadBits, nArrayBits);
403 CPPUNIT_MSG("Array size: head=" << m.head_size() << ", array_node=" << m.array_node_size());
404 CPPUNIT_ASSERT(m.head_size() >= (size_t(1) << nHeadBits));
405 CPPUNIT_ASSERT(m.array_node_size() == (size_t(1) << nArrayBits));
407 CPPUNIT_ASSERT(m.empty());
408 CPPUNIT_ASSERT(m.size() == 0);
410 // insert( key )/update()/get()/find()
411 for (size_t i = 0; i < capacity; ++i) {
413 CPPUNIT_ASSERT(!m.contains(key))
414 CPPUNIT_ASSERT(m.insert(key));
415 CPPUNIT_ASSERT(m.contains(key));
416 CPPUNIT_ASSERT(m.size() == i + 1);
418 auto ret = m.update(key, [](value_type& v, value_type * old) {
419 CPPUNIT_ASSERT_CURRENT(old != nullptr);
420 ++v.second.nInsertCall;
422 CPPUNIT_ASSERT(ret.first);
423 CPPUNIT_ASSERT(!ret.second);
425 CPPUNIT_ASSERT(m.find(key, [](value_type& v) { ++v.second.nFindCall;}));
429 value_type* p{ m.get(key) };
431 CPPUNIT_ASSERT(p->first == key);
432 CPPUNIT_ASSERT(p->second.nInsertCall == 1);
433 CPPUNIT_ASSERT(p->second.nFindCall == 1);
436 CPPUNIT_ASSERT(!m.empty());
437 CPPUNIT_ASSERT(m.size() == capacity);
443 for (auto it = m.begin(), itEnd = m.end(); it != itEnd; ++it) {
444 CPPUNIT_ASSERT(it->second.nIteratorCall == 0);
445 CPPUNIT_ASSERT(it->second.nInsertCall == 1);
446 CPPUNIT_ASSERT((*it).second.nFindCall == 1);
447 it->second.nIteratorCall += 1;
451 CPPUNIT_ASSERT(nCount == capacity);
456 for (auto it = m.rbegin(), itEnd = m.rend(); it != itEnd; ++it) {
457 CPPUNIT_ASSERT(it->second.nInsertCall == 1);
458 CPPUNIT_ASSERT((*it).second.nFindCall == 1);
459 CPPUNIT_ASSERT(it->second.nIteratorCall == 1);
460 (*it).second.nIteratorCall += 1;
464 CPPUNIT_ASSERT(nCount == capacity);
469 for (auto it = m.cbegin(), itEnd = m.cend(); it != itEnd; ++it) {
470 CPPUNIT_ASSERT(it->second.nInsertCall == 1);
471 CPPUNIT_ASSERT((*it).second.nFindCall == 1);
472 CPPUNIT_ASSERT(it->second.nIteratorCall == 2);
473 (*it).second.nIteratorCall += 1;
477 CPPUNIT_ASSERT(nCount == capacity);
482 for (auto it = m.crbegin(), itEnd = m.crend(); it != itEnd; ++it) {
483 CPPUNIT_ASSERT(it->second.nInsertCall == 1);
484 CPPUNIT_ASSERT((*it).second.nFindCall == 1);
485 CPPUNIT_ASSERT(it->second.nIteratorCall == 3);
486 (*it).second.nIteratorCall += 1;
490 CPPUNIT_ASSERT(nCount == capacity);
493 for (size_t i = 0; i < capacity; i++) {
495 CPPUNIT_ASSERT(m.find(key, [key](value_type& v) {
496 CPPUNIT_ASSERT_CURRENT(v.first == key);
497 CPPUNIT_ASSERT_CURRENT(v.second.nInsertCall == 1);
498 CPPUNIT_ASSERT_CURRENT(v.second.nFindCall == 1);
499 CPPUNIT_ASSERT_CURRENT(v.second.nIteratorCall == 4);
504 for (size_t i = capacity; i > 0; --i) {
505 size_t key = (i - 1) * 57;
508 value_type* p = m.get(key);
510 CPPUNIT_ASSERT(p->first == key);
511 CPPUNIT_ASSERT(p->second.nInsertCall == 1);
512 CPPUNIT_ASSERT(p->second.nFindCall == 1);
513 CPPUNIT_ASSERT(p->second.nIteratorCall == 4);
516 CPPUNIT_ASSERT(m.erase(key));
520 value_type* p = m.get(key);
523 CPPUNIT_ASSERT(!m.contains(key));
525 CPPUNIT_ASSERT(m.empty());
526 CPPUNIT_ASSERT(m.size() == 0);
528 // Iterators on empty map
531 CPPUNIT_ASSERT(m.begin() == m.end());
532 CPPUNIT_ASSERT(m.cbegin() == m.cend());
533 CPPUNIT_ASSERT(m.rbegin() == m.rend());
534 CPPUNIT_ASSERT(m.crbegin() == m.crend());
537 // insert( key, val )
538 for (size_t i = 0; i < capacity; ++i) {
539 CPPUNIT_ASSERT(!m.contains(i));
540 CPPUNIT_ASSERT(m.insert(i, (unsigned int)i * 100));
541 CPPUNIT_ASSERT(m.contains(i));
542 CPPUNIT_ASSERT(m.find(i, [i](value_type& v) {
543 CPPUNIT_ASSERT_CURRENT(v.first == i);
544 CPPUNIT_ASSERT_CURRENT(v.second.nInsertCall == i * 100);
547 CPPUNIT_ASSERT(!m.empty());
548 CPPUNIT_ASSERT(m.size() == capacity);
550 // erase( key, func )
551 for (size_t i = 0; i < capacity; ++i) {
552 CPPUNIT_ASSERT(m.contains(i));
553 CPPUNIT_ASSERT(m.erase(i, [i](value_type& v) {
554 CPPUNIT_ASSERT_CURRENT(v.first == i);
555 CPPUNIT_ASSERT_CURRENT(v.second.nInsertCall == i * 100);
556 v.second.nInsertCall = 0;
559 CPPUNIT_ASSERT(m.empty());
560 CPPUNIT_ASSERT(m.size() == 0);
563 for (size_t i = 0; i < capacity; ++i) {
564 size_t key = i * 121;
565 CPPUNIT_ASSERT(!m.contains(key));
566 CPPUNIT_ASSERT(m.insert_with(key, [key](value_type& v) {
567 CPPUNIT_ASSERT_CURRENT(v.first == key);
568 CPPUNIT_ASSERT_CURRENT(v.second.nInsertCall == 0);
569 v.second.nInsertCall = decltype(v.second.nInsertCall)(key);
571 CPPUNIT_ASSERT(m.find(key, [key](value_type& v) {
572 CPPUNIT_ASSERT_CURRENT(v.first == key);
573 CPPUNIT_ASSERT_CURRENT(v.second.nInsertCall == key);
575 CPPUNIT_ASSERT(m.size() == i + 1);
577 CPPUNIT_ASSERT(!m.empty());
578 CPPUNIT_ASSERT(m.size() == capacity);
583 for (auto it = m.begin(), itEnd = m.end(); it != itEnd; ++it) {
584 CPPUNIT_ASSERT(it->first == it->second.nInsertCall);
585 CPPUNIT_ASSERT(it->second.nIteratorCall == 0);
586 it->second.nIteratorCall += 1;
590 CPPUNIT_ASSERT(nCount == capacity);
595 for (auto it = m.rbegin(), itEnd = m.rend(); it != itEnd; ++it) {
596 CPPUNIT_ASSERT(it->first == it->second.nInsertCall);
597 CPPUNIT_ASSERT(it->second.nIteratorCall == 1);
598 it->second.nIteratorCall += 1;
602 CPPUNIT_ASSERT(nCount == capacity);
606 CPPUNIT_ASSERT(m.empty());
607 CPPUNIT_ASSERT(m.size() == 0);
610 for (size_t i = 0; i < capacity; ++i) {
611 size_t key = i * 1023;
612 CPPUNIT_ASSERT(!m.contains(key));
613 CPPUNIT_ASSERT(m.emplace(key, static_cast<unsigned int>(i)));
614 CPPUNIT_ASSERT(m.find(key, [key](value_type& v) {
615 CPPUNIT_ASSERT_CURRENT(v.first == key);
616 CPPUNIT_ASSERT_CURRENT(v.second.nInsertCall * 1023 == key);
618 CPPUNIT_ASSERT(m.size() == i + 1);
620 CPPUNIT_ASSERT(!m.empty());
621 CPPUNIT_ASSERT(m.size() == capacity);
624 for (size_t i = capacity; i > 0; --i) {
625 size_t key = (i - 1) * 1023;
626 exempt_ptr xp{ m.extract(key) };
628 CPPUNIT_ASSERT(xp->first == key);
629 CPPUNIT_ASSERT((*xp).second.nInsertCall == static_cast<unsigned int>(i - 1));
633 CPPUNIT_ASSERT(m.empty());
634 CPPUNIT_ASSERT(m.size() == 0);
636 CPPUNIT_MSG(m.statistics());
640 void hp_nohash_stat();
641 void hp_nohash_5_3();
642 void hp_nohash_5_3_stat();
644 void hp_stdhash_stat();
645 void hp_stdhash_5_3();
646 void hp_stdhash_5_3_stat();
648 void hp_hash128_stat();
649 void hp_hash128_4_3();
650 void hp_hash128_4_3_stat();
653 void dhp_nohash_stat();
654 void dhp_nohash_5_3();
655 void dhp_nohash_5_3_stat();
657 void dhp_stdhash_stat();
658 void dhp_stdhash_5_3();
659 void dhp_stdhash_5_3_stat();
661 void dhp_hash128_stat();
662 void dhp_hash128_4_3();
663 void dhp_hash128_4_3_stat();
665 void rcu_gpb_nohash();
666 void rcu_gpb_nohash_stat();
667 void rcu_gpb_nohash_5_3();
668 void rcu_gpb_nohash_5_3_stat();
669 void rcu_gpb_stdhash();
670 void rcu_gpb_stdhash_stat();
671 void rcu_gpb_stdhash_5_3();
672 void rcu_gpb_stdhash_5_3_stat();
673 void rcu_gpb_hash128();
674 void rcu_gpb_hash128_stat();
675 void rcu_gpb_hash128_4_3();
676 void rcu_gpb_hash128_4_3_stat();
678 void rcu_gpi_nohash();
679 void rcu_gpi_nohash_stat();
680 void rcu_gpi_nohash_5_3();
681 void rcu_gpi_nohash_5_3_stat();
682 void rcu_gpi_stdhash();
683 void rcu_gpi_stdhash_stat();
684 void rcu_gpi_stdhash_5_3();
685 void rcu_gpi_stdhash_5_3_stat();
686 void rcu_gpi_hash128();
687 void rcu_gpi_hash128_stat();
688 void rcu_gpi_hash128_4_3();
689 void rcu_gpi_hash128_4_3_stat();
691 void rcu_gpt_nohash();
692 void rcu_gpt_nohash_stat();
693 void rcu_gpt_nohash_5_3();
694 void rcu_gpt_nohash_5_3_stat();
695 void rcu_gpt_stdhash();
696 void rcu_gpt_stdhash_stat();
697 void rcu_gpt_stdhash_5_3();
698 void rcu_gpt_stdhash_5_3_stat();
699 void rcu_gpt_hash128();
700 void rcu_gpt_hash128_stat();
701 void rcu_gpt_hash128_4_3();
702 void rcu_gpt_hash128_4_3_stat();
704 void rcu_shb_nohash();
705 void rcu_shb_nohash_stat();
706 void rcu_shb_nohash_5_3();
707 void rcu_shb_nohash_5_3_stat();
708 void rcu_shb_stdhash();
709 void rcu_shb_stdhash_stat();
710 void rcu_shb_stdhash_5_3();
711 void rcu_shb_stdhash_5_3_stat();
712 void rcu_shb_hash128();
713 void rcu_shb_hash128_stat();
714 void rcu_shb_hash128_4_3();
715 void rcu_shb_hash128_4_3_stat();
717 void rcu_sht_nohash();
718 void rcu_sht_nohash_stat();
719 void rcu_sht_nohash_5_3();
720 void rcu_sht_nohash_5_3_stat();
721 void rcu_sht_stdhash();
722 void rcu_sht_stdhash_stat();
723 void rcu_sht_stdhash_5_3();
724 void rcu_sht_stdhash_5_3_stat();
725 void rcu_sht_hash128();
726 void rcu_sht_hash128_stat();
727 void rcu_sht_hash128_4_3();
728 void rcu_sht_hash128_4_3_stat();
730 CPPUNIT_TEST_SUITE(FeldmanHashMapHdrTest)
731 CPPUNIT_TEST(hp_nohash)
732 CPPUNIT_TEST(hp_nohash_stat)
733 CPPUNIT_TEST(hp_nohash_5_3)
734 CPPUNIT_TEST(hp_nohash_5_3_stat)
735 CPPUNIT_TEST(hp_stdhash)
736 CPPUNIT_TEST(hp_stdhash_stat)
737 CPPUNIT_TEST(hp_stdhash_5_3)
738 CPPUNIT_TEST(hp_stdhash_5_3_stat)
739 CPPUNIT_TEST(hp_hash128)
740 CPPUNIT_TEST(hp_hash128_stat)
741 CPPUNIT_TEST(hp_hash128_4_3)
742 CPPUNIT_TEST(hp_hash128_4_3_stat)
744 CPPUNIT_TEST(dhp_nohash)
745 CPPUNIT_TEST(dhp_nohash_stat)
746 CPPUNIT_TEST(dhp_nohash_5_3)
747 CPPUNIT_TEST(dhp_nohash_5_3_stat)
748 CPPUNIT_TEST(dhp_stdhash)
749 CPPUNIT_TEST(dhp_stdhash_stat)
750 CPPUNIT_TEST(dhp_stdhash_5_3)
751 CPPUNIT_TEST(dhp_stdhash_5_3_stat)
752 CPPUNIT_TEST(dhp_hash128)
753 CPPUNIT_TEST(dhp_hash128_stat)
754 CPPUNIT_TEST(dhp_hash128_4_3)
755 CPPUNIT_TEST(dhp_hash128_4_3_stat)
757 CPPUNIT_TEST(rcu_gpb_nohash)
758 CPPUNIT_TEST(rcu_gpb_nohash_stat)
759 CPPUNIT_TEST(rcu_gpb_nohash_5_3)
760 CPPUNIT_TEST(rcu_gpb_nohash_5_3_stat)
761 CPPUNIT_TEST(rcu_gpb_stdhash)
762 CPPUNIT_TEST(rcu_gpb_stdhash_stat)
763 CPPUNIT_TEST(rcu_gpb_stdhash_5_3)
764 CPPUNIT_TEST(rcu_gpb_stdhash_5_3_stat)
765 CPPUNIT_TEST(rcu_gpb_hash128)
766 CPPUNIT_TEST(rcu_gpb_hash128_stat)
767 CPPUNIT_TEST(rcu_gpb_hash128_4_3)
768 CPPUNIT_TEST(rcu_gpb_hash128_4_3_stat)
770 CPPUNIT_TEST(rcu_gpi_nohash)
771 CPPUNIT_TEST(rcu_gpi_nohash_stat)
772 CPPUNIT_TEST(rcu_gpi_nohash_5_3)
773 CPPUNIT_TEST(rcu_gpi_nohash_5_3_stat)
774 CPPUNIT_TEST(rcu_gpi_stdhash)
775 CPPUNIT_TEST(rcu_gpi_stdhash_stat)
776 CPPUNIT_TEST(rcu_gpi_stdhash_5_3)
777 CPPUNIT_TEST(rcu_gpi_stdhash_5_3_stat)
778 CPPUNIT_TEST(rcu_gpi_hash128)
779 CPPUNIT_TEST(rcu_gpi_hash128_stat)
780 CPPUNIT_TEST(rcu_gpi_hash128_4_3)
781 CPPUNIT_TEST(rcu_gpi_hash128_4_3_stat)
783 CPPUNIT_TEST(rcu_gpt_nohash)
784 CPPUNIT_TEST(rcu_gpt_nohash_stat)
785 CPPUNIT_TEST(rcu_gpt_nohash_5_3)
786 CPPUNIT_TEST(rcu_gpt_nohash_5_3_stat)
787 CPPUNIT_TEST(rcu_gpt_stdhash)
788 CPPUNIT_TEST(rcu_gpt_stdhash_stat)
789 CPPUNIT_TEST(rcu_gpt_stdhash_5_3)
790 CPPUNIT_TEST(rcu_gpt_stdhash_5_3_stat)
791 CPPUNIT_TEST(rcu_gpt_hash128)
792 CPPUNIT_TEST(rcu_gpt_hash128_stat)
793 CPPUNIT_TEST(rcu_gpt_hash128_4_3)
794 CPPUNIT_TEST(rcu_gpt_hash128_4_3_stat)
796 CPPUNIT_TEST(rcu_shb_nohash)
797 CPPUNIT_TEST(rcu_shb_nohash_stat)
798 CPPUNIT_TEST(rcu_shb_nohash_5_3)
799 CPPUNIT_TEST(rcu_shb_nohash_5_3_stat)
800 CPPUNIT_TEST(rcu_shb_stdhash)
801 CPPUNIT_TEST(rcu_shb_stdhash_stat)
802 CPPUNIT_TEST(rcu_shb_stdhash_5_3)
803 CPPUNIT_TEST(rcu_shb_stdhash_5_3_stat)
804 CPPUNIT_TEST(rcu_shb_hash128)
805 CPPUNIT_TEST(rcu_shb_hash128_stat)
806 CPPUNIT_TEST(rcu_shb_hash128_4_3)
807 CPPUNIT_TEST(rcu_shb_hash128_4_3_stat)
809 CPPUNIT_TEST(rcu_sht_nohash)
810 CPPUNIT_TEST(rcu_sht_nohash_stat)
811 CPPUNIT_TEST(rcu_sht_nohash_5_3)
812 CPPUNIT_TEST(rcu_sht_nohash_5_3_stat)
813 CPPUNIT_TEST(rcu_sht_stdhash)
814 CPPUNIT_TEST(rcu_sht_stdhash_stat)
815 CPPUNIT_TEST(rcu_sht_stdhash_5_3)
816 CPPUNIT_TEST(rcu_sht_stdhash_5_3_stat)
817 CPPUNIT_TEST(rcu_sht_hash128)
818 CPPUNIT_TEST(rcu_sht_hash128_stat)
819 CPPUNIT_TEST(rcu_sht_hash128_4_3)
820 CPPUNIT_TEST(rcu_sht_hash128_4_3_stat)
821 CPPUNIT_TEST_SUITE_END()
827 #endif //#ifndef CDSTEST_HDR_FELDMAN_HASHMAP_H