Renamed MultiLevelHashSet/Map to FeldmanHashSet/Map
[libcds.git] / tests / unit / set2 / set_insdelfind.h
1 //$$CDS-header$$
2
3 #include "set2/set_type.h"
4 #include "cppunit/thread.h"
5
6 namespace set2 {
7
8 #define TEST_CASE(TAG, X)  void X();
9
10     class Set_InsDelFind: public CppUnitMini::TestCase
11     {
12     public:
13         size_t c_nSetSize = 500000;      // initial set size
14         size_t c_nThreadCount = 8;       // thread count
15         size_t c_nMaxLoadFactor = 8;     // maximum load factor
16         unsigned int c_nInsertPercentage = 5;
17         unsigned int c_nDeletePercentage = 5;
18         unsigned int c_nDuration = 30;   // test duration, seconds
19         bool c_bPrintGCState = true;
20
21         size_t  c_nCuckooInitialSize = 1024;// initial size for CuckooSet
22         size_t  c_nCuckooProbesetSize = 16; // CuckooSet probeset size (only for list-based probeset)
23         size_t  c_nCuckooProbesetThreshold = 0; // CUckooSet probeset threshold (0 - use default)
24
25         size_t c_nFeldmanSet_HeadBits = 10;
26         size_t c_nFeldmanSet_ArrayBits = 4;
27
28         size_t c_nLoadFactor = 2;
29
30     public:
31         enum actions
32         {
33             do_find,
34             do_insert,
35             do_delete
36         };
37         static const unsigned int c_nShuffleSize = 100;
38         actions m_arrShuffle[c_nShuffleSize];
39
40     protected:
41         typedef size_t  key_type;
42         typedef size_t  value_type;
43
44         template <class Set>
45         class WorkThread: public CppUnitMini::TestThread
46         {
47             Set&     m_Map;
48
49             virtual WorkThread *    clone()
50             {
51                 return new WorkThread( *this );
52             }
53         public:
54             size_t  m_nInsertSuccess;
55             size_t  m_nInsertFailed;
56             size_t  m_nDeleteSuccess;
57             size_t  m_nDeleteFailed;
58             size_t  m_nFindSuccess;
59             size_t  m_nFindFailed;
60
61         public:
62             WorkThread( CppUnitMini::ThreadPool& pool, Set& rMap )
63                 : CppUnitMini::TestThread( pool )
64                 , m_Map( rMap )
65             {}
66             WorkThread( WorkThread& src )
67                 : CppUnitMini::TestThread( src )
68                 , m_Map( src.m_Map )
69             {}
70
71             Set_InsDelFind&  getTest()
72             {
73                 return reinterpret_cast<Set_InsDelFind&>( m_Pool.m_Test );
74             }
75
76             virtual void init() { cds::threading::Manager::attachThread()   ; }
77             virtual void fini() { cds::threading::Manager::detachThread()   ; }
78
79             virtual void test()
80             {
81                 Set& rMap = m_Map;
82
83                 m_nInsertSuccess =
84                     m_nInsertFailed =
85                     m_nDeleteSuccess =
86                     m_nDeleteFailed =
87                     m_nFindSuccess =
88                     m_nFindFailed = 0;
89
90                 actions * pAct = getTest().m_arrShuffle;
91                 unsigned int i = 0;
92                 size_t const nNormalize = size_t(-1) / ( getTest().c_nSetSize * 2);
93
94                 size_t nRand = 0;
95                 while ( !time_elapsed() ) {
96                     nRand = cds::bitop::RandXorShift(nRand);
97                     size_t n = nRand / nNormalize;
98                     switch ( pAct[i] ) {
99                     case do_find:
100                         if ( rMap.contains( n ))
101                             ++m_nFindSuccess;
102                         else
103                             ++m_nFindFailed;
104                         break;
105                     case do_insert:
106                         if ( rMap.insert( n ))
107                             ++m_nInsertSuccess;
108                         else
109                             ++m_nInsertFailed;
110                         break;
111                     case do_delete:
112                         if ( rMap.erase( n ))
113                             ++m_nDeleteSuccess;
114                         else
115                             ++m_nDeleteFailed;
116                         break;
117                     }
118
119                     if ( ++i >= c_nShuffleSize )
120                         i = 0;
121                 }
122             }
123         };
124
125     protected:
126         template <class Set>
127         void do_test( Set& testSet )
128         {
129             typedef WorkThread<Set> work_thread;
130
131             // fill map - only odd number
132             {
133                 size_t * pInitArr = new size_t[ c_nSetSize ];
134                 size_t * pEnd = pInitArr + c_nSetSize;
135                 for ( size_t i = 0; i < c_nSetSize; ++i )
136                     pInitArr[i] = i * 2 + 1;
137                 shuffle( pInitArr, pEnd );
138                 for ( size_t * p = pInitArr; p < pEnd; ++p )
139                     testSet.insert( typename Set::value_type( *p, *p ) );
140                 delete [] pInitArr;
141             }
142
143             cds::OS::Timer    timer;
144
145             CppUnitMini::ThreadPool pool( *this );
146             pool.add( new work_thread( pool, testSet ), c_nThreadCount );
147             pool.run( c_nDuration );
148             CPPUNIT_MSG( "   Duration=" << pool.avgDuration() );
149
150             size_t nInsertSuccess = 0;
151             size_t nInsertFailed = 0;
152             size_t nDeleteSuccess = 0;
153             size_t nDeleteFailed = 0;
154             size_t nFindSuccess = 0;
155             size_t nFindFailed = 0;
156             for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
157                 work_thread * pThread = static_cast<work_thread *>( *it );
158                 assert( pThread != nullptr );
159                 nInsertSuccess += pThread->m_nInsertSuccess;
160                 nInsertFailed += pThread->m_nInsertFailed;
161                 nDeleteSuccess += pThread->m_nDeleteSuccess;
162                 nDeleteFailed += pThread->m_nDeleteFailed;
163                 nFindSuccess += pThread->m_nFindSuccess;
164                 nFindFailed += pThread->m_nFindFailed;
165             }
166
167             size_t nTotalOps = nInsertSuccess + nInsertFailed + nDeleteSuccess + nDeleteFailed + nFindSuccess + nFindFailed;
168
169             CPPUNIT_MSG( "  Totals (success/failed): \n\t"
170                       << "      Insert=" << nInsertSuccess << '/' << nInsertFailed << "\n\t"
171                       << "      Delete=" << nDeleteSuccess << '/' << nDeleteFailed << "\n\t"
172                       << "        Find=" << nFindSuccess   << '/' << nFindFailed   << "\n\t"
173                       << "       Speed=" << (nFindSuccess + nFindFailed) / c_nDuration << " find/sec\n\t"
174                       << "             " << (nInsertSuccess + nDeleteSuccess) / c_nDuration << " modify/sec\n\t"
175                       << "   Total ops=" << nTotalOps << "\n\t"
176                       << "       speed=" << nTotalOps / c_nDuration << " ops/sec\n\t"
177                       << "      Set size=" << testSet.size()
178                 );
179
180
181             CPPUNIT_MSG( "  Clear map (single-threaded)..." );
182             timer.reset();
183             testSet.clear();
184             CPPUNIT_MSG( "   Duration=" << timer.duration() );
185             CPPUNIT_CHECK_EX( testSet.empty(), ((long long) testSet.size()) );
186
187             additional_check( testSet );
188             print_stat( testSet );
189             additional_cleanup( testSet );
190         }
191
192         template <class Set>
193         void run_test()
194         {
195             CPPUNIT_MSG( "Thread count=" << c_nThreadCount
196                 << " initial map size=" << c_nSetSize
197                 << " insert=" << c_nInsertPercentage << '%'
198                 << " delete=" << c_nDeletePercentage << '%'
199                 << " duration=" << c_nDuration << "s"
200                 );
201
202             if ( Set::c_bLoadFactorDepended ) {
203                 for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
204                     CPPUNIT_MSG("  LoadFactor = " << c_nLoadFactor );
205                     Set s( *this );
206                     do_test( s );
207                     if ( c_bPrintGCState )
208                         print_gc_state();
209                 }
210             }
211             else {
212                 Set s( *this );
213                 do_test( s );
214                 if ( c_bPrintGCState )
215                     print_gc_state();
216             }
217         }
218
219         void setUpParams( const CppUnitMini::TestCfg& cfg );
220
221 #   include "set2/set_defs.h"
222         CDSUNIT_DECLARE_MichaelSet
223         CDSUNIT_DECLARE_SplitList
224         CDSUNIT_DECLARE_StripedSet
225         CDSUNIT_DECLARE_RefinableSet
226         CDSUNIT_DECLARE_CuckooSet
227         CDSUNIT_DECLARE_SkipListSet
228         CDSUNIT_DECLARE_EllenBinTreeSet
229         CDSUNIT_DECLARE_FeldmanHashSet
230         CDSUNIT_DECLARE_StdSet
231
232         CPPUNIT_TEST_SUITE_(Set_InsDelFind, "Map_InsDelFind")
233             CDSUNIT_TEST_MichaelSet
234             CDSUNIT_TEST_SplitList
235             CDSUNIT_TEST_SkipListSet
236             CDSUNIT_TEST_FeldmanHashSet
237             CDSUNIT_TEST_EllenBinTreeSet
238             CDSUNIT_TEST_StripedSet
239             CDSUNIT_TEST_RefinableSet
240             CDSUNIT_TEST_CuckooSet
241             CDSUNIT_TEST_StdSet
242         CPPUNIT_TEST_SUITE_END();
243
244     };
245 } // namespace set2