3 #include "map2/map_types.h"
4 #include "cppunit/thread.h"
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)
16 static size_t c_nMapSize = 1000000 ; // map size
17 static size_t c_nThreadCount = 4 ; // thread count
18 static size_t c_nGoalItem = c_nMapSize / 2;
19 static size_t c_nAttemptCount = 100000 ; // count of SUCCESS insert/delete for each thread
20 static size_t c_nMaxLoadFactor = 8 ; // maximum load factor
21 static bool c_bPrintGCState = true;
24 class Map_InsDel_Item_string: public CppUnitMini::TestCase
26 typedef std::string key_type;
27 typedef size_t value_type;
29 const std::vector<std::string> * m_parrString;
32 class Inserter: public CppUnitMini::TestThread
36 virtual Inserter * clone()
38 return new Inserter( *this );
41 size_t m_nInsertSuccess;
42 size_t m_nInsertFailed;
45 Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
46 : CppUnitMini::TestThread( pool )
49 Inserter( Inserter& src )
50 : CppUnitMini::TestThread( src )
54 Map_InsDel_Item_string& getTest()
56 return reinterpret_cast<Map_InsDel_Item_string&>( m_Pool.m_Test );
59 virtual void init() { cds::threading::Manager::attachThread() ; }
60 virtual void fini() { cds::threading::Manager::detachThread() ; }
69 size_t nGoalItem = c_nGoalItem;
70 std::string strGoal = (*getTest().m_parrString)[nGoalItem];
72 for ( size_t nAttempt = 0; nAttempt < c_nAttemptCount; ) {
73 if ( rMap.insert( strGoal, nGoalItem )) {
84 class Deleter: public CppUnitMini::TestThread
88 struct erase_cleaner {
89 void operator ()(std::pair<typename Map::key_type const, typename Map::mapped_type>& val )
93 // for boost::container::flat_map
94 void operator ()(std::pair< typename std::remove_const< typename Map::key_type >::type, typename Map::mapped_type>& val )
98 // for BronsonAVLTreeMap
99 void operator()( typename Map::mapped_type& val )
105 virtual Deleter * clone()
107 return new Deleter( *this );
110 size_t m_nDeleteSuccess;
111 size_t m_nDeleteFailed;
114 Deleter( CppUnitMini::ThreadPool& pool, Map& rMap )
115 : CppUnitMini::TestThread( pool )
118 Deleter( Deleter& src )
119 : CppUnitMini::TestThread( src )
123 Map_InsDel_Item_string& getTest()
125 return reinterpret_cast<Map_InsDel_Item_string&>( m_Pool.m_Test );
128 virtual void init() { cds::threading::Manager::attachThread() ; }
129 virtual void fini() { cds::threading::Manager::detachThread() ; }
138 size_t nGoalItem = c_nGoalItem;
139 std::string strGoal = (*getTest().m_parrString)[nGoalItem];
141 for ( size_t nAttempt = 0; nAttempt < c_nAttemptCount; ) {
142 if ( rMap.erase( strGoal, erase_cleaner() )) {
155 void do_test( Map& testMap )
157 typedef Inserter<Map> InserterThread;
158 typedef Deleter<Map> DeleterThread;
159 cds::OS::Timer timer;
162 CPPUNIT_MSG( " Fill map (" << c_nMapSize << " items)...");
164 for ( size_t i = 0; i < c_nMapSize; ++i ) {
165 CPPUNIT_ASSERT_EX( testMap.insert( (*m_parrString)[i], i ), i );
167 CPPUNIT_MSG( " Duration=" << timer.duration() );
169 CPPUNIT_MSG( " Insert/delete the key " << c_nGoalItem << " (" << c_nAttemptCount << " successful times)...");
170 CppUnitMini::ThreadPool pool( *this );
171 pool.add( new InserterThread( pool, testMap ), (c_nThreadCount + 1) / 2 );
172 pool.add( new DeleterThread( pool, testMap ), (c_nThreadCount + 1) / 2 );
174 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
176 size_t nInsertSuccess = 0;
177 size_t nInsertFailed = 0;
178 size_t nDeleteSuccess = 0;
179 size_t nDeleteFailed = 0;
180 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
181 InserterThread * pThread = dynamic_cast<InserterThread *>( *it );
183 CPPUNIT_CHECK( pThread->m_nInsertSuccess == c_nAttemptCount );
184 nInsertSuccess += pThread->m_nInsertSuccess;
185 nInsertFailed += pThread->m_nInsertFailed;
188 DeleterThread * p = static_cast<DeleterThread *>( *it );
189 CPPUNIT_CHECK( p->m_nDeleteSuccess == c_nAttemptCount );
190 nDeleteSuccess += p->m_nDeleteSuccess;
191 nDeleteFailed += p->m_nDeleteFailed;
194 CPPUNIT_CHECK_EX( nInsertSuccess == nDeleteSuccess, "nInsertSuccess=" << nInsertSuccess << ", nDeleteSuccess=" << nDeleteSuccess );
195 CPPUNIT_MSG( " Totals: Ins fail=" << nInsertFailed << " Del fail=" << nDeleteFailed );
197 // Check if the map contains all items
198 CPPUNIT_MSG( " Check if the map contains all items" );
200 for ( size_t i = 0; i < c_nMapSize; ++i ) {
201 CPPUNIT_CHECK_EX( testMap.find( (*m_parrString)[i] ), "Key \"" << (*m_parrString)[i] << "\" not found" );
203 CPPUNIT_MSG( " Duration=" << timer.duration() );
206 additional_check( testMap );
207 print_stat( testMap );
208 additional_cleanup( testMap );
214 m_parrString = &CppUnitMini::TestCase::getTestStrings();
215 if ( c_nMapSize > m_parrString->size() )
216 c_nMapSize = m_parrString->size();
217 if ( c_nGoalItem > m_parrString->size() )
218 c_nGoalItem = m_parrString->size() / 2;
220 CPPUNIT_MSG( "Thread count= " << c_nThreadCount
221 << " pass count=" << c_nAttemptCount
222 << " map size=" << c_nMapSize
225 for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
226 CPPUNIT_MSG( "Load factor=" << nLoadFactor );
227 Map testMap( c_nMapSize, nLoadFactor );
229 if ( c_bPrintGCState )
234 template <typename Map>
237 m_parrString = &CppUnitMini::TestCase::getTestStrings();
238 if ( c_nMapSize > m_parrString->size() )
239 c_nMapSize = m_parrString->size();
240 if ( c_nGoalItem > m_parrString->size() )
241 c_nGoalItem = m_parrString->size() / 2;
243 CPPUNIT_MSG( "Thread count= " << c_nThreadCount
244 << " pass count=" << c_nAttemptCount
245 << " map size=" << c_nMapSize
250 if ( c_bPrintGCState )
254 void setUpParams( const CppUnitMini::TestCfg& cfg ) {
255 c_nThreadCount = cfg.getULong("ThreadCount", 8 ) ; // thread count
256 c_nMapSize = cfg.getULong("MapSize", 1000000 );
257 c_nGoalItem = cfg.getULong("GoalItemIndex", (unsigned long) (c_nMapSize / 2) );
258 c_nAttemptCount = cfg.getULong("AttemptCount", 100000 );
259 c_nMaxLoadFactor = cfg.getULong("MaxLoadFactor", 8 );
260 c_bPrintGCState = cfg.getBool("PrintGCStateFlag", true );
263 # include "map2/map_defs.h"
264 CDSUNIT_DECLARE_MichaelMap
265 CDSUNIT_DECLARE_SplitList
266 CDSUNIT_DECLARE_SkipListMap
267 CDSUNIT_DECLARE_EllenBinTreeMap
268 CDSUNIT_DECLARE_BronsonAVLTreeMap
269 CDSUNIT_DECLARE_StripedMap
270 CDSUNIT_DECLARE_RefinableMap
271 CDSUNIT_DECLARE_CuckooMap
272 CDSUNIT_DECLARE_StdMap
274 CPPUNIT_TEST_SUITE( Map_InsDel_Item_string )
275 CDSUNIT_TEST_MichaelMap
276 CDSUNIT_TEST_SplitList
277 CDSUNIT_TEST_SkipListMap
278 CDSUNIT_TEST_EllenBinTreeMap
279 CDSUNIT_TEST_BronsonAVLTreeMap
280 CDSUNIT_TEST_StripedMap
281 CDSUNIT_TEST_RefinableMap
282 CDSUNIT_TEST_CuckooMap
283 //CDSUNIT_TEST_StdMap // very slow!!!
284 CPPUNIT_TEST_SUITE_END()
288 CPPUNIT_TEST_SUITE_REGISTRATION( Map_InsDel_Item_string );