3 // defines concurrent access to map::nonconcurrent_iterator::Sequence::TValue::nAccess field
5 #include "map2/map_type.h"
6 #include "cppunit/thread.h"
10 // find int test in map<int> in mutithreaded mode
13 #define TEST_CASE(TAG, X) void X();
15 class Map_find_int: public CppUnitMini::TestCase
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;
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)
29 size_t c_nMultiLevelMap_HeadBits = 10;
30 size_t c_nMultiLevelMap_ArrayBits = 4;
32 size_t c_nLoadFactor; // current load factor
35 typedef CppUnitMini::TestCase Base;
36 typedef size_t key_type;
38 key_type nKey ; // key
39 bool bExists ; // true - key in map, false - key not in map
42 typedef std::vector<value_type> ValueVector;
44 size_t m_nRealMapSize;
46 void generateSequence();
48 template <typename Iterator, typename Map>
49 static bool check_result( Iterator const& it, Map const& map )
51 return it != map.end();
53 template <typename Map>
54 static bool check_result( bool b, Map const& )
60 class TestThread: public CppUnitMini::TestThread
64 virtual TestThread * clone()
66 return new TestThread( *this );
83 TestThread( CppUnitMini::ThreadPool& pool, Map& rMap )
84 : CppUnitMini::TestThread( pool )
87 TestThread( TestThread& src )
88 : CppUnitMini::TestThread( src )
92 Map_find_int& getTest()
94 return reinterpret_cast<Map_find_int&>( m_Pool.m_Test );
97 virtual void init() { cds::threading::Manager::attachThread() ; }
98 virtual void fini() { cds::threading::Manager::detachThread() ; }
102 ValueVector& arr = getTest().m_Arr;
103 size_t const nPassCount = getTest().c_nPassCount;
106 for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
107 if ( m_nThreadNo & 1 ) {
108 ValueVector::const_iterator itEnd = arr.end();
109 for ( ValueVector::const_iterator it = arr.begin(); it != itEnd; ++it ) {
110 auto bFound = rMap.contains( it->nKey );
112 if ( check_result( bFound, rMap ))
113 ++m_KeyExists.nSuccess;
115 //rMap.find( it->nKey );
116 ++m_KeyExists.nFailed;
120 if ( check_result( bFound, rMap )) {
121 //rMap.find( it->nKey );
122 ++m_KeyNotExists.nFailed;
125 ++m_KeyNotExists.nSuccess;
130 ValueVector::const_reverse_iterator itEnd = arr.rend();
131 for ( ValueVector::const_reverse_iterator it = arr.rbegin(); it != itEnd; ++it ) {
132 auto bFound = rMap.contains( it->nKey );
134 if ( check_result( bFound, rMap ))
135 ++m_KeyExists.nSuccess;
137 //rMap.find( it->nKey );
138 ++m_KeyExists.nFailed;
142 if ( check_result( bFound, rMap )) {
143 //rMap.find( it->nKey );
144 ++m_KeyNotExists.nFailed;
147 ++m_KeyNotExists.nSuccess;
158 void find_int_test( Map& testMap )
160 typedef TestThread<Map> Thread;
161 cds::OS::Timer timer;
164 CPPUNIT_MSG( " Fill map with " << m_Arr.size() << " items...");
166 for ( size_t i = 0; i < m_Arr.size(); ++i ) {
167 if ( m_Arr[i].bExists ) {
168 CPPUNIT_ASSERT( check_result( testMap.insert( m_Arr[i].nKey, m_Arr[i] ), testMap ));
171 CPPUNIT_MSG( " Duration=" << timer.duration() );
173 CPPUNIT_MSG( " Searching...");
174 CppUnitMini::ThreadPool pool( *this );
175 pool.add( new Thread( pool, testMap ), c_nThreadCount );
177 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
179 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
180 Thread * pThread = static_cast<Thread *>( *it );
181 CPPUNIT_CHECK( pThread->m_KeyExists.nFailed == 0 );
182 CPPUNIT_CHECK( pThread->m_KeyExists.nSuccess == m_nRealMapSize * c_nPassCount );
183 CPPUNIT_CHECK( pThread->m_KeyNotExists.nFailed == 0 );
184 CPPUNIT_CHECK( pThread->m_KeyNotExists.nSuccess == (m_Arr.size() - m_nRealMapSize) * c_nPassCount );
187 check_before_cleanup( testMap );
190 additional_check( testMap );
191 print_stat( testMap );
192 additional_cleanup( testMap );
198 if ( Map::c_bLoadFactorDepended ) {
199 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
200 CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
201 Map testMap( *this );
202 find_int_test( testMap );
203 if ( c_bPrintGCState )
208 Map testMap( *this );
209 find_int_test( testMap );
210 if ( c_bPrintGCState )
215 void setUpParams( const CppUnitMini::TestCfg& cfg );
222 # include "map2/map_defs.h"
223 CDSUNIT_DECLARE_MichaelMap
224 CDSUNIT_DECLARE_MichaelMap_nogc
225 CDSUNIT_DECLARE_SplitList
226 CDSUNIT_DECLARE_SplitList_nogc
227 CDSUNIT_DECLARE_SkipListMap
228 CDSUNIT_DECLARE_SkipListMap_nogc
229 CDSUNIT_DECLARE_EllenBinTreeMap
230 CDSUNIT_DECLARE_BronsonAVLTreeMap
231 CDSUNIT_DECLARE_MultiLevelHashMap
232 CDSUNIT_DECLARE_StripedMap
233 CDSUNIT_DECLARE_RefinableMap
234 CDSUNIT_DECLARE_CuckooMap
235 CDSUNIT_DECLARE_StdMap
236 CDSUNIT_DECLARE_StdMap_NoLock
238 CPPUNIT_TEST_SUITE(Map_find_int)
239 CDSUNIT_TEST_MichaelMap
240 CDSUNIT_TEST_MichaelMap_nogc
241 CDSUNIT_TEST_SplitList
242 CDSUNIT_TEST_SplitList_nogc
243 CDSUNIT_TEST_SkipListMap
244 CDSUNIT_TEST_SkipListMap_nogc
245 CDSUNIT_TEST_EllenBinTreeMap
246 CDSUNIT_TEST_BronsonAVLTreeMap
247 CDSUNIT_TEST_MultiLevelHashMap
248 CDSUNIT_TEST_CuckooMap
249 CDSUNIT_TEST_StripedMap
250 CDSUNIT_TEST_RefinableMap
252 CDSUNIT_TEST_StdMap_NoLock
253 CPPUNIT_TEST_SUITE_END();