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