Refactors folly test cases to use gtest
[folly.git] / folly / stress-test / stress-sequential-folly-map.cpp
1 #include <folly/concurrency/ConcurrentHashMap.h>
2 #include <folly/AtomicHashMap.h>
3 #include <folly/AtomicUnorderedMap.h>
4
5 #include <gtest/gtest.h>
6
7 #include <memory>
8
9 namespace {
10
11 const unsigned s_nInsertPercentage = 10;
12
13 const size_t kConcurrentHashMapSize = 10000;
14 const size_t kConcurrentHashMapPassCount = 36000;
15
16 const size_t kAtomicHashMapSize = 10000;
17 const size_t kAtomicHashMapPassCount = 250000;
18
19 const size_t kAtomicUnorderedInsertMapSize = 10000;
20 const size_t kAtomicUnorderedInsertMapPassCount = 500000;
21
22 typedef folly::ConcurrentHashMap<size_t, size_t> ConcurrentHashMap;
23 typedef folly::AtomicHashMap<size_t, size_t> AtomicHashMap;
24 typedef folly::AtomicUnorderedInsertMap64<size_t, size_t>
25     AtomicUnorderedInsertMap;
26 }
27
28 template <typename Key>
29 bool map_contains(const AtomicUnorderedInsertMap* map, Key key) {
30   return map->find(key) != map->cend();
31 }
32
33 template <typename Key>
34 bool map_contains(const ConcurrentHashMap* map, Key key) {
35   return map->find(key) != map->cend();
36 }
37
38 template <typename Map, typename Key>
39 bool map_contains(const Map* map, Key key) {
40   return map->find(key) != map->end();
41 }
42
43 template <typename Map>
44 void run_atomic_unordered_insert_map(size_t map_size, size_t pass_count) {
45     size_t nInsertedNum = 0;
46     size_t nFindSuccess = 0;
47     std::unique_ptr<Map> map(new Map(map_size));
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->find(i);
55                 if (iter != map->cend()) {
56                   if (iter->second == n) {
57                     map->emplace(i, n / 2);
58                   } else {
59                     map->emplace(i, n);
60                   }
61                 } else {
62                   map->emplace(i, n);
63                 }
64                 nInsertedNum++;
65             }
66             // Find
67             {
68                 if (map_contains(map.get(), i)) {
69                     ++nFindSuccess;
70                 }
71             }
72         }
73     }
74     EXPECT_EQ(nFindSuccess, nInsertedNum);
75 }
76
77 template <typename Map>
78 void run_atomic_hashmap(size_t map_size, size_t pass_count) {
79     size_t nInsertedNum = 0;
80     size_t nFindSuccess = 0;
81     std::unique_ptr<Map> map(new Map(map_size));
82     for (size_t count = 0; count < pass_count; count++) {
83         for (size_t i = 0; i < map_size; ++i) {
84             // The number to operate on the map.
85             size_t n = map_size + i;
86             // Insert
87             if (i % s_nInsertPercentage == 1) {
88                 auto iter = map->find(i);
89                 if (iter != map->end()) {
90                   if (iter->second == n) {
91                     iter->second = n / 2;
92                   } else {
93                     iter->second = n;
94                   }
95                 } else {
96                   map->insert({i, n});
97                 }
98                 nInsertedNum++;
99             }
100             // Find
101             {
102                 if (map_contains(map.get(), i)) {
103                     ++nFindSuccess;
104                 }
105             }
106         }
107     }
108     EXPECT_EQ(nFindSuccess, nInsertedNum);
109 }
110
111 template <typename Map>
112 void run_concurrent_hashmap(size_t map_size, size_t pass_count) {
113     size_t nInsertedNum = 0;
114     size_t nFindSuccess = 0;
115     std::unique_ptr<Map> map(new Map(map_size));
116     for (size_t count = 0; count < pass_count; count++) {
117         for (size_t i = 0; i < map_size; ++i) {
118             // The number to operate on the map.
119             size_t n = map_size + i;
120             // Insert
121             if (i % s_nInsertPercentage == 1) {
122                   auto iter = map->insert({i, n});
123                   nInsertedNum++;
124             }
125             // Find
126             {
127                 if (map_contains(map.get(), i)) {
128                     ++nFindSuccess;
129                 }
130             }
131             // Delete
132             if (i % s_nInsertPercentage == 1) {
133                 if (map_contains(map.get(), i)) {
134                     map->erase(i);
135                 }
136             }
137         }
138     }
139     EXPECT_EQ(nFindSuccess, nInsertedNum);
140 }
141
142 class FollyMapInsDelFindTest: public ::testing::Test {
143 };
144
145 TEST_F(FollyMapInsDelFindTest, FollyConcurrentHashMap) {
146   run_concurrent_hashmap<ConcurrentHashMap>(
147           kConcurrentHashMapSize,
148           kConcurrentHashMapPassCount);
149 }
150
151 TEST_F(FollyMapInsDelFindTest, FollyAtomicHashMap) {
152   run_atomic_hashmap<AtomicHashMap>(
153           kAtomicHashMapSize,
154           kAtomicHashMapPassCount);
155 }
156
157 TEST_F(FollyMapInsDelFindTest, FollyAtomicUnorderedInsertMap) {
158   run_atomic_unordered_insert_map<AtomicUnorderedInsertMap>(
159           kAtomicUnorderedInsertMapSize,
160           kAtomicUnorderedInsertMapPassCount);
161 }
162
163 int main(int argc, char** argv) {
164   // Init Google test
165   ::testing::InitGoogleTest(&argc, argv);
166   int result = RUN_ALL_TESTS();
167   return result;
168 }