Renamed MultiLevelHashSet/Map to FeldmanHashSet/Map
[libcds.git] / tests / unit / map2 / map_find_int.h
1 //$$CDS-header$$
2
3 // defines concurrent access to map::nonconcurrent_iterator::Sequence::TValue::nAccess field
4
5 #include "map2/map_type.h"
6 #include "cppunit/thread.h"
7
8 #include <vector>
9
10 // find int test in map<int> in mutithreaded mode
11 namespace map2 {
12
13 #define TEST_CASE(TAG, X)  void X();
14
15     class Map_find_int: public CppUnitMini::TestCase
16     {
17     public:
18         size_t c_nThreadCount = 8;     // thread count
19         size_t c_nMapSize = 10000000;  // map size (count of searching item)
20         size_t c_nPercentExists = 50;  // percent of existing keys in searching sequence
21         size_t c_nPassCount = 2;
22         size_t c_nMaxLoadFactor = 8;   // maximum load factor
23         bool   c_bPrintGCState = true;
24
25         size_t c_nCuckooInitialSize = 1024;// initial size for CuckooMap
26         size_t c_nCuckooProbesetSize = 16; // CuckooMap probeset size (only for list-based probeset)
27         size_t c_nCuckooProbesetThreshold = 0; // CUckooMap probeset threshold (o - use default)
28
29         size_t c_nFeldmanMap_HeadBits = 10;
30         size_t c_nFeldmanMap_ArrayBits = 4;
31
32         size_t  c_nLoadFactor;  // current load factor
33
34     private:
35         typedef size_t   key_type;
36         struct value_type {
37             key_type    nKey    ;   // key
38             bool        bExists ;   // true - key in map, false - key not in map
39         };
40
41         typedef std::vector<value_type> ValueVector;
42         ValueVector             m_Arr;
43         size_t                  m_nRealMapSize;
44
45         void generateSequence();
46
47         template <typename Iterator, typename Map>
48         static bool check_result( Iterator const& it, Map const& map )
49         {
50             return it != map.end();
51         }
52         template <typename Map>
53         static bool check_result( bool b, Map const& )
54         {
55             return b;
56         }
57
58         template <class Map>
59         class TestThread: public CppUnitMini::TestThread
60         {
61             Map&     m_Map;
62
63             virtual TestThread *    clone()
64             {
65                 return new TestThread( *this );
66             }
67         public:
68             struct Stat {
69                 size_t      nSuccess;
70                 size_t      nFailed;
71
72                 Stat()
73                     : nSuccess(0)
74                     , nFailed(0)
75                 {}
76             };
77
78             Stat    m_KeyExists;
79             Stat    m_KeyNotExists;
80
81         public:
82             TestThread( CppUnitMini::ThreadPool& pool, Map& rMap )
83                 : CppUnitMini::TestThread( pool )
84                 , m_Map( rMap )
85             {}
86             TestThread( TestThread& src )
87                 : CppUnitMini::TestThread( src )
88                 , m_Map( src.m_Map )
89             {}
90
91             Map_find_int&  getTest()
92             {
93                 return reinterpret_cast<Map_find_int&>( m_Pool.m_Test );
94             }
95
96             virtual void init() { cds::threading::Manager::attachThread()   ; }
97             virtual void fini() { cds::threading::Manager::detachThread()   ; }
98
99             virtual void test()
100             {
101                 ValueVector& arr = getTest().m_Arr;
102                 size_t const nPassCount = getTest().c_nPassCount;
103
104                 Map& rMap = m_Map;
105                 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
106                     if ( m_nThreadNo & 1 ) {
107                         ValueVector::const_iterator itEnd = arr.end();
108                         for ( ValueVector::const_iterator it = arr.begin(); it != itEnd; ++it ) {
109                             auto bFound = rMap.contains( it->nKey );
110                             if ( it->bExists ) {
111                                 if ( check_result( bFound, rMap ))
112                                     ++m_KeyExists.nSuccess;
113                                 else {
114                                     //rMap.find( it->nKey );
115                                     ++m_KeyExists.nFailed;
116                                 }
117                             }
118                             else {
119                                 if ( check_result( bFound, rMap )) {
120                                     //rMap.find( it->nKey );
121                                     ++m_KeyNotExists.nFailed;
122                                 }
123                                 else
124                                     ++m_KeyNotExists.nSuccess;
125                             }
126                         }
127                     }
128                     else {
129                         ValueVector::const_reverse_iterator itEnd = arr.rend();
130                         for ( ValueVector::const_reverse_iterator it = arr.rbegin(); it != itEnd; ++it ) {
131                             auto bFound = rMap.contains( it->nKey );
132                             if ( it->bExists ) {
133                                 if ( check_result( bFound, rMap ))
134                                     ++m_KeyExists.nSuccess;
135                                 else {
136                                     //rMap.find( it->nKey );
137                                     ++m_KeyExists.nFailed;
138                                 }
139                             }
140                             else {
141                                 if ( check_result( bFound, rMap )) {
142                                     //rMap.find( it->nKey );
143                                     ++m_KeyNotExists.nFailed;
144                                 }
145                                 else
146                                     ++m_KeyNotExists.nSuccess;
147                             }
148                         }
149                     }
150                 }
151             }
152         };
153
154     protected:
155
156         template <class Map>
157         void find_int_test( Map& testMap )
158         {
159             typedef TestThread<Map>     Thread;
160             cds::OS::Timer    timer;
161
162             // Fill the map
163             CPPUNIT_MSG( "  Fill map with " << m_Arr.size() << " items...");
164             timer.reset();
165             for ( size_t i = 0; i < m_Arr.size(); ++i ) {
166                 if ( m_Arr[i].bExists ) {
167                     CPPUNIT_ASSERT( check_result( testMap.insert( m_Arr[i].nKey, m_Arr[i] ), testMap ));
168                 }
169             }
170             CPPUNIT_MSG( "   Duration=" << timer.duration() );
171
172             CPPUNIT_MSG( "  Searching...");
173             CppUnitMini::ThreadPool pool( *this );
174             pool.add( new Thread( pool, testMap ), c_nThreadCount );
175             pool.run();
176             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
177
178             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
179                 Thread * pThread = static_cast<Thread *>( *it );
180                 CPPUNIT_CHECK( pThread->m_KeyExists.nFailed == 0 );
181                 CPPUNIT_CHECK( pThread->m_KeyExists.nSuccess == m_nRealMapSize * c_nPassCount );
182                 CPPUNIT_CHECK( pThread->m_KeyNotExists.nFailed == 0 );
183                 CPPUNIT_CHECK( pThread->m_KeyNotExists.nSuccess == (m_Arr.size() - m_nRealMapSize) * c_nPassCount );
184             }
185
186             check_before_cleanup( testMap );
187
188             testMap.clear();
189             additional_check( testMap );
190             print_stat( testMap );
191             additional_cleanup( testMap );
192         }
193
194         template <class Map>
195         void run_test()
196         {
197             if ( Map::c_bLoadFactorDepended ) {
198                 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
199                     CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
200                     Map  testMap( *this );
201                     find_int_test( testMap );
202                     if ( c_bPrintGCState )
203                         print_gc_state();
204                 }
205             }
206             else {
207                 Map testMap( *this );
208                 find_int_test( testMap );
209                 if ( c_bPrintGCState )
210                     print_gc_state();
211             }
212         }
213
214         void setUpParams( const CppUnitMini::TestCfg& cfg );
215
216     public:
217         Map_find_int()
218             : c_nLoadFactor(2)
219         {}
220
221 #   include "map2/map_defs.h"
222         CDSUNIT_DECLARE_MichaelMap
223         CDSUNIT_DECLARE_MichaelMap_nogc
224         CDSUNIT_DECLARE_SplitList
225         CDSUNIT_DECLARE_SplitList_nogc
226         CDSUNIT_DECLARE_SkipListMap
227         CDSUNIT_DECLARE_SkipListMap_nogc
228         CDSUNIT_DECLARE_EllenBinTreeMap
229         CDSUNIT_DECLARE_BronsonAVLTreeMap
230         CDSUNIT_DECLARE_FeldmanHashMap
231         CDSUNIT_DECLARE_StripedMap
232         CDSUNIT_DECLARE_RefinableMap
233         CDSUNIT_DECLARE_CuckooMap
234         CDSUNIT_DECLARE_StdMap
235         CDSUNIT_DECLARE_StdMap_NoLock
236
237         CPPUNIT_TEST_SUITE(Map_find_int)
238             CDSUNIT_TEST_MichaelMap
239             CDSUNIT_TEST_MichaelMap_nogc
240             CDSUNIT_TEST_SplitList
241             CDSUNIT_TEST_SplitList_nogc
242             CDSUNIT_TEST_SkipListMap
243             CDSUNIT_TEST_SkipListMap_nogc
244             CDSUNIT_TEST_EllenBinTreeMap
245             CDSUNIT_TEST_BronsonAVLTreeMap
246             CDSUNIT_TEST_FeldmanHashMap
247             CDSUNIT_TEST_CuckooMap
248             CDSUNIT_TEST_StripedMap
249             CDSUNIT_TEST_RefinableMap
250             CDSUNIT_TEST_StdMap
251             CDSUNIT_TEST_StdMap_NoLock
252         CPPUNIT_TEST_SUITE_END();
253     };
254 } // namespace map