3ac134b62f445725b2373eafe22b28cc73ab53dc
[junction.git] / test / junction_driver.cpp
1 #include <junction/ConcurrentMap_Grampa.h>
2 #include <junction/ConcurrentMap_Linear.h>
3 #include <junction/ConcurrentMap_Leapfrog.h>
4 #include <junction/ConcurrentMap_Crude.h>
5 #include <iostream>
6 #include <memory>
7 #include <chrono>
8 #include <cassert>
9
10 namespace {
11
12 const unsigned s_nInsertPercentage = 10;
13 const char* kTestName = "InsDelFind";
14 // Run GC after "kGCFrequency" operations.
15 const size_t kGCFrequency = 3000;
16 const size_t kLeapfrogGCFrequency = 1500;
17
18 const size_t kCrudeMapSize = 10000;
19 const size_t kCrudePassCount = 400000;
20 const char* kCrudeBenchmarkName = "JunctionMapCrude";
21
22 const size_t kGrampaMapSize = 20000;
23 const size_t kGrampaPassCount = 30000;
24 const char* kGrampaBenchmarkName = "JunctionMapGrampa";
25
26 const size_t kLinearMapSize = 20000;
27 const size_t kLinearPassCount = 70000;
28 const char* kLinearBenchmarkName = "JunctionMapLinear";
29
30 const size_t kLeapfrogMapSize = 20000;
31 const size_t kLeapfrogPassCount = 75000;
32 const char* kLeapfrogBenchmarkName = "JunctionMapLeapfrog";
33
34 } // namespace
35
36 typedef junction::ConcurrentMap_Grampa<size_t, size_t> GrampaMap;
37 typedef junction::ConcurrentMap_Linear<size_t, size_t> LinearMap;
38 typedef junction::ConcurrentMap_Leapfrog<size_t, size_t> LeapfrogMap;
39 typedef junction::ConcurrentMap_Crude<size_t, size_t> CrudeMap;
40
41 template <typename Map>
42 void run_crude_map(size_t map_size, size_t pass_count, const char* bench_name,
43     size_t gc_frequency) {
44     std::cout << "[ RUN      ] " << kTestName << "." << bench_name << "\n";
45     auto start_time = std::chrono::system_clock::now();
46
47     size_t nInsertedNum = 0;
48     size_t nFindSuccess = 0;
49     size_t nOperations = 0;
50     // Seems like the crude map won't resize, so better have a large enough
51     // capacity.
52     std::unique_ptr<Map> map(new Map(map_size * 32));
53     auto qsbrContext = junction::DefaultQSBR.createContext();
54     for (size_t count = 0; count < pass_count; count++) {
55         for (size_t i = 0; i < map_size; ++i) {
56             // The number to operate on the map.
57             size_t n = map_size + i;
58             // Insert
59             if (i % s_nInsertPercentage == 1) {
60                 map->assign(i, n);
61                 nInsertedNum++;
62 //                std::cout << "Inserted" << i << "\n";
63             }
64             // Find
65             {
66                 if (map->get(i)) {
67                     ++nFindSuccess;
68 //                    std::cout << "Found" << i << "\n";
69                 }
70             }
71             // Delete
72             if (i % s_nInsertPercentage == 1) {
73                 if (map->get(i)) {
74                     map->assign(n, 0);
75 //                    std::cout << "Erased" << i << "\n";
76                 }
77             }
78             if (++nOperations > gc_frequency) {
79               junction::DefaultQSBR.update(qsbrContext);
80               nOperations = 0;
81             }
82         }
83     }
84     junction::DefaultQSBR.update(qsbrContext);
85     junction::DefaultQSBR.destroyContext(qsbrContext );
86     auto finish_time = std::chrono::system_clock::now();
87     auto dur = finish_time - start_time;
88     auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
89
90     if (nFindSuccess != nInsertedNum) {
91         std::cout << "nFindSuccess=" << nFindSuccess << ", nInsertedNum="
92                   << nInsertedNum << "\n";
93         std::cout << "[       FAILED ] " << kTestName << "." << bench_name
94                   << "(" << milisecs.count() << " ms)\n";
95         assert(false && "ConcurrentMap ERROR");
96     } else {
97         std::cout << "[       OK ] " << kTestName << "." << bench_name
98                   << "(" << milisecs.count() << " ms)\n";
99     }
100 }
101
102 template <typename Map>
103 void run_test(size_t map_size, size_t pass_count, const char* bench_name,
104     size_t gc_frequency) {
105     std::cout << "[ RUN      ] " << kTestName << "." << bench_name << "\n";
106     auto start_time = std::chrono::system_clock::now();
107
108     size_t nInsertedNum = 0;
109     size_t nFindSuccess = 0;
110     size_t nOperations = 0;
111     std::unique_ptr<Map> map(new Map());
112     auto qsbrContext = junction::DefaultQSBR.createContext();
113     for (size_t count = 0; count < pass_count; count++) {
114         for (size_t i = 0; i < map_size; ++i) {
115             // The number to operate on the map.
116             size_t n = map_size + i;
117             // Insert
118             if (i % s_nInsertPercentage == 1) {
119                 auto iter = map->insertOrFind(i);
120                 if (!iter.getValue()) {
121                   iter.assignValue(n);
122                   nInsertedNum++;
123 //                  std::cout << "Inserted" << i << "\n";
124                 }
125             }
126             // Find
127             {
128                 auto iter = map->find(i);
129                 if (iter.getValue()) {
130                     ++nFindSuccess;
131 //                    std::cout << "Found" << i << "\n";
132                 }
133             }
134             // Delete
135             if (i % s_nInsertPercentage == 1) {
136                 auto iter = map->find(i);
137                 if (iter.getValue()) {
138                     iter.eraseValue();
139 //                    std::cout << "Erased" << i << "\n";
140                 }
141             }
142             if (++nOperations > gc_frequency) {
143                 junction::DefaultQSBR.update(qsbrContext);
144                 nOperations = 0;
145             }
146         }
147     }
148     junction::DefaultQSBR.update(qsbrContext);
149     junction::DefaultQSBR.destroyContext(qsbrContext );
150     auto finish_time = std::chrono::system_clock::now();
151     auto dur = finish_time - start_time;
152     auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
153
154     if (nFindSuccess != nInsertedNum) {
155         std::cout << "nFindSuccess=" << nFindSuccess << ", nInsertedNum="
156                   << nInsertedNum << "\n";
157         std::cout << "[       FAILED ] " << kTestName << "." << bench_name
158                   << "(" << milisecs.count() << " ms)\n";
159         assert(false && "ConcurrentMap ERROR");
160     } else {
161         std::cout << "[       OK ] " << kTestName << "." << bench_name
162                   << "(" << milisecs.count() << " ms)\n";
163     }
164 }
165
166 int main() {
167     run_crude_map<CrudeMap>(kCrudeMapSize, kCrudePassCount, kCrudeBenchmarkName,
168         kGCFrequency);
169     run_test<LeapfrogMap>(kLeapfrogMapSize, kLeapfrogPassCount,
170         kLeapfrogBenchmarkName, kLeapfrogGCFrequency );
171     run_test<LinearMap>(kLinearMapSize, kLinearPassCount, kLinearBenchmarkName,
172         kGCFrequency);
173     run_test<GrampaMap>(kGrampaMapSize, kGrampaPassCount, kGrampaBenchmarkName,
174         kGCFrequency);
175     return 0;
176 }