Renoved MD5 MT-test
[libcds.git] / tests / unit / map2 / map_insdel_item_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_Item_string: public CppUnitMini::TestCase
13     {
14     public:
15         size_t  c_nMapSize = 1000000;       // map size
16         size_t  c_nThreadCount = 4;         // thread count
17         size_t  c_nAttemptCount = 100000;   // count of SUCCESS insert/delete for each thread
18         size_t  c_nMaxLoadFactor = 8;       // maximum load factor
19         bool    c_bPrintGCState = true;
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_nFeldmanMap_HeadBits = 10;
26         size_t c_nFeldmanMap_ArrayBits = 4;
27
28         size_t  c_nGoalItem;
29         size_t  c_nLoadFactor = 2;  // current load factor
30
31     private:
32         typedef std::string  key_type;
33         typedef size_t  value_type;
34
35         const std::vector<std::string> *  m_parrString;
36
37         template <class Map>
38         class Inserter: public CppUnitMini::TestThread
39         {
40             Map&     m_Map;
41
42             virtual Inserter *    clone()
43             {
44                 return new Inserter( *this );
45             }
46         public:
47             size_t  m_nInsertSuccess;
48             size_t  m_nInsertFailed;
49
50         public:
51             Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
52                 : CppUnitMini::TestThread( pool )
53                 , m_Map( rMap )
54             {}
55             Inserter( Inserter& src )
56                 : CppUnitMini::TestThread( src )
57                 , m_Map( src.m_Map )
58             {}
59
60             Map_InsDel_Item_string&  getTest()
61             {
62                 return reinterpret_cast<Map_InsDel_Item_string&>( m_Pool.m_Test );
63             }
64
65             virtual void init() { cds::threading::Manager::attachThread()   ; }
66             virtual void fini() { cds::threading::Manager::detachThread()   ; }
67
68             virtual void test()
69             {
70                 Map& rMap = m_Map;
71
72                 m_nInsertSuccess =
73                     m_nInsertFailed = 0;
74
75                 size_t nGoalItem = getTest().c_nGoalItem;
76                 std::string strGoal = (*getTest().m_parrString)[nGoalItem];
77                 size_t const nAttemptCount = getTest().c_nAttemptCount;
78
79                 for ( size_t nAttempt = 0; nAttempt < nAttemptCount; ) {
80                     if ( rMap.insert( strGoal, nGoalItem )) {
81                         ++m_nInsertSuccess;
82                         ++nAttempt;
83                     }
84                     else
85                         ++m_nInsertFailed;
86                 }
87             }
88         };
89
90         template <class Map>
91         class Deleter: public CppUnitMini::TestThread
92         {
93             Map&     m_Map;
94
95             struct erase_cleaner {
96                 void operator ()(std::pair<typename Map::key_type const, typename Map::mapped_type>& val )
97                 {
98                     val.second = 0;
99                 }
100                 // for boost::container::flat_map
101                 void operator ()(std::pair< typename std::remove_const< typename Map::key_type >::type, typename Map::mapped_type>& val )
102                 {
103                     val.second = 0;
104                 }
105                 // for BronsonAVLTreeMap
106                 void operator()( typename Map::key_type const& /*key*/, typename Map::mapped_type& val )
107                 {
108                     val = 0;
109                 }
110             };
111
112             virtual Deleter *    clone()
113             {
114                 return new Deleter( *this );
115             }
116         public:
117             size_t  m_nDeleteSuccess;
118             size_t  m_nDeleteFailed;
119
120         public:
121             Deleter( CppUnitMini::ThreadPool& pool, Map& rMap )
122                 : CppUnitMini::TestThread( pool )
123                 , m_Map( rMap )
124             {}
125             Deleter( Deleter& src )
126                 : CppUnitMini::TestThread( src )
127                 , m_Map( src.m_Map )
128             {}
129
130             Map_InsDel_Item_string&  getTest()
131             {
132                 return reinterpret_cast<Map_InsDel_Item_string&>( m_Pool.m_Test );
133             }
134
135             virtual void init() { cds::threading::Manager::attachThread()   ; }
136             virtual void fini() { cds::threading::Manager::detachThread()   ; }
137
138             virtual void test()
139             {
140                 Map& rMap = m_Map;
141
142                 m_nDeleteSuccess =
143                     m_nDeleteFailed = 0;
144
145                 size_t nGoalItem = getTest().c_nGoalItem;
146                 std::string strGoal = (*getTest().m_parrString)[nGoalItem];
147                 size_t const nAttemptCount = getTest().c_nAttemptCount;
148
149                 for ( size_t nAttempt = 0; nAttempt < nAttemptCount; ) {
150                     if ( rMap.erase( strGoal, erase_cleaner() )) {
151                         ++m_nDeleteSuccess;
152                         ++nAttempt;
153                     }
154                     else
155                         ++m_nDeleteFailed;
156                 }
157             }
158         };
159
160     protected:
161
162         template <class Map>
163         void do_test( Map& testMap )
164         {
165             typedef Inserter<Map>       InserterThread;
166             typedef Deleter<Map>        DeleterThread;
167             cds::OS::Timer    timer;
168
169             // Fill the map
170             CPPUNIT_MSG( "  Fill map (" << c_nMapSize << " items)...");
171             timer.reset();
172             for ( size_t i = 0; i < c_nMapSize; ++i ) {
173                 CPPUNIT_ASSERT_EX( testMap.insert( (*m_parrString)[i], i ), i );
174             }
175             CPPUNIT_MSG( "   Duration=" << timer.duration() );
176
177             CPPUNIT_MSG( "  Insert/delete the key " << c_nGoalItem << " (" << c_nAttemptCount << " successful times)...");
178             CppUnitMini::ThreadPool pool( *this );
179             pool.add( new InserterThread( pool, testMap ), (c_nThreadCount + 1) / 2 );
180             pool.add( new DeleterThread( pool, testMap ), (c_nThreadCount + 1) / 2 );
181             pool.run();
182             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
183
184             size_t nInsertSuccess = 0;
185             size_t nInsertFailed = 0;
186             size_t nDeleteSuccess = 0;
187             size_t nDeleteFailed = 0;
188             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
189                 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
190                 if ( pThread ) {
191                     CPPUNIT_CHECK( pThread->m_nInsertSuccess == c_nAttemptCount );
192                     nInsertSuccess += pThread->m_nInsertSuccess;
193                     nInsertFailed += pThread->m_nInsertFailed;
194                 }
195                 else {
196                     DeleterThread * p = static_cast<DeleterThread *>( *it );
197                     CPPUNIT_CHECK( p->m_nDeleteSuccess == c_nAttemptCount );
198                     nDeleteSuccess += p->m_nDeleteSuccess;
199                     nDeleteFailed += p->m_nDeleteFailed;
200                 }
201             }
202             CPPUNIT_CHECK_EX( nInsertSuccess == nDeleteSuccess, "nInsertSuccess=" << nInsertSuccess << ", nDeleteSuccess=" << nDeleteSuccess );
203             CPPUNIT_MSG( "    Totals: Ins fail=" << nInsertFailed << " Del fail=" << nDeleteFailed );
204
205             // Check if the map contains all items
206             CPPUNIT_MSG( "    Check if the map contains all items" );
207             timer.reset();
208             for ( size_t i = 0; i < c_nMapSize; ++i ) {
209                 CPPUNIT_CHECK_EX( testMap.contains( (*m_parrString)[i] ), "Key \"" << (*m_parrString)[i] << "\" not found" );
210             }
211             CPPUNIT_MSG( "    Duration=" << timer.duration() );
212
213             check_before_cleanup( testMap );
214
215             testMap.clear();
216             additional_check( testMap );
217             print_stat( testMap );
218             additional_cleanup( testMap );
219         }
220
221         template <class Map>
222         void run_test()
223         {
224             m_parrString = &CppUnitMini::TestCase::getTestStrings();
225             if ( c_nMapSize > m_parrString->size() )
226                 c_nMapSize = m_parrString->size();
227             if ( c_nGoalItem > m_parrString->size() )
228                 c_nGoalItem = m_parrString->size() / 2;
229
230             CPPUNIT_MSG( "Thread count= " << c_nThreadCount
231                 << " pass count=" << c_nAttemptCount
232                 << " map size=" << c_nMapSize
233                 );
234
235             if ( Map::c_bLoadFactorDepended ) {
236                 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
237                     CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
238                     Map  testMap( *this );
239                     do_test( testMap );
240                     if ( c_bPrintGCState )
241                         print_gc_state();
242                 }
243             }
244             else {
245                 Map testMap( *this );
246                 do_test( testMap );
247                 if ( c_bPrintGCState )
248                     print_gc_state();
249             }
250         }
251
252         void setUpParams( const CppUnitMini::TestCfg& cfg );
253
254 #   include "map2/map_defs.h"
255         CDSUNIT_DECLARE_MichaelMap
256         CDSUNIT_DECLARE_SplitList
257         CDSUNIT_DECLARE_SkipListMap
258         CDSUNIT_DECLARE_EllenBinTreeMap
259         CDSUNIT_DECLARE_BronsonAVLTreeMap
260         CDSUNIT_DECLARE_FeldmanHashMap_city
261         CDSUNIT_DECLARE_StripedMap
262         CDSUNIT_DECLARE_RefinableMap
263         CDSUNIT_DECLARE_CuckooMap
264         // CDSUNIT_DECLARE_StdMap // very slow!!
265
266         CPPUNIT_TEST_SUITE(Map_InsDel_Item_string)
267             CDSUNIT_TEST_MichaelMap
268             CDSUNIT_TEST_SplitList
269             CDSUNIT_TEST_SkipListMap
270             CDSUNIT_TEST_EllenBinTreeMap
271             CDSUNIT_TEST_BronsonAVLTreeMap
272             CDSUNIT_TEST_FeldmanHashMap_city
273             CDSUNIT_TEST_CuckooMap
274             CDSUNIT_TEST_StripedMap
275             CDSUNIT_TEST_RefinableMap
276             // CDSUNIT_TEST_StdMap // very slow!!
277         CPPUNIT_TEST_SUITE_END();
278
279     };
280 } // namespace map2