a47738fd61eccbe8d7c7860092b224bf672e50c6
[libcds.git] / tests / unit / map2 / map_insdel_int.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_int: 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 size_t  key_type;
35         typedef size_t  value_type;
36
37         typedef std::vector<key_type>   key_array;
38         key_array                       m_arrValues;
39
40         template <class Map>
41         class Inserter: public CppUnitMini::TestThread
42         {
43             Map&     m_Map;
44
45             virtual Inserter *    clone()
46             {
47                 return new Inserter( *this );
48             }
49         public:
50             size_t  m_nInsertSuccess;
51             size_t  m_nInsertFailed;
52
53         public:
54             Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
55                 : CppUnitMini::TestThread( pool )
56                 , m_Map( rMap )
57             {}
58             Inserter( Inserter& src )
59                 : CppUnitMini::TestThread( src )
60                 , m_Map( src.m_Map )
61             {}
62
63             Map_InsDel_int&  getTest()
64             {
65                 return reinterpret_cast<Map_InsDel_int&>( m_Pool.m_Test );
66             }
67
68             virtual void init() { cds::threading::Manager::attachThread()   ; }
69             virtual void fini() { cds::threading::Manager::detachThread()   ; }
70
71             virtual void test()
72             {
73                 Map& rMap = m_Map;
74
75                 m_nInsertSuccess =
76                     m_nInsertFailed = 0;
77                 key_array const& arr = getTest().m_arrValues;
78
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 ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
84                             if ( rMap.insert( *it, *it * 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 ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
94                             if ( rMap.insert( *it, *it * 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_int&  getTest()
128             {
129                 return reinterpret_cast<Map_InsDel_int&>( 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                 key_array const& arr = getTest().m_arrValues;
142
143                 size_t const nPassCount = getTest().c_nThreadPassCount;
144
145                 if ( m_nThreadNo & 1 ) {
146                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
147                         for ( key_array::const_iterator it = arr.begin(), itEnd = arr.end(); it != itEnd; ++it ) {
148                             if ( rMap.erase( *it ) )
149                                 ++m_nDeleteSuccess;
150                             else
151                                 ++m_nDeleteFailed;
152                         }
153                     }
154                 }
155                 else {
156                     for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
157                         for ( key_array::const_reverse_iterator it = arr.rbegin(), itEnd = arr.rend(); it != itEnd; ++it ) {
158                             if ( rMap.erase( *it ) )
159                                 ++m_nDeleteSuccess;
160                             else
161                                 ++m_nDeleteFailed;
162                         }
163                     }
164                 }
165             }
166         };
167
168     protected:
169         template <class Map>
170         void do_test( Map& testMap )
171         {
172             typedef Inserter<Map>       InserterThread;
173             typedef Deleter<Map>        DeleterThread;
174             cds::OS::Timer    timer;
175
176             CppUnitMini::ThreadPool pool( *this );
177             pool.add( new InserterThread( pool, testMap ), c_nInsertThreadCount );
178             pool.add( new DeleterThread( pool, testMap ), c_nDeleteThreadCount );
179             pool.run();
180             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
181
182             size_t nInsertSuccess = 0;
183             size_t nInsertFailed = 0;
184             size_t nDeleteSuccess = 0;
185             size_t nDeleteFailed = 0;
186             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
187                 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
188                 if ( pThread ) {
189                     nInsertSuccess += pThread->m_nInsertSuccess;
190                     nInsertFailed += pThread->m_nInsertFailed;
191                 }
192                 else {
193                     DeleterThread * p = static_cast<DeleterThread *>( *it );
194                     nDeleteSuccess += p->m_nDeleteSuccess;
195                     nDeleteFailed += p->m_nDeleteFailed;
196                 }
197             }
198
199             CPPUNIT_MSG( "    Totals: Ins succ=" << nInsertSuccess
200                 << " Del succ=" << nDeleteSuccess << "\n"
201                 << "          : Ins fail=" << nInsertFailed
202                 << " Del fail=" << nDeleteFailed
203                 << " Map size=" << testMap.size()
204                 );
205
206             check_before_cleanup( testMap );
207
208             CPPUNIT_MSG( "  Clear map (single-threaded)..." );
209             timer.reset();
210             for ( size_t nItem = 0; nItem < c_nMapSize; ++nItem ) {
211                 testMap.erase( nItem );
212             }
213             CPPUNIT_MSG( "   Duration=" << timer.duration() );
214             CPPUNIT_ASSERT_EX( testMap.empty(), ((long long) testMap.size()) );
215
216             additional_check( testMap );
217             print_stat( testMap );
218             additional_cleanup( testMap );
219         }
220
221         template <class Map>
222         void run_test()
223         {
224             CPPUNIT_MSG( "Thread count: insert=" << c_nInsertThreadCount
225                 << " delete=" << c_nDeleteThreadCount
226                 << " pass count=" << c_nThreadPassCount
227                 << " map size=" << c_nMapSize
228                 );
229
230             if ( Map::c_bLoadFactorDepended ) {
231                 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
232                     CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
233                     Map  testMap( *this );
234                     do_test( testMap );
235                     if ( c_bPrintGCState )
236                         print_gc_state();
237                 }
238             }
239             else {
240                 Map testMap( *this );
241                 do_test( testMap );
242                 if ( c_bPrintGCState )
243                     print_gc_state();
244             }
245         }
246
247         void setUpParams( const CppUnitMini::TestCfg& cfg );
248
249 #   include "map2/map_defs.h"
250         CDSUNIT_DECLARE_MichaelMap
251         CDSUNIT_DECLARE_SplitList
252         CDSUNIT_DECLARE_SkipListMap
253         CDSUNIT_DECLARE_EllenBinTreeMap
254         CDSUNIT_DECLARE_BronsonAVLTreeMap
255         CDSUNIT_DECLARE_MultiLevelHashMap
256         CDSUNIT_DECLARE_StripedMap
257         CDSUNIT_DECLARE_RefinableMap
258         CDSUNIT_DECLARE_CuckooMap
259         CDSUNIT_DECLARE_StdMap
260
261         CPPUNIT_TEST_SUITE(Map_InsDel_int)
262             CDSUNIT_TEST_MichaelMap
263             CDSUNIT_TEST_SplitList
264             CDSUNIT_TEST_SkipListMap
265             CDSUNIT_TEST_EllenBinTreeMap
266             CDSUNIT_TEST_BronsonAVLTreeMap
267             CDSUNIT_TEST_MultiLevelHashMap
268             CDSUNIT_TEST_CuckooMap
269             CDSUNIT_TEST_StripedMap
270             CDSUNIT_TEST_RefinableMap
271             CDSUNIT_TEST_StdMap
272         CPPUNIT_TEST_SUITE_END();
273     };
274 } // namespace map2