Improved map unit test
[libcds.git] / tests / unit / map2 / map_delodd.h
1 //$$CDS-header$$
2
3 #include "cppunit/thread.h"
4 #include "map2/map_types.h"
5 #include <algorithm> // random_shuffle
6
7 namespace map2 {
8
9 #   define TEST_MAP(X)         void X() { test<MapTypes<key_type, value_type>::X >(); }
10 #   define TEST_MAP_EXTRACT(X) void X() { test_extract<MapTypes<key_type, value_type>::X >(); }
11 #   define TEST_MAP_NOLF(X)    void X() { test_nolf<MapTypes<key_type, value_type>::X >(); }
12 #   define TEST_MAP_NOLF_EXTRACT(X) void X() { test_nolf_extract<MapTypes<key_type, value_type>::X >(); }
13
14     namespace {
15         struct key_thread
16         {
17             size_t  nKey;
18             size_t  nThread;
19
20             key_thread( size_t key, size_t threadNo )
21                 : nKey( key )
22                 , nThread( threadNo )
23             {}
24
25             key_thread()
26             {}
27         };
28
29         //typedef MapTypes<key_thread, size_t>::key_val     key_value_pair;
30     }
31
32     template <>
33     struct cmp<key_thread> {
34         int operator ()(key_thread const& k1, key_thread const& k2) const
35         {
36             if ( k1.nKey < k2.nKey )
37                 return -1;
38             if ( k1.nKey > k2.nKey )
39                 return 1;
40             if ( k1.nThread < k2.nThread )
41                 return -1;
42             if ( k1.nThread > k2.nThread )
43                 return 1;
44             return 0;
45         }
46         int operator ()(key_thread const& k1, size_t k2) const
47         {
48             if ( k1.nKey < k2 )
49                 return -1;
50             if ( k1.nKey > k2 )
51                 return 1;
52             return 0;
53         }
54         int operator ()(size_t k1, key_thread const& k2) const
55         {
56             if ( k1 < k2.nKey )
57                 return -1;
58             if ( k1 > k2.nKey )
59                 return 1;
60             return 0;
61         }
62     };
63
64 } // namespace map2
65
66 namespace std {
67     template <>
68     struct less<map2::key_thread>
69     {
70         bool operator()(map2::key_thread const& k1, map2::key_thread const& k2) const
71         {
72             if ( k1.nKey <= k2.nKey )
73                 return k1.nKey < k2.nKey || k1.nThread < k2.nThread;
74             return false;
75         }
76     };
77
78     template <>
79     struct hash<map2::key_thread>
80     {
81         typedef size_t              result_type;
82         typedef map2::key_thread    argument_type;
83
84         size_t operator()( map2::key_thread const& k ) const
85         {
86             return std::hash<size_t>()(k.nKey);
87         }
88         size_t operator()( size_t k ) const
89         {
90             return std::hash<size_t>()(k);
91         }
92     };
93 } // namespace std
94
95 namespace boost {
96     inline size_t hash_value( map2::key_thread const& k )
97     {
98         return std::hash<size_t>()( k.nKey );
99     }
100
101     template <>
102     struct hash<map2::key_thread>
103     {
104         typedef size_t              result_type;
105         typedef map2::key_thread    argument_type;
106
107         size_t operator()(map2::key_thread const& k) const
108         {
109             return boost::hash<size_t>()( k.nKey );
110         }
111         size_t operator()(size_t k) const
112         {
113             return boost::hash<size_t>()( k );
114         }
115     };
116 } // namespace boost
117
118 namespace map2 {
119
120     class Map_DelOdd: public CppUnitMini::TestCase
121     {
122         static size_t  c_nMapSize;          // max map size
123         static size_t  c_nInsThreadCount;   // insert thread count
124         static size_t  c_nDelThreadCount;   // delete thread count
125         static size_t  c_nExtractThreadCount;  // extract thread count
126         static size_t  c_nMaxLoadFactor;    // maximum load factor
127         static bool    c_bPrintGCState;
128
129         std::vector<size_t>     m_arrData;
130
131     protected:
132         typedef CppUnitMini::TestCase Base;
133
134         typedef key_thread  key_type;
135         typedef size_t      value_type;
136         typedef std::pair<key_type const, value_type> pair_type;
137
138         atomics::atomic<size_t>      m_nInsThreadCount;
139
140         // Inserts keys from [0..N)
141         template <class Map>
142         class InsertThread: public CppUnitMini::TestThread
143         {
144             Map&     m_Map;
145
146             virtual InsertThread *    clone()
147             {
148                 return new InsertThread( *this );
149             }
150
151             struct ensure_func
152             {
153                 template <typename Q>
154                 void operator()( bool /*bNew*/, Q const& )
155                 {}
156                 template <typename Q, typename V>
157                 void operator()( bool /*bNew*/, Q const&, V& )
158                 {}
159             };
160         public:
161             size_t  m_nInsertSuccess;
162             size_t  m_nInsertFailed;
163
164         public:
165             InsertThread( CppUnitMini::ThreadPool& pool, Map& rMap )
166                 : CppUnitMini::TestThread( pool )
167                 , m_Map( rMap )
168             {}
169             InsertThread( InsertThread& src )
170                 : CppUnitMini::TestThread( src )
171                 , m_Map( src.m_Map )
172             {}
173
174             Map_DelOdd&  getTest()
175             {
176                 return reinterpret_cast<Map_DelOdd&>( m_Pool.m_Test );
177             }
178
179             virtual void init() { cds::threading::Manager::attachThread()   ; }
180             virtual void fini() { cds::threading::Manager::detachThread()   ; }
181
182             virtual void test()
183             {
184                 Map& rMap = m_Map;
185
186                 m_nInsertSuccess =
187                     m_nInsertFailed = 0;
188
189                 std::vector<size_t>& arrData = getTest().m_arrData;
190                 for ( size_t i = 0; i < arrData.size(); ++i ) {
191                     if ( rMap.insert( key_type( arrData[i], m_nThreadNo )))
192                         ++m_nInsertSuccess;
193                     else
194                         ++m_nInsertFailed;
195                 }
196
197                 ensure_func f;
198                 for ( size_t i = arrData.size() - 1; i > 0; --i ) {
199                     if ( arrData[i] & 1 ) {
200                         rMap.ensure( key_type( arrData[i], m_nThreadNo ), f );
201                     }
202                 }
203
204                 getTest().m_nInsThreadCount.fetch_sub( 1, atomics::memory_order_acquire );
205             }
206         };
207
208         struct key_equal {
209             bool operator()( key_type const& k1, key_type const& k2 ) const
210             {
211                 return k1.nKey == k2.nKey;
212             }
213             bool operator()( size_t k1, key_type const& k2 ) const
214             {
215                 return k1 == k2.nKey;
216             }
217             bool operator()( key_type const& k1, size_t k2 ) const
218             {
219                 return k1.nKey == k2;
220             }
221         };
222
223         struct key_less {
224             bool operator()( key_type const& k1, key_type const& k2 ) const
225             {
226                 return k1.nKey < k2.nKey;
227             }
228             bool operator()( size_t k1, key_type const& k2 ) const
229             {
230                 return k1 < k2.nKey;
231             }
232             bool operator()( key_type const& k1, size_t k2 ) const
233             {
234                 return k1.nKey < k2;
235             }
236
237             typedef key_equal equal_to;
238         };
239
240         // Deletes odd keys from [0..N)
241         template <class Map>
242         class DeleteThread: public CppUnitMini::TestThread
243         {
244             Map&     m_Map;
245
246             virtual DeleteThread *    clone()
247             {
248                 return new DeleteThread( *this );
249             }
250         public:
251             size_t  m_nDeleteSuccess;
252             size_t  m_nDeleteFailed;
253
254         public:
255             DeleteThread( CppUnitMini::ThreadPool& pool, Map& rMap )
256                 : CppUnitMini::TestThread( pool )
257                 , m_Map( rMap )
258             {}
259             DeleteThread( DeleteThread& src )
260                 : CppUnitMini::TestThread( src )
261                 , m_Map( src.m_Map )
262             {}
263
264             Map_DelOdd&  getTest()
265             {
266                 return reinterpret_cast<Map_DelOdd&>( m_Pool.m_Test );
267             }
268
269             virtual void init() { cds::threading::Manager::attachThread()   ; }
270             virtual void fini() { cds::threading::Manager::detachThread()   ; }
271
272             virtual void test()
273             {
274                 Map& rMap = m_Map;
275
276                 m_nDeleteSuccess =
277                     m_nDeleteFailed = 0;
278
279                 for ( size_t pass = 0; pass < 2; pass++ ) {
280                     std::vector<size_t>& arrData = getTest().m_arrData;
281                     if ( m_nThreadNo & 1 ) {
282                         for ( size_t k = 0; k < c_nInsThreadCount; ++k ) {
283                             for ( size_t i = 0; i < arrData.size(); ++i ) {
284                                 if ( arrData[i] & 1 ) {
285                                     if ( rMap.erase_with( arrData[i], key_less() ))
286                                         ++m_nDeleteSuccess;
287                                     else
288                                         ++m_nDeleteFailed;
289                                 }
290                             }
291                             if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
292                                 break;
293                         }
294                     }
295                     else {
296                         for ( size_t k = 0; k < c_nInsThreadCount; ++k ) {
297                             for ( size_t i = arrData.size() - 1; i > 0; --i ) {
298                                 if ( arrData[i] & 1 ) {
299                                     if ( rMap.erase_with( arrData[i], key_less() ))
300                                         ++m_nDeleteSuccess;
301                                     else
302                                         ++m_nDeleteFailed;
303                                 }
304                             }
305                             if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
306                                 break;
307                         }
308                     }
309                 }
310             }
311         };
312
313         // Deletes odd keys from [0..N)
314         template <class GC, class Map >
315         class ExtractThread: public CppUnitMini::TestThread
316         {
317             Map&     m_Map;
318
319             virtual ExtractThread *    clone()
320             {
321                 return new ExtractThread( *this );
322             }
323         public:
324             size_t  m_nDeleteSuccess;
325             size_t  m_nDeleteFailed;
326
327         public:
328             ExtractThread( CppUnitMini::ThreadPool& pool, Map& rMap )
329                 : CppUnitMini::TestThread( pool )
330                 , m_Map( rMap )
331             {}
332             ExtractThread( ExtractThread& src )
333                 : CppUnitMini::TestThread( src )
334                 , m_Map( src.m_Map )
335             {}
336
337             Map_DelOdd&  getTest()
338             {
339                 return reinterpret_cast<Map_DelOdd&>( m_Pool.m_Test );
340             }
341
342             virtual void init() { cds::threading::Manager::attachThread()   ; }
343             virtual void fini() { cds::threading::Manager::detachThread()   ; }
344
345             virtual void test()
346             {
347                 Map& rMap = m_Map;
348
349                 m_nDeleteSuccess =
350                     m_nDeleteFailed = 0;
351
352                 typename Map::guarded_ptr gp;
353
354                 for ( size_t pass = 0; pass < 2; ++pass ) {
355                     std::vector<size_t>& arrData = getTest().m_arrData;
356                     if ( m_nThreadNo & 1 ) {
357                         for ( size_t k = 0; k < c_nInsThreadCount; ++k ) {
358                             for ( size_t i = 0; i < arrData.size(); ++i ) {
359                                 if ( arrData[i] & 1 ) {
360                                     gp = rMap.extract_with( arrData[i], key_less());
361                                     if ( gp )
362                                         ++m_nDeleteSuccess;
363                                     else
364                                         ++m_nDeleteFailed;
365                                     gp.release();
366                                 }
367                             }
368                             if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
369                                 break;
370                         }
371                     }
372                     else {
373                         for ( size_t k = 0; k < c_nInsThreadCount; ++k ) {
374                             for ( size_t i = arrData.size() - 1; i > 0; --i ) {
375                                 if ( arrData[i] & 1 ) {
376                                     gp = rMap.extract_with( arrData[i], key_less());
377                                     if ( gp )
378                                         ++m_nDeleteSuccess;
379                                     else
380                                         ++m_nDeleteFailed;
381                                     gp.release();
382                                 }
383                             }
384                             if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
385                                 break;
386                         }
387                     }
388                 }
389             }
390         };
391
392         template <class RCU, class Map >
393         class ExtractThread< cds::urcu::gc<RCU>, Map > : public CppUnitMini::TestThread
394         {
395             Map&     m_Map;
396
397             virtual ExtractThread *    clone()
398             {
399                 return new ExtractThread( *this );
400             }
401         public:
402             size_t  m_nDeleteSuccess;
403             size_t  m_nDeleteFailed;
404
405         public:
406             ExtractThread( CppUnitMini::ThreadPool& pool, Map& rMap )
407                 : CppUnitMini::TestThread( pool )
408                 , m_Map( rMap )
409             {}
410             ExtractThread( ExtractThread& src )
411                 : CppUnitMini::TestThread( src )
412                 , m_Map( src.m_Map )
413             {}
414
415             Map_DelOdd&  getTest()
416             {
417                 return reinterpret_cast<Map_DelOdd&>( m_Pool.m_Test );
418             }
419
420             virtual void init() { cds::threading::Manager::attachThread()   ; }
421             virtual void fini() { cds::threading::Manager::detachThread()   ; }
422
423             virtual void test()
424             {
425                 Map& rMap = m_Map;
426
427                 m_nDeleteSuccess =
428                     m_nDeleteFailed = 0;
429
430                 typename Map::exempt_ptr xp;
431
432                 std::vector<size_t>& arrData = getTest().m_arrData;
433                 if ( m_nThreadNo & 1 ) {
434                     for ( size_t k = 0; k < c_nInsThreadCount; ++k ) {
435                         for ( size_t i = 0; i < arrData.size(); ++i ) {
436                             if ( arrData[i] & 1 ) {
437                                 if ( Map::c_bExtractLockExternal ) {
438                                     {
439                                         typename Map::rcu_lock l;
440                                         xp = rMap.extract_with( arrData[i], key_less() );
441                                         if ( xp )
442                                             ++m_nDeleteSuccess;
443                                         else
444                                             ++m_nDeleteFailed;
445                                     }
446                                 }
447                                 else {
448                                     xp = rMap.extract_with( arrData[i], key_less() );
449                                     if ( xp )
450                                         ++m_nDeleteSuccess;
451                                     else
452                                         ++m_nDeleteFailed;
453                                 }
454                                 xp.release();
455                             }
456                         }
457                         if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
458                             break;
459                     }
460                 }
461                 else {
462                     for ( size_t k = 0; k < c_nInsThreadCount; ++k ) {
463                         for ( size_t i = arrData.size() - 1; i > 0; --i ) {
464                             if ( arrData[i] & 1 ) {
465                                 if ( Map::c_bExtractLockExternal ) {
466                                     {
467                                         typename Map::rcu_lock l;
468                                         xp = rMap.extract_with( arrData[i], key_less() );
469                                         if ( xp )
470                                             ++m_nDeleteSuccess;
471                                         else
472                                             ++m_nDeleteFailed;
473                                     }
474                                 }
475                                 else {
476                                     xp = rMap.extract_with( arrData[i], key_less() );
477                                     if ( xp )
478                                         ++m_nDeleteSuccess;
479                                     else
480                                         ++m_nDeleteFailed;
481                                 }
482                                 xp.release();
483                             }
484                         }
485                         if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
486                             break;
487                     }
488                 }
489             }
490         };
491
492     protected:
493         template <class Map>
494         void do_test( size_t nLoadFactor )
495         {
496             Map  testMap( c_nMapSize, nLoadFactor );
497             do_test_with( testMap );
498         }
499
500         template <class Map>
501         void do_test_extract( size_t nLoadFactor )
502         {
503             Map  testMap( c_nMapSize, nLoadFactor );
504             do_test_extract_with( testMap );
505         }
506
507         template <class Map>
508         void do_test_with( Map& testMap )
509         {
510             typedef InsertThread<Map> insert_thread;
511             typedef DeleteThread<Map> delete_thread;
512
513             m_nInsThreadCount.store( c_nInsThreadCount, atomics::memory_order_release );
514
515             CppUnitMini::ThreadPool pool( *this );
516             pool.add( new insert_thread( pool, testMap ), c_nInsThreadCount );
517             pool.add( new delete_thread( pool, testMap ), c_nDelThreadCount ? c_nDelThreadCount : cds::OS::topology::processor_count());
518             pool.run();
519             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
520
521             size_t nInsertSuccess = 0;
522             size_t nInsertFailed = 0;
523             size_t nDeleteSuccess = 0;
524             size_t nDeleteFailed = 0;
525             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
526                 insert_thread * pThread = dynamic_cast<insert_thread *>( *it );
527                 if ( pThread ) {
528                     nInsertSuccess += pThread->m_nInsertSuccess;
529                     nInsertFailed += pThread->m_nInsertFailed;
530                 }
531                 else {
532                     delete_thread * p = static_cast<delete_thread *>( *it );
533                     nDeleteSuccess += p->m_nDeleteSuccess;
534                     nDeleteFailed += p->m_nDeleteFailed;
535                 }
536             }
537
538             CPPUNIT_MSG( "  Totals (success/failed): \n\t"
539                 << "      Insert=" << nInsertSuccess << '/' << nInsertFailed << "\n\t"
540                 << "      Delete=" << nDeleteSuccess << '/' << nDeleteFailed << "\n\t"
541                 );
542             CPPUNIT_CHECK( nInsertSuccess == c_nMapSize * c_nInsThreadCount );
543             CPPUNIT_CHECK( nInsertFailed == 0 );
544
545             analyze( testMap );
546         }
547
548         template <class Map>
549         void do_test_extract_with( Map& testMap )
550         {
551             typedef InsertThread<Map> insert_thread;
552             typedef DeleteThread<Map> delete_thread;
553             typedef ExtractThread< typename Map::gc, Map > extract_thread;
554
555             m_nInsThreadCount.store( c_nInsThreadCount, atomics::memory_order_release );
556
557             CppUnitMini::ThreadPool pool( *this );
558             pool.add( new insert_thread( pool, testMap ), c_nInsThreadCount );
559             if ( c_nDelThreadCount )
560                 pool.add( new delete_thread( pool, testMap ), c_nDelThreadCount );
561             if ( c_nExtractThreadCount )
562                 pool.add( new extract_thread( pool, testMap ), c_nExtractThreadCount );
563             pool.run();
564             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
565
566             size_t nInsertSuccess = 0;
567             size_t nInsertFailed = 0;
568             size_t nDeleteSuccess = 0;
569             size_t nDeleteFailed = 0;
570             size_t nExtractSuccess = 0;
571             size_t nExtractFailed = 0;
572             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
573                 insert_thread * pThread = dynamic_cast<insert_thread *>( *it );
574                 if ( pThread ) {
575                     nInsertSuccess += pThread->m_nInsertSuccess;
576                     nInsertFailed += pThread->m_nInsertFailed;
577                 }
578                 else {
579                     delete_thread * p = dynamic_cast<delete_thread *>( *it );
580                     if ( p ) {
581                         nDeleteSuccess += p->m_nDeleteSuccess;
582                         nDeleteFailed += p->m_nDeleteFailed;
583                     }
584                     else {
585                         extract_thread * pExtract = dynamic_cast<extract_thread *>( *it );
586                         assert( pExtract );
587                         nExtractSuccess += pExtract->m_nDeleteSuccess;
588                         nExtractFailed += pExtract->m_nDeleteFailed;
589                     }
590                 }
591             }
592
593             CPPUNIT_MSG( "  Totals (success/failed): \n\t"
594                 << "      Insert=" << nInsertSuccess << '/' << nInsertFailed << "\n\t"
595                 << "      Delete=" << nDeleteSuccess << '/' << nDeleteFailed << "\n\t"
596                 << "      Extract=" << nExtractSuccess << '/' << nExtractFailed << "\n\t"
597                 );
598             CPPUNIT_CHECK( nInsertSuccess == c_nMapSize * c_nInsThreadCount );
599             CPPUNIT_CHECK( nInsertFailed == 0 );
600
601             analyze( testMap );
602         }
603
604         template <class Map>
605         void analyze( Map& testMap )
606         {
607             cds::OS::Timer    timer;
608
609             // All even keys must be in the map
610             {
611                 size_t nErrorCount = 0;
612                 CPPUNIT_MSG( "  Check even keys..." );
613                 for ( size_t n = 0; n < c_nMapSize; n +=2 ) {
614                     for ( size_t i = 0; i < c_nInsThreadCount; ++i ) {
615                         if ( !testMap.find( key_type(n, i) ) ) {
616                             if ( ++nErrorCount < 10 ) {
617                                 CPPUNIT_MSG( "key " << n << "-" << i << " is not found!");
618                             }
619                         }
620                     }
621                 }
622                 CPPUNIT_CHECK_EX( nErrorCount == 0, "Totals: " << nErrorCount << " keys is not found");
623             }
624
625             check_before_cleanup( testMap );
626
627             CPPUNIT_MSG( "  Clear map (single-threaded)..." );
628             timer.reset();
629             testMap.clear();
630             CPPUNIT_MSG( "   Duration=" << timer.duration() );
631             CPPUNIT_CHECK_EX( testMap.empty(), ((long long) testMap.size()) );
632
633             additional_check( testMap );
634             print_stat( testMap );
635
636             additional_cleanup( testMap );
637         }
638
639
640         template <class Map>
641         void test()
642         {
643             CPPUNIT_MSG( "Insert thread count=" << c_nInsThreadCount
644                 << " delete thread count=" << c_nDelThreadCount
645                 << " set size=" << c_nMapSize
646                 );
647
648             for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
649                 CPPUNIT_MSG( "Load factor=" << nLoadFactor );
650                 do_test<Map>( nLoadFactor );
651                 if ( c_bPrintGCState )
652                     print_gc_state();
653             }
654         }
655
656         template <class Map>
657         void test_extract()
658         {
659             CPPUNIT_MSG( "Thread count: insert=" << c_nInsThreadCount
660                 << ", delete=" << c_nDelThreadCount
661                 << ", extract=" << c_nExtractThreadCount
662                 << "; set size=" << c_nMapSize
663                 );
664
665             for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
666                 CPPUNIT_MSG( "Load factor=" << nLoadFactor );
667                 do_test_extract<Map>( nLoadFactor );
668                 if ( c_bPrintGCState )
669                     print_gc_state();
670             }
671         }
672
673         template <class Map>
674         void test_nolf()
675         {
676             CPPUNIT_MSG( "Insert thread count=" << c_nInsThreadCount
677                 << " delete thread count=" << c_nDelThreadCount
678                 << " set size=" << c_nMapSize
679                 );
680
681             Map s;
682             do_test_with( s );
683             if ( c_bPrintGCState )
684                 print_gc_state();
685         }
686
687         template <class Map>
688         void test_nolf_extract()
689         {
690             CPPUNIT_MSG( "Thread count: insert=" << c_nInsThreadCount
691                 << ", delete=" << c_nDelThreadCount
692                 << ", extract=" << c_nExtractThreadCount
693                 << "; set size=" << c_nMapSize
694                 );
695
696             Map s;
697             do_test_extract_with( s );
698             if ( c_bPrintGCState )
699                 print_gc_state();
700         }
701
702         void setUpParams( const CppUnitMini::TestCfg& cfg );
703
704         void run_MichaelMap(const char *in_name, bool invert = false);
705         void run_SplitList(const char *in_name, bool invert = false);
706         //void run_StripedMap(const char *in_name, bool invert = false);
707         //void run_RefinableMap(const char *in_name, bool invert = false);
708         void run_CuckooMap(const char *in_name, bool invert = false);
709         void run_SkipListMap(const char *in_name, bool invert = false);
710         void run_EllenBinTreeMap(const char *in_name, bool invert = false);
711         void run_BronsonAVLTreeMap(const char *in_name, bool invert = false);
712         //void run_StdMap(const char *in_name, bool invert = false);
713
714         virtual void myRun(const char *in_name, bool invert = false);
715
716 #   include "map2/map_defs.h"
717         CDSUNIT_DECLARE_MichaelMap
718         CDSUNIT_DECLARE_SplitList
719         //CDSUNIT_DECLARE_StripedMap
720         //CDSUNIT_DECLARE_RefinableMap
721         CDSUNIT_DECLARE_CuckooMap
722         CDSUNIT_DECLARE_SkipListMap
723         CDSUNIT_DECLARE_EllenBinTreeMap
724         CDSUNIT_DECLARE_BronsonAVLTreeMap
725         //CDSUNIT_DECLARE_StdMap
726     };
727 } // namespace map2