Disables running some stat analysis for benchmarks & Adds some sequential data structures
[libcds.git] / test / stress / sequential / sequential-set / delodd / set_delodd.h
index 45302cd..8fc8440 100644 (file)
@@ -122,7 +122,13 @@ namespace set {
         static size_t s_nDelThreadCount;       // delete thread count
         static size_t s_nExtractThreadCount;   // extract thread count
         static size_t s_nMaxLoadFactor;        // maximum load factor
+        
+        static size_t s_nPassCount;
+        static size_t s_nFeldmanPassCount;
         static size_t s_nInsertPassCount;
+        static size_t s_nDeletePassCount;
+        static size_t s_nFindPassCount;
+
         static size_t s_nFindThreadCount;      // find thread count
 
         static size_t s_nCuckooInitialSize;    // initial size for CuckooSet
@@ -743,110 +749,137 @@ namespace set {
         }
 
         template <class Set>
-        void do_test_extract_with( Set& testSet )
-        {
-            typedef Inserter<Set> insert_thread;
-            typedef Deleter<Set> delete_thread;
-            typedef Extractor< typename Set::gc, Set > extract_thread;
-            typedef Observer<Set> observer_thread;
-
-            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
-
-            cds_test::thread_pool& pool = get_pool();
-            pool.add( new insert_thread( pool, testSet ), s_nInsThreadCount );
-            if ( s_nDelThreadCount )
-                pool.add( new delete_thread( pool, testSet ), s_nDelThreadCount );
-            if ( s_nExtractThreadCount )
-                pool.add( new extract_thread( pool, testSet ), s_nExtractThreadCount );
-            if ( s_nFindThreadCount )
-                pool.add( new observer_thread( pool, testSet ), s_nFindThreadCount );
-
-            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
-                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
-                << std::make_pair( "extract_thread_count", s_nExtractThreadCount )
-                << std::make_pair( "find_thread_count", s_nFindThreadCount )
-                << std::make_pair( "set_size", s_nSetSize )
-                << std::make_pair( "pass_count", s_nInsertPassCount );
-
-            std::chrono::milliseconds duration = pool.run();
-
-            propout() << std::make_pair( "duration", duration );
-
-            size_t nInsertInitFailed = 0;
-            size_t nInsertInitSuccess = 0;
-            size_t nInsertSuccess = 0;
-            size_t nInsertFailed = 0;
-            size_t nDeleteSuccess = 0;
-            size_t nDeleteFailed = 0;
-            size_t nExtractSuccess = 0;
-            size_t nExtractFailed = 0;
-
-            size_t nFindEvenSuccess = 0;
-            size_t nFindEvenFailed = 0;
-            size_t nFindOddSuccess = 0;
-            size_t nFindOddFailed = 0;
-
-            for ( size_t i = 0; i < pool.size(); ++i ) {
-                cds_test::thread& thr = pool.get( i );
-                switch ( thr.type()) {
-                case inserter_thread:
-                    {
-                        insert_thread& inserter = static_cast<insert_thread&>( thr );
-                        nInsertSuccess += inserter.m_nInsertSuccess;
-                        nInsertFailed += inserter.m_nInsertFailed;
-                        nInsertInitSuccess += inserter.m_nInsertInitSuccess;
-                        nInsertInitFailed += inserter.m_nInsertInitFailed;
-                    }
-                    break;
-                case deleter_thread:
-                    {
-                        delete_thread& deleter = static_cast<delete_thread&>(thr);
-                        nDeleteSuccess += deleter.m_nDeleteSuccess;
-                        nDeleteFailed += deleter.m_nDeleteFailed;
-                    }
-                    break;
-                case extractor_thread:
-                    {
-                        extract_thread& extractor = static_cast<extract_thread&>(thr);
-                        nExtractSuccess += extractor.m_nExtractSuccess;
-                        nExtractFailed += extractor.m_nExtractFailed;
-                    }
-                    break;
-                case find_thread:
-                    {
-                        observer_thread& observer = static_cast<observer_thread&>( thr );
-                        nFindEvenSuccess = observer.m_nFindEvenSuccess;
-                        nFindEvenFailed = observer.m_nFindEvenFailed;
-                        nFindOddSuccess = observer.m_nFindOddSuccess;
-                        nFindOddFailed = observer.m_nFindOddFailed;
-                    }
-                    break;
-                default:
-                    assert( false );
-                }
-            }
-
-            size_t const nInitialOddKeys = ( s_nSetSize * s_nInsThreadCount ) / 2;
-
-            EXPECT_EQ( nInsertInitFailed, 0u );
-            EXPECT_EQ( nInsertInitSuccess, s_nSetSize * s_nInsThreadCount );
-            EXPECT_EQ( nFindEvenFailed, 0u );
-            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess + nExtractSuccess );
-            EXPECT_LE( nInsertSuccess, nDeleteSuccess + nExtractSuccess );
-
-            propout()
-                << std::make_pair( "insert_init_success", nInsertInitSuccess )
-                << std::make_pair( "insert_init_failed", nInsertInitFailed )
-                << std::make_pair( "insert_success", nInsertSuccess )
-                << std::make_pair( "insert_failed", nInsertFailed )
-                << std::make_pair( "delete_success", nDeleteSuccess )
-                << std::make_pair( "delete_failed", nDeleteFailed )
-                << std::make_pair( "extract_success", nExtractSuccess )
-                << std::make_pair( "extract_failed", nExtractFailed )
-                << std::make_pair( "find_even_success", nFindEvenSuccess )
-                << std::make_pair( "find_even_failed", nFindEvenFailed )
-                << std::make_pair( "find_odd_success", nFindOddSuccess )
-                << std::make_pair( "find_odd_failed", nFindOddFailed );
+        void do_test_extract_with(Set &testSet, size_t pass_count) {
+          typedef Inserter<Set> insert_thread;
+          typedef Deleter<Set> delete_thread;
+          typedef Extractor<typename Set::gc, Set> extract_thread;
+          typedef Observer<Set> observer_thread;
+
+          size_t nInsertSuccess = 0;
+          size_t nInsertFailed = 0;
+          size_t nDeleteSuccess = 0;
+          size_t nDeleteFailed = 0;
+          size_t nExtractSuccess = 0;
+          size_t nExtractFailed = 0;
+          size_t nFindEvenSuccess = 0;
+          size_t nFindEvenFailed = 0;
+          size_t nFindOddSuccess = 0;
+          size_t nFindOddFailed = 0;
+
+          auto reset_stat = [&]() {
+            nInsertSuccess = 0;
+            nInsertFailed = 0;
+            nDeleteSuccess = 0;
+            nDeleteFailed = 0;
+            nExtractSuccess = 0;
+            nExtractFailed = 0;
+            nFindEvenSuccess = 0;
+            nFindEvenFailed = 0;
+            nFindOddSuccess = 0;
+            nFindOddFailed = 0;
+          };
+
+          auto insert_func = [&]() {
+            for (auto el : m_arrData) {
+              if (testSet.insert(key_type(el, 0)))
+                ++nInsertSuccess;
+              else
+                ++nInsertFailed;
+            }
+          };
+
+          auto delete_func = [&]() {
+            for (auto el : m_arrData) {
+              if (el & 1) {
+                if (testSet.erase(key_type(el, 0)))
+                  ++nDeleteSuccess;
+                else
+                  ++nDeleteFailed;
+              }
+            }
+          };
+
+          auto extract_func = [&]() {
+            for (auto el : m_arrData) {
+              if (el & 1) {
+                auto gp = testSet.extract(key_type(el, 0));
+                if (gp)
+                  ++nExtractSuccess;
+                else
+                  ++nExtractFailed;
+                gp.release();
+              }
+            }
+          };
+
+          auto find_func = [&]() {
+            for (size_t el : m_arrData) {
+              if (el & 1) {
+                if (testSet.contains(key_thread(el, 0)))
+                  ++nFindOddSuccess;
+                else
+                  ++nFindOddFailed;
+              } else {
+                // even keys MUST be in the map
+                if (testSet.contains(key_thread(el, 0)))
+                  ++nFindEvenSuccess;
+                else
+                  ++nFindEvenFailed;
+              }
+            }
+          };
+
+          auto test_func = [&](size_t count, std::function<void()> func) {
+            for (size_t i = 0; i < count; ++i) {
+              func();
+            }
+          };
+
+          size_t const nInitialOddKeys = s_nSetSize / 2;
+          size_t const nInitialEvenKeys = s_nSetSize / 2;
+          for (size_t nPass = 0; nPass < pass_count; ++nPass) {
+            // Start with an empty set.
+            testSet.clear();
+            reset_stat();
+
+            test_func(s_nInsertPassCount, insert_func);
+            EXPECT_EQ(nInsertSuccess, s_nSetSize);
+            reset_stat();
+
+            test_func(s_nFindPassCount, find_func);
+            EXPECT_EQ(nFindEvenFailed, 0u);
+            EXPECT_EQ(nFindOddFailed, 0u);
+            reset_stat();
+
+            test_func(s_nDeletePassCount, delete_func);
+            EXPECT_EQ(nDeleteSuccess, nInitialOddKeys);
+            reset_stat();
+
+            test_func(s_nInsertPassCount, insert_func);
+            EXPECT_EQ(nInsertSuccess, nInitialOddKeys);
+            reset_stat();
+
+            test_func(s_nDeletePassCount, extract_func);
+            EXPECT_EQ(nExtractSuccess, nInitialOddKeys);
+            reset_stat();
+
+            test_func(s_nFindPassCount, find_func);
+            EXPECT_EQ(nFindEvenFailed, 0u);
+            EXPECT_EQ(nFindOddSuccess, 0u);
+          }
+
+          //          std::chrono::duration<double> time_elapsed;
+          //          std::chrono::duration<double> time_diff;
+          //          std::chrono::time_point<std::chrono::steady_clock>
+          //          time_start;
+          //          std::chrono::time_point<std::chrono::steady_clock>
+          //          time_end;
+          //          time_start = std::chrono::steady_clock::now();
+          //          time_end = std::chrono::steady_clock::now();
+          //          time_diff = time_end - time_start;
+          //          time_elapsed = time_diff;
+          //          std::cout << "Time elapsed: " << time_elapsed.count() <<
+          //          "\n";
         }
 
         template <typename Set>
@@ -882,13 +915,12 @@ namespace set {
         }
 
         template <class Set>
-        void run_test_extract()
+        void run_test_extract(size_t pass_count = s_nPassCount)
         {
             static_assert( Set::c_bExtractSupported, "Set class must support extract() method" );
 
             Set  testSet( *this );
-            do_test_extract_with( testSet );
-            analyze( testSet );
+            do_test_extract_with( testSet, pass_count);
         }
 
         template <class Map>
@@ -908,11 +940,11 @@ namespace set {
         }
 
         template <class Set>
-        void run_test_extract()
+        void run_test_extract(size_t pass_count = s_nPassCount)
         {
             s_nLoadFactor = GetParam();
             propout() << std::make_pair( "load_factor", s_nLoadFactor );
-            Set_DelOdd::run_test_extract<Set>();
+            Set_DelOdd::run_test_extract<Set>(pass_count);
         }
 
         static std::vector<size_t> get_load_factors();