Reorganized map2 unit test to reduce compiling time and memory
[libcds.git] / tests / unit / map2 / map_insfind_int.h
1 //$$CDS-header$$
2
3 #include "map2/map_type.h"
4 #include "cppunit/thread.h"
5
6 #include <cds/os/topology.h>
7 #include <vector>
8 #include <algorithm> // random_shuffle
9
10 namespace map2 {
11
12 #   define TEST_MAP(IMPL, C, X)         void C::X() { test<map_type<IMPL, key_type, value_type>::X >(); }
13 #   define TEST_MAP_NOLF(IMPL, C, X)    void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >(); }
14 #   define TEST_MAP_EXTRACT(IMPL, C, X)  TEST_MAP(IMPL, C, X)
15 #   define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
16
17     class Map_InsFind_int: public CppUnitMini::TestCase
18     {
19         static size_t  c_nMapSize;       // map size
20         static size_t  c_nThreadCount;   // count of insertion thread
21         static size_t  c_nMaxLoadFactor; // maximum load factor
22         static bool    c_bPrintGCState;
23
24         typedef CppUnitMini::TestCase Base;
25         typedef size_t  key_type;
26         typedef size_t  value_type;
27
28         template <typename Iterator, typename Map>
29         static bool check_result( Iterator const& it, Map const& map )
30         {
31             return it != map.end();
32         }
33         template <typename Map>
34         static bool check_result( bool b, Map const& )
35         {
36             return b;
37         }
38
39         template <class Map>
40         class Inserter: public CppUnitMini::TestThread
41         {
42             Map&     m_Map;
43             std::vector<size_t> m_arrVal;
44
45             virtual Inserter *    clone()
46             {
47                 return new Inserter( *this );
48             }
49
50             void make_array()
51             {
52                 size_t const nSize = c_nMapSize / c_nThreadCount + 1;
53                 m_arrVal.resize( nSize );
54                 size_t nItem = m_nThreadNo;
55                 for ( size_t i = 0; i < nSize; nItem += c_nThreadCount, ++i )
56                     m_arrVal[i] = nItem;
57                 std::random_shuffle( m_arrVal.begin(), m_arrVal.end() );
58             }
59         public:
60             size_t  m_nInsertSuccess;
61             size_t  m_nInsertFailed;
62             size_t  m_nFindSuccess;
63             size_t  m_nFindFail;
64
65         public:
66             Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
67                 : CppUnitMini::TestThread( pool )
68                 , m_Map( rMap )
69             {}
70             Inserter( Inserter& src )
71                 : CppUnitMini::TestThread( src )
72                 , m_Map( src.m_Map )
73             {}
74
75             Map_InsFind_int&  getTest()
76             {
77                 return reinterpret_cast<Map_InsFind_int&>( m_Pool.m_Test );
78             }
79
80             virtual void init()
81             {
82                 cds::threading::Manager::attachThread();
83                 make_array();
84             }
85             virtual void fini() { cds::threading::Manager::detachThread()   ; }
86
87             virtual void test()
88             {
89                 Map& rMap = m_Map;
90
91                 m_nInsertSuccess =
92                     m_nInsertFailed =
93                     m_nFindSuccess =
94                     m_nFindFail = 0;
95
96                 size_t const nArrSize = m_arrVal.size();
97                 for ( size_t i = 0; i < nArrSize; ++i ) {
98                     size_t const nItem = m_arrVal[i];
99                     if ( check_result( rMap.insert( nItem, nItem * 8 ), rMap ))
100                         ++m_nInsertSuccess;
101                     else
102                         ++m_nInsertFailed;
103
104                     for ( size_t k = 0; k <= i; ++k ) {
105                         if ( check_result( rMap.find( m_arrVal[k] ), rMap ))
106                             ++m_nFindSuccess;
107                         else
108                             ++m_nFindFail;
109                     }
110                 }
111             }
112         };
113
114     protected:
115
116         template <class Map>
117         void do_test( Map& testMap )
118         {
119             typedef Inserter<Map>       InserterThread;
120             cds::OS::Timer    timer;
121
122             CppUnitMini::ThreadPool pool( *this );
123             pool.add( new InserterThread( pool, testMap ), c_nThreadCount );
124             pool.run();
125             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
126
127             size_t nInsertSuccess = 0;
128             size_t nInsertFailed = 0;
129             size_t nFindSuccess = 0;
130             size_t nFindFailed = 0;
131             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
132                 InserterThread * pThread = static_cast<InserterThread *>( *it );
133
134                 nInsertSuccess += pThread->m_nInsertSuccess;
135                 nInsertFailed += pThread->m_nInsertFailed;
136                 nFindSuccess += pThread->m_nFindSuccess;
137                 nFindFailed += pThread->m_nFindFail;
138             }
139
140             CPPUNIT_MSG( "    Totals: Ins succ=" << nInsertSuccess << " fail=" << nInsertFailed << "\n"
141                       << "           Find succ=" << nFindSuccess << " fail=" << nFindFailed
142             );
143
144             CPPUNIT_CHECK( nInsertFailed == 0 );
145             CPPUNIT_CHECK( nFindFailed == 0 );
146
147             check_before_cleanup( testMap );
148
149             testMap.clear();
150             additional_check( testMap );
151             print_stat( testMap );
152             additional_cleanup( testMap );
153         }
154
155         template <class Map>
156         void test()
157         {
158             static_assert( (!std::is_same< typename Map::item_counter, cds::atomicity::empty_item_counter >::value),
159                 "Empty item counter is not suitable for this test");
160
161             CPPUNIT_MSG( "Thread count: " << c_nThreadCount
162                 << " map size=" << c_nMapSize
163                 );
164
165             for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
166                 CPPUNIT_MSG( "Load factor=" << nLoadFactor );
167                 Map  testMap( c_nMapSize, nLoadFactor );
168                 do_test( testMap );
169                 if ( c_bPrintGCState )
170                     print_gc_state();
171             }
172         }
173
174         template <class Map>
175         void test_nolf()
176         {
177             static_assert( (!std::is_same< typename Map::item_counter, cds::atomicity::empty_item_counter >::value),
178                 "Empty item counter is not suitable for this test");
179
180             CPPUNIT_MSG( "Thread count: " << c_nThreadCount
181                 << " map size=" << c_nMapSize
182                 );
183
184             Map testMap;
185             do_test( testMap );
186             if ( c_bPrintGCState )
187                 print_gc_state();
188         }
189
190         void setUpParams( const CppUnitMini::TestCfg& cfg );
191
192         void run_MichaelMap(const char *in_name, bool invert = false);
193         void run_SplitList(const char *in_name, bool invert = false);
194         void run_StripedMap(const char *in_name, bool invert = false);
195         void run_RefinableMap(const char *in_name, bool invert = false);
196         void run_CuckooMap(const char *in_name, bool invert = false);
197         void run_SkipListMap(const char *in_name, bool invert = false);
198         void run_EllenBinTreeMap(const char *in_name, bool invert = false);
199         void run_BronsonAVLTreeMap(const char *in_name, bool invert = false);
200         void run_StdMap(const char *in_name, bool invert = false);
201
202         virtual void myRun(const char *in_name, bool invert = false);
203
204 #   include "map2/map_defs.h"
205         CDSUNIT_DECLARE_MichaelMap
206         CDSUNIT_DECLARE_MichaelMap_nogc
207         CDSUNIT_DECLARE_SplitList
208         CDSUNIT_DECLARE_SplitList_nogc
209         CDSUNIT_DECLARE_SkipListMap
210         CDSUNIT_DECLARE_SkipListMap_nogc
211         CDSUNIT_DECLARE_EllenBinTreeMap
212         CDSUNIT_DECLARE_BronsonAVLTreeMap
213         CDSUNIT_DECLARE_StripedMap
214         CDSUNIT_DECLARE_RefinableMap
215         CDSUNIT_DECLARE_CuckooMap
216         CDSUNIT_DECLARE_StdMap
217     };
218 } // namespace map2