3 #include "map2/map_types.h"
4 #include "cppunit/thread.h"
6 #include <cds/os/topology.h>
8 #include <algorithm> // random_shuffle
12 # define TEST_MAP(X) void X() { test<MapTypes<key_type, value_type>::X >() ; }
13 # define TEST_MAP_NOLF(X) void X() { test_nolf<MapTypes<key_type, value_type>::X >() ; }
14 # define TEST_MAP_EXTRACT(X) TEST_MAP(X)
15 # define TEST_MAP_NOLF_EXTRACT(X) TEST_MAP_NOLF(X)
17 class Map_InsFind_int: public CppUnitMini::TestCase
19 static size_t c_nMapSize; // map size
20 static size_t c_nThreadCount; // count of insertion thread
21 static size_t c_nMaxLoadFactor; // maximum load factor
22 static bool c_bPrintGCState;
24 typedef CppUnitMini::TestCase Base;
25 typedef size_t key_type;
26 typedef size_t value_type;
28 template <typename Iterator, typename Map>
29 static bool check_result( Iterator const& it, Map const& map )
31 return it != map.end();
33 template <typename Map>
34 static bool check_result( bool b, Map const& )
40 class Inserter: public CppUnitMini::TestThread
43 std::vector<size_t> m_arrVal;
45 virtual Inserter * clone()
47 return new Inserter( *this );
52 size_t const nSize = c_nMapSize / c_nThreadCount + 1;
53 m_arrVal.resize( nSize );
54 size_t nItem = m_nThreadNo;
55 for ( size_t i = 0; i < nSize; nItem += c_nThreadCount, ++i )
57 std::random_shuffle( m_arrVal.begin(), m_arrVal.end() );
60 size_t m_nInsertSuccess;
61 size_t m_nInsertFailed;
62 size_t m_nFindSuccess;
66 Inserter( CppUnitMini::ThreadPool& pool, Map& rMap )
67 : CppUnitMini::TestThread( pool )
70 Inserter( Inserter& src )
71 : CppUnitMini::TestThread( src )
75 Map_InsFind_int& getTest()
77 return reinterpret_cast<Map_InsFind_int&>( m_Pool.m_Test );
82 cds::threading::Manager::attachThread();
85 virtual void fini() { cds::threading::Manager::detachThread() ; }
96 size_t const nArrSize = m_arrVal.size();
97 for ( size_t i = 0; i < nArrSize; ++i ) {
98 size_t const nItem = m_arrVal[i];
99 if ( check_result( rMap.insert( nItem, nItem * 8 ), rMap ))
104 for ( size_t k = 0; k <= i; ++k ) {
105 if ( check_result( rMap.find( m_arrVal[k] ), rMap ))
117 void do_test( Map& testMap )
119 typedef Inserter<Map> InserterThread;
120 cds::OS::Timer timer;
122 CppUnitMini::ThreadPool pool( *this );
123 pool.add( new InserterThread( pool, testMap ), c_nThreadCount );
125 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
127 size_t nInsertSuccess = 0;
128 size_t nInsertFailed = 0;
129 size_t nFindSuccess = 0;
130 size_t nFindFailed = 0;
131 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
132 InserterThread * pThread = static_cast<InserterThread *>( *it );
134 nInsertSuccess += pThread->m_nInsertSuccess;
135 nInsertFailed += pThread->m_nInsertFailed;
136 nFindSuccess += pThread->m_nFindSuccess;
137 nFindFailed += pThread->m_nFindFail;
140 CPPUNIT_MSG( " Totals: Ins succ=" << nInsertSuccess << " fail=" << nInsertFailed << "\n"
141 << " Find succ=" << nFindSuccess << " fail=" << nFindFailed
144 CPPUNIT_CHECK( nInsertFailed == 0 );
145 CPPUNIT_CHECK( nFindFailed == 0 );
147 check_before_cleanup( testMap );
150 additional_check( testMap );
151 print_stat( testMap );
152 additional_cleanup( testMap );
158 static_assert( (!std::is_same< typename Map::item_counter, cds::atomicity::empty_item_counter >::value),
159 "Empty item counter is not suitable for this test");
161 CPPUNIT_MSG( "Thread count: " << c_nThreadCount
162 << " map size=" << c_nMapSize
165 for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
166 CPPUNIT_MSG( "Load factor=" << nLoadFactor );
167 Map testMap( c_nMapSize, nLoadFactor );
169 if ( c_bPrintGCState )
177 static_assert( (!std::is_same< typename Map::item_counter, cds::atomicity::empty_item_counter >::value),
178 "Empty item counter is not suitable for this test");
180 CPPUNIT_MSG( "Thread count: " << c_nThreadCount
181 << " map size=" << c_nMapSize
186 if ( c_bPrintGCState )
190 void setUpParams( const CppUnitMini::TestCfg& cfg );
192 void run_MichaelMap(const char *in_name, bool invert = false);
193 void run_SplitList(const char *in_name, bool invert = false);
194 void run_StripedMap(const char *in_name, bool invert = false);
195 void run_RefinableMap(const char *in_name, bool invert = false);
196 void run_CuckooMap(const char *in_name, bool invert = false);
197 void run_SkipListMap(const char *in_name, bool invert = false);
198 void run_EllenBinTreeMap(const char *in_name, bool invert = false);
199 void run_BronsonAVLTreeMap(const char *in_name, bool invert = false);
200 void run_StdMap(const char *in_name, bool invert = false);
202 virtual void myRun(const char *in_name, bool invert = false);
204 # include "map2/map_defs.h"
205 CDSUNIT_DECLARE_MichaelMap
206 CDSUNIT_DECLARE_MichaelMap_nogc
207 CDSUNIT_DECLARE_SplitList
208 CDSUNIT_DECLARE_SplitList_nogc
209 CDSUNIT_DECLARE_SkipListMap
210 CDSUNIT_DECLARE_SkipListMap_nogc
211 CDSUNIT_DECLARE_EllenBinTreeMap
212 CDSUNIT_DECLARE_BronsonAVLTreeMap
213 CDSUNIT_DECLARE_StripedMap
214 CDSUNIT_DECLARE_RefinableMap
215 CDSUNIT_DECLARE_CuckooMap
216 CDSUNIT_DECLARE_StdMap