MultiLevelHashSet test, bugfixing
[libcds.git] / tests / unit / map2 / map_insdel_string.h
1 //$$CDS-header$$
2
3 #include "map2/map_type.h"
4 #include "cppunit/thread.h"
5
6 #include <vector>
7
8 namespace map2 {
9
10 #define TEST_CASE(TAG, X)  void X();
11
12     class Map_InsDel_string: public CppUnitMini::TestCase
13     {
14     public:
15         size_t  c_nMapSize = 1000000;      // map size
16         size_t  c_nInsertThreadCount = 4;  // count of insertion thread
17         size_t  c_nDeleteThreadCount = 4;  // count of deletion thread
18         size_t  c_nThreadPassCount = 4;    // pass count for each thread
19         size_t  c_nMaxLoadFactor = 8;      // maximum load factor
20
21         size_t c_nCuckooInitialSize = 1024;// initial size for CuckooMap
22         size_t c_nCuckooProbesetSize = 16; // CuckooMap probeset size (only for list-based probeset)
23         size_t c_nCuckooProbesetThreshold = 0; // CUckooMap probeset threshold (o - use default)
24
25         size_t c_nMultiLevelMap_HeadBits = 10;
26         size_t c_nMultiLevelMap_ArrayBits = 4;
27
28         bool    c_bPrintGCState = true;
29
30         size_t  c_nLoadFactor;  // current load factor
31
32     private:
33         typedef std::string key_type;
34         typedef size_t      value_type;
35
36         const std::vector<std::string> *  m_parrString;
37
38         template <class Map>
39         class Inserter: public CppUnitMini::TestThread
40         {
41             Map&     m_Map;
42
43             virtual Inserter *    clone()
44             {
45                 return new Inserter( *this );
46             }
47         public:
48             size_t  m_nInsertSuccess;
49             size_t  m_nInsertFailed;
50
51         public:
52             Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
53                 : CppUnitMini::TestThread( pool )
54                 , m_Map( rMap )
55             {}
56             Inserter( Inserter& src )
57                 : CppUnitMini::TestThread( src )
58                 , m_Map( src.m_Map )
59             {}
60
61             Map_InsDel_string&  getTest()
62             {
63                 return reinterpret_cast<Map_InsDel_string&>( m_Pool.m_Test );
64             }
65
66             virtual void init() { cds::threading::Manager::attachThread()   ; }
67             virtual void fini() { cds::threading::Manager::detachThread()   ; }
68
69             virtual void test()
70             {
71                 Map& rMap = m_Map;
72
73                 m_nInsertSuccess =
74                     m_nInsertFailed = 0;
75
76                 const std::vector<std::string>& arrString = *getTest().m_parrString;
77                 size_t nArrSize = arrString.size();
78                 size_t const nMapSize = getTest().c_nMapSize;
79                 size_t const nPassCount = getTest().c_nThreadPassCount;
80
81                 if ( m_nThreadNo & 1 ) {
82                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
83                         for ( size_t nItem = 0; nItem < nMapSize; ++nItem ) {
84                             if ( rMap.insert( arrString[nItem % nArrSize], nItem * 8 ) )
85                                 ++m_nInsertSuccess;
86                             else
87                                 ++m_nInsertFailed;
88                         }
89                     }
90                 }
91                 else {
92                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
93                         for ( size_t nItem = nMapSize; nItem > 0; --nItem ) {
94                             if ( rMap.insert( arrString[nItem % nArrSize], nItem * 8 ) )
95                                 ++m_nInsertSuccess;
96                             else
97                                 ++m_nInsertFailed;
98                         }
99                     }
100                 }
101             }
102         };
103
104         template <class Map>
105         class Deleter: public CppUnitMini::TestThread
106         {
107             Map&     m_Map;
108
109             virtual Deleter *    clone()
110             {
111                 return new Deleter( *this );
112             }
113         public:
114             size_t  m_nDeleteSuccess;
115             size_t  m_nDeleteFailed;
116
117         public:
118             Deleter( CppUnitMini::ThreadPool& pool, Map& rMap )
119                 : CppUnitMini::TestThread( pool )
120                 , m_Map( rMap )
121             {}
122             Deleter( Deleter& src )
123                 : CppUnitMini::TestThread( src )
124                 , m_Map( src.m_Map )
125             {}
126
127             Map_InsDel_string&  getTest()
128             {
129                 return reinterpret_cast<Map_InsDel_string&>( m_Pool.m_Test );
130             }
131
132             virtual void init() { cds::threading::Manager::attachThread()   ; }
133             virtual void fini() { cds::threading::Manager::detachThread()   ; }
134
135             virtual void test()
136             {
137                 Map& rMap = m_Map;
138
139                 m_nDeleteSuccess =
140                     m_nDeleteFailed = 0;
141
142                 const std::vector<std::string>& arrString = *getTest().m_parrString;
143                 size_t nArrSize = arrString.size();
144                 size_t const nMapSize = getTest().c_nMapSize;
145                 size_t const nPassCount = getTest().c_nThreadPassCount;
146
147                 if ( m_nThreadNo & 1 ) {
148                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
149                         for ( size_t nItem = 0; nItem < nMapSize; ++nItem ) {
150                             if ( rMap.erase( arrString[nItem % nArrSize] ) )
151                                 ++m_nDeleteSuccess;
152                             else
153                                 ++m_nDeleteFailed;
154                         }
155                     }
156                 }
157                 else {
158                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
159                         for ( size_t nItem = nMapSize; nItem > 0; --nItem ) {
160                             if ( rMap.erase( arrString[nItem % nArrSize] ) )
161                                 ++m_nDeleteSuccess;
162                             else
163                                 ++m_nDeleteFailed;
164                         }
165                     }
166                 }
167             }
168         };
169
170     protected:
171
172         template <class Map>
173         void do_test( Map& testMap )
174         {
175             typedef Inserter<Map>       InserterThread;
176             typedef Deleter<Map>        DeleterThread;
177             cds::OS::Timer    timer;
178
179             CppUnitMini::ThreadPool pool( *this );
180             pool.add( new InserterThread( pool, testMap ), c_nInsertThreadCount );
181             pool.add( new DeleterThread( pool, testMap ), c_nDeleteThreadCount );
182             pool.run();
183             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
184
185             size_t nInsertSuccess = 0;
186             size_t nInsertFailed = 0;
187             size_t nDeleteSuccess = 0;
188             size_t nDeleteFailed = 0;
189             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
190                 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
191                 if ( pThread ) {
192                     nInsertSuccess += pThread->m_nInsertSuccess;
193                     nInsertFailed += pThread->m_nInsertFailed;
194                 }
195                 else {
196                     DeleterThread * p = static_cast<DeleterThread *>( *it );
197                     nDeleteSuccess += p->m_nDeleteSuccess;
198                     nDeleteFailed += p->m_nDeleteFailed;
199                 }
200             }
201
202             CPPUNIT_MSG( "    Totals: Ins succ=" << nInsertSuccess
203                 << " Del succ=" << nDeleteSuccess << "\n"
204                       << "          : Ins fail=" << nInsertFailed
205                 << " Del fail=" << nDeleteFailed
206                 << " Map size=" << testMap.size()
207                 );
208
209             check_before_cleanup( testMap );
210
211             CPPUNIT_MSG( "  Clear map (single-threaded)..." );
212             timer.reset();
213             for ( size_t i = 0; i < m_parrString->size(); ++i )
214                 testMap.erase( (*m_parrString)[i] );
215             CPPUNIT_MSG( "   Duration=" << timer.duration() );
216             CPPUNIT_CHECK( testMap.empty() );
217
218             additional_check( testMap );
219             print_stat( testMap );
220             additional_cleanup( testMap );
221         }
222
223         template <class Map>
224         void run_test()
225         {
226             m_parrString = &CppUnitMini::TestCase::getTestStrings();
227
228             CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
229                 << " delete=" << c_nDeleteThreadCount
230                 << " pass count=" << c_nThreadPassCount
231                 << " map size=" << c_nMapSize
232                 );
233
234             if ( Map::c_bLoadFactorDepended ) {
235                 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
236                     CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
237                     Map  testMap( *this );
238                     do_test( testMap );
239                     if ( c_bPrintGCState )
240                         print_gc_state();
241                 }
242             }
243             else {
244                 Map testMap( *this );
245                 do_test( testMap );
246                 if ( c_bPrintGCState )
247                     print_gc_state();
248             }
249         }
250
251         void setUpParams( const CppUnitMini::TestCfg& cfg );
252
253 #   include "map2/map_defs.h"
254         CDSUNIT_DECLARE_MichaelMap
255         CDSUNIT_DECLARE_SplitList
256         CDSUNIT_DECLARE_SkipListMap
257         CDSUNIT_DECLARE_EllenBinTreeMap
258         CDSUNIT_DECLARE_BronsonAVLTreeMap
259         CDSUNIT_DECLARE_MultiLevelHashMap_sha256
260         CDSUNIT_DECLARE_MultiLevelHashMap_city
261         CDSUNIT_DECLARE_StripedMap
262         CDSUNIT_DECLARE_RefinableMap
263         CDSUNIT_DECLARE_CuckooMap
264         CDSUNIT_DECLARE_StdMap
265
266         CPPUNIT_TEST_SUITE(Map_InsDel_string)
267             CDSUNIT_TEST_MichaelMap
268             CDSUNIT_TEST_SplitList
269             CDSUNIT_TEST_SkipListMap
270             CDSUNIT_TEST_EllenBinTreeMap
271             CDSUNIT_TEST_BronsonAVLTreeMap
272             CDSUNIT_TEST_MultiLevelHashMap_sha256
273             CDSUNIT_TEST_MultiLevelHashMap_city
274             CDSUNIT_TEST_CuckooMap
275             CDSUNIT_TEST_StripedMap
276             CDSUNIT_TEST_RefinableMap
277             CDSUNIT_TEST_StdMap
278         CPPUNIT_TEST_SUITE_END();
279     };
280 } // namespace map2