Adds parallel test case organization in CMakefile (no actual parallel test cases...
[junction.git] / test / junction_parallel_driver.cpp
1 #include <cassert>
2 #include <chrono>
3 #include <iostream>
4 #include <junction/ConcurrentMap_Crude.h>
5 #include <junction/ConcurrentMap_Grampa.h>
6 #include <junction/ConcurrentMap_Leapfrog.h>
7 #include <junction/ConcurrentMap_Linear.h>
8 #include <memory>
9
10 #include <gtest/gtest.h>
11
12 namespace junction_test {
13
14 class JunctionMapInsDelFindTest : public ::testing::Test {
15 protected:
16   typedef junction::ConcurrentMap_Grampa<size_t, size_t> GrampaMap;
17   typedef junction::ConcurrentMap_Linear<size_t, size_t> LinearMap;
18   typedef junction::ConcurrentMap_Leapfrog<size_t, size_t> LeapfrogMap;
19   typedef junction::ConcurrentMap_Crude<size_t, size_t> CrudeMap;
20
21   static const unsigned s_nInsertPercentage = 10;
22   // Run GC after "kGCFrequency" operations.
23   static const size_t kGCFrequency = 3000;
24   static const size_t kLeapfrogGCFrequency = 1500;
25
26   static const size_t kCrudeMapSize = 10000;
27   static const size_t kCrudePassCount = 400000;
28
29   static const size_t kGrampaMapSize = 20000;
30   static const size_t kGrampaPassCount = 60000;
31
32   static const size_t kLinearMapSize = 20000;
33   static const size_t kLinearPassCount = 70000;
34
35   static const size_t kLeapfrogMapSize = 20000;
36   static const size_t kLeapfrogPassCount = 75000;
37
38   static void SetUpTestCase() {}
39
40   template <typename Map>
41   static void run_test(size_t map_size, size_t pass_count,
42                        size_t gc_frequency) {
43     size_t nInsertedNum = 0;
44     size_t nFindSuccess = 0;
45     size_t nOperations = 0;
46     std::unique_ptr<Map> map(new Map());
47     auto qsbrContext = junction::DefaultQSBR.createContext();
48     for (size_t count = 0; count < pass_count; count++) {
49       for (size_t i = 0; i < map_size; ++i) {
50         // The number to operate on the map.
51         size_t n = map_size + i;
52         // Insert
53         if (i % s_nInsertPercentage == 1) {
54           auto iter = map->insertOrFind(i);
55           if (!iter.getValue()) {
56             iter.assignValue(n);
57             nInsertedNum++;
58             //                  std::cout << "Inserted" << i << "\n";
59           }
60         }
61         // Find
62         {
63           auto iter = map->find(i);
64           if (iter.getValue()) {
65             ++nFindSuccess;
66             //                    std::cout << "Found" << i << "\n";
67           }
68         }
69         // Delete
70         if (i % s_nInsertPercentage == 1) {
71           auto iter = map->find(i);
72           if (iter.getValue()) {
73             iter.eraseValue();
74             //                    std::cout << "Erased" << i << "\n";
75           }
76         }
77         if (++nOperations > gc_frequency) {
78           junction::DefaultQSBR.update(qsbrContext);
79           nOperations = 0;
80         }
81       }
82     }
83     junction::DefaultQSBR.update(qsbrContext);
84     junction::DefaultQSBR.destroyContext(qsbrContext);
85     EXPECT_EQ(nFindSuccess, nInsertedNum);
86   }
87
88   template <typename Map>
89   void run_crude_map(size_t map_size, size_t pass_count, size_t gc_frequency) {
90     size_t nInsertedNum = 0;
91     size_t nFindSuccess = 0;
92     size_t nOperations = 0;
93     // Seems like the crude map won't resize, so better have a large enough
94     // capacity.
95     std::unique_ptr<Map> map(new Map(map_size * 32));
96     auto qsbrContext = junction::DefaultQSBR.createContext();
97     for (size_t count = 0; count < pass_count; count++) {
98       for (size_t i = 0; i < map_size; ++i) {
99         // The number to operate on the map.
100         size_t n = map_size + i;
101         // Insert
102         if (i % s_nInsertPercentage == 1) {
103           map->assign(i, n);
104           nInsertedNum++;
105           //                std::cout << "Inserted" << i << "\n";
106         }
107         // Find
108         {
109           if (map->get(i)) {
110             ++nFindSuccess;
111             //                    std::cout << "Found" << i << "\n";
112           }
113         }
114         // Delete
115         if (i % s_nInsertPercentage == 1) {
116           if (map->get(i)) {
117             map->assign(n, 0);
118             //                    std::cout << "Erased" << i << "\n";
119           }
120         }
121         if (++nOperations > gc_frequency) {
122           junction::DefaultQSBR.update(qsbrContext);
123           nOperations = 0;
124         }
125       }
126     }
127     junction::DefaultQSBR.update(qsbrContext);
128     junction::DefaultQSBR.destroyContext(qsbrContext);
129
130     EXPECT_EQ(nFindSuccess, nInsertedNum);
131   }
132 };
133
134 TEST_F(JunctionMapInsDelFindTest, JunctionMapCrude) {
135   run_crude_map<CrudeMap>(kCrudeMapSize, kCrudePassCount, kGCFrequency);
136 }
137
138 TEST_F(JunctionMapInsDelFindTest, JunctionMapLeapfrog) {
139   run_test<LeapfrogMap>(kLeapfrogMapSize, kLeapfrogPassCount,
140                         kLeapfrogGCFrequency);
141 }
142
143 TEST_F(JunctionMapInsDelFindTest, JunctionMapLinear) {
144   run_test<LinearMap>(kLinearMapSize, kLinearPassCount, kGCFrequency);
145 }
146
147 TEST_F(JunctionMapInsDelFindTest, JunctionMapGrampa) {
148   run_test<GrampaMap>(kGrampaMapSize, kGrampaPassCount, kGCFrequency);
149 }
150
151 } // namespace junction_test
152
153 int main(int argc, char** argv) {
154   // Init Google test
155   ::testing::InitGoogleTest(&argc, argv);
156   int result = RUN_ALL_TESTS();
157   return 0;
158 }