372bbd6b009e979fa1243c49d874939b31deba4c
[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 CppUnitMini::TestCase Base;
34         typedef std::string key_type;
35         typedef size_t      value_type;
36
37         const std::vector<std::string> *  m_parrString;
38
39         template <class Map>
40         class Inserter: public CppUnitMini::TestThread
41         {
42             Map&     m_Map;
43
44             virtual Inserter *    clone()
45             {
46                 return new Inserter( *this );
47             }
48         public:
49             size_t  m_nInsertSuccess;
50             size_t  m_nInsertFailed;
51
52         public:
53             Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
54                 : CppUnitMini::TestThread( pool )
55                 , m_Map( rMap )
56             {}
57             Inserter( Inserter& src )
58                 : CppUnitMini::TestThread( src )
59                 , m_Map( src.m_Map )
60             {}
61
62             Map_InsDel_string&  getTest()
63             {
64                 return reinterpret_cast<Map_InsDel_string&>( m_Pool.m_Test );
65             }
66
67             virtual void init() { cds::threading::Manager::attachThread()   ; }
68             virtual void fini() { cds::threading::Manager::detachThread()   ; }
69
70             virtual void test()
71             {
72                 Map& rMap = m_Map;
73
74                 m_nInsertSuccess =
75                     m_nInsertFailed = 0;
76
77                 const std::vector<std::string>& arrString = *getTest().m_parrString;
78                 size_t nArrSize = arrString.size();
79                 size_t const nMapSize = getTest().c_nMapSize;
80                 size_t const nPassCount = getTest().c_nThreadPassCount;
81
82                 if ( m_nThreadNo & 1 ) {
83                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
84                         for ( size_t nItem = 0; nItem < nMapSize; ++nItem ) {
85                             if ( rMap.insert( arrString[nItem % nArrSize], nItem * 8 ) )
86                                 ++m_nInsertSuccess;
87                             else
88                                 ++m_nInsertFailed;
89                         }
90                     }
91                 }
92                 else {
93                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
94                         for ( size_t nItem = nMapSize; nItem > 0; --nItem ) {
95                             if ( rMap.insert( arrString[nItem % nArrSize], nItem * 8 ) )
96                                 ++m_nInsertSuccess;
97                             else
98                                 ++m_nInsertFailed;
99                         }
100                     }
101                 }
102             }
103         };
104
105         template <class Map>
106         class Deleter: public CppUnitMini::TestThread
107         {
108             Map&     m_Map;
109
110             virtual Deleter *    clone()
111             {
112                 return new Deleter( *this );
113             }
114         public:
115             size_t  m_nDeleteSuccess;
116             size_t  m_nDeleteFailed;
117
118         public:
119             Deleter( CppUnitMini::ThreadPool& pool, Map& rMap )
120                 : CppUnitMini::TestThread( pool )
121                 , m_Map( rMap )
122             {}
123             Deleter( Deleter& src )
124                 : CppUnitMini::TestThread( src )
125                 , m_Map( src.m_Map )
126             {}
127
128             Map_InsDel_string&  getTest()
129             {
130                 return reinterpret_cast<Map_InsDel_string&>( m_Pool.m_Test );
131             }
132
133             virtual void init() { cds::threading::Manager::attachThread()   ; }
134             virtual void fini() { cds::threading::Manager::detachThread()   ; }
135
136             virtual void test()
137             {
138                 Map& rMap = m_Map;
139
140                 m_nDeleteSuccess =
141                     m_nDeleteFailed = 0;
142
143                 const std::vector<std::string>& arrString = *getTest().m_parrString;
144                 size_t nArrSize = arrString.size();
145                 size_t const nMapSize = getTest().c_nMapSize;
146                 size_t const nPassCount = getTest().c_nThreadPassCount;
147
148                 if ( m_nThreadNo & 1 ) {
149                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
150                         for ( size_t nItem = 0; nItem < nMapSize; ++nItem ) {
151                             if ( rMap.erase( arrString[nItem % nArrSize] ) )
152                                 ++m_nDeleteSuccess;
153                             else
154                                 ++m_nDeleteFailed;
155                         }
156                     }
157                 }
158                 else {
159                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
160                         for ( size_t nItem = nMapSize; nItem > 0; --nItem ) {
161                             if ( rMap.erase( arrString[nItem % nArrSize] ) )
162                                 ++m_nDeleteSuccess;
163                             else
164                                 ++m_nDeleteFailed;
165                         }
166                     }
167                 }
168             }
169         };
170
171     protected:
172
173         template <class Map>
174         void do_test( Map& testMap )
175         {
176             typedef Inserter<Map>       InserterThread;
177             typedef Deleter<Map>        DeleterThread;
178             cds::OS::Timer    timer;
179
180             CppUnitMini::ThreadPool pool( *this );
181             pool.add( new InserterThread( pool, testMap ), c_nInsertThreadCount );
182             pool.add( new DeleterThread( pool, testMap ), c_nDeleteThreadCount );
183             pool.run();
184             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
185
186             size_t nInsertSuccess = 0;
187             size_t nInsertFailed = 0;
188             size_t nDeleteSuccess = 0;
189             size_t nDeleteFailed = 0;
190             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
191                 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
192                 if ( pThread ) {
193                     nInsertSuccess += pThread->m_nInsertSuccess;
194                     nInsertFailed += pThread->m_nInsertFailed;
195                 }
196                 else {
197                     DeleterThread * p = static_cast<DeleterThread *>( *it );
198                     nDeleteSuccess += p->m_nDeleteSuccess;
199                     nDeleteFailed += p->m_nDeleteFailed;
200                 }
201             }
202
203             CPPUNIT_MSG( "    Totals: Ins succ=" << nInsertSuccess
204                 << " Del succ=" << nDeleteSuccess << "\n"
205                       << "          : Ins fail=" << nInsertFailed
206                 << " Del fail=" << nDeleteFailed
207                 << " Map size=" << testMap.size()
208                 );
209
210             check_before_cleanup( testMap );
211
212             CPPUNIT_MSG( "  Clear map (single-threaded)..." );
213             timer.reset();
214             for ( size_t i = 0; i < m_parrString->size(); ++i )
215                 testMap.erase( (*m_parrString)[i] );
216             CPPUNIT_MSG( "   Duration=" << timer.duration() );
217             CPPUNIT_CHECK( testMap.empty() );
218
219             additional_check( testMap );
220             print_stat( testMap );
221             additional_cleanup( testMap );
222         }
223
224         template <class Map>
225         void run_test()
226         {
227             m_parrString = &CppUnitMini::TestCase::getTestStrings();
228
229             CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
230                 << " delete=" << c_nDeleteThreadCount
231                 << " pass count=" << c_nThreadPassCount
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_MultiLevelHashMap
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
273             CDSUNIT_TEST_CuckooMap
274             CDSUNIT_TEST_StripedMap
275             CDSUNIT_TEST_RefinableMap
276             CDSUNIT_TEST_StdMap
277         CPPUNIT_TEST_SUITE_END();
278     };
279 } // namespace map2