5 class FollyMapInsDelFindTest_Parallel : public cds_test::stress_fixture {
7 static unsigned s_nInsertPercentage;
8 static unsigned s_nDeletePercentage;
9 static size_t s_nThreadCount;
10 static size_t s_nMapKeyRange;
11 static size_t s_nInitialMapSize;
13 enum actions { do_find, do_insert, do_delete };
14 static const unsigned int kShuffleSize = 100;
15 static actions s_arrShuffle[kShuffleSize];
17 static size_t s_nConcurrentHashMapPassCount;
18 static size_t s_nAtomicHashMapPassCount;
19 static size_t s_nAtomicUnorderedInsertMapPassCount;
21 static void InitShuffleArray() {
22 // Build an array of shuffled actions.
23 EXPECT_LE(s_nInsertPercentage + s_nDeletePercentage, 100);
24 actions* pFirst = s_arrShuffle;
25 actions* pLast = s_arrShuffle + s_nInsertPercentage;
26 std::fill(pFirst, pLast, do_insert);
28 pLast += s_nDeletePercentage;
29 std::fill(pFirst, pLast, do_delete);
31 pLast = s_arrShuffle + sizeof(s_arrShuffle) / sizeof(s_arrShuffle[0]);
33 std::fill(pFirst, pLast, do_find);
35 std::random_device rd;
37 std::shuffle(s_arrShuffle, pLast, g);
40 static void SetUpTestCase() {
42 const cds_test::config& cfg = get_config("ParallelFollyMap");
43 GetConfigNonZeroExpected(InsertPercentage, 5);
44 GetConfigNonZeroExpected(DeletePercentage, 5);
45 GetConfigNonZeroExpected(ThreadCount, 4);
46 GetConfigNonZeroExpected(MapKeyRange, 20000);
47 GetConfigNonZeroExpected(InitialMapSize, 20000);
48 GetConfigNonZeroExpected(ConcurrentHashMapPassCount, 1000);
49 GetConfigNonZeroExpected(AtomicHashMapPassCount, 1000);
50 GetConfigNonZeroExpected(AtomicUnorderedInsertMapPassCount, 1000);
53 template <typename Map>
54 static void run_test(Map* map, size_t pass_count, size_t* inserted_num,
55 size_t* deleted_num) {
56 std::random_device rd;
57 std::mt19937 gen(rd());
58 std::uniform_int_distribution<size_t> dis(2, s_nMapKeyRange);
60 unsigned action_index = 0;
61 size_t nInsertedNum = 0;
62 size_t nDeletedNum = 0;
63 size_t nFindSuccess = 0;
64 size_t nOperations = 0;
66 for (size_t count = 0; count < pass_count; count++) {
67 // The number to operate on the map.
68 size_t key = dis(gen);
69 switch (s_arrShuffle[action_index]) {
71 size_t val = dis(gen);
72 if (map_insert(map, key, val)) {
78 if (map_delete(map, key)) {
84 if (map_find(map, key)) {
91 if (++action_index >= kShuffleSize) {
95 *inserted_num = nInsertedNum;
96 *deleted_num = nDeletedNum;
100 size_t FollyMapInsDelFindTest_Parallel::s_nThreadCount;
101 size_t FollyMapInsDelFindTest_Parallel::s_nMapKeyRange;
102 size_t FollyMapInsDelFindTest_Parallel::s_nInitialMapSize;
103 unsigned FollyMapInsDelFindTest_Parallel::s_nInsertPercentage;
104 unsigned FollyMapInsDelFindTest_Parallel::s_nDeletePercentage;
105 const unsigned int FollyMapInsDelFindTest_Parallel::kShuffleSize;
106 FollyMapInsDelFindTest_Parallel::actions FollyMapInsDelFindTest_Parallel::
107 s_arrShuffle[FollyMapInsDelFindTest_Parallel::kShuffleSize];
108 size_t FollyMapInsDelFindTest_Parallel::s_nConcurrentHashMapPassCount;
109 size_t FollyMapInsDelFindTest_Parallel::s_nAtomicHashMapPassCount;
110 size_t FollyMapInsDelFindTest_Parallel::s_nAtomicUnorderedInsertMapPassCount;
112 #define FollyMapThreading(map_type, pass_count) \
113 std::unique_ptr<std::thread[]> threads(new std::thread[s_nThreadCount]); \
114 std::unique_ptr<size_t[]> inserted_nums(new size_t[s_nThreadCount]); \
115 std::unique_ptr<size_t[]> deleted_nums(new size_t[s_nThreadCount]); \
116 for (size_t i = 0; i < s_nThreadCount; i++) { \
117 threads[i] = std::thread(run_test<map_type>, map.get(), pass_count, \
118 &inserted_nums[i], &deleted_nums[i]); \
120 size_t inserted_sum = 0; \
121 size_t deleted_sum = 0; \
122 for (size_t i = 0; i < s_nThreadCount; i++) { \
124 inserted_sum += inserted_nums[i]; \
125 deleted_sum += deleted_nums[i]; \
127 EXPECT_LE(deleted_sum, inserted_sum);
129 TEST_F(FollyMapInsDelFindTest_Parallel, FollyConcurrentHashMap) {
130 std::unique_ptr<ConcurrentHashMap> map(
131 new ConcurrentHashMap(s_nInitialMapSize));
132 FollyMapThreading(ConcurrentHashMap, s_nConcurrentHashMapPassCount);
135 TEST_F(FollyMapInsDelFindTest_Parallel, FollyAtomicHashMap) {
136 std::unique_ptr<AtomicHashMap> map(
137 new AtomicHashMap(s_nInitialMapSize));
138 FollyMapThreading(AtomicHashMap, s_nAtomicHashMapPassCount);
141 TEST_F(FollyMapInsDelFindTest_Parallel, FollyAtomicUnorderedInsertMap) {
142 std::unique_ptr<AtomicUnorderedInsertMap> map(
143 new AtomicUnorderedInsertMap(s_nInitialMapSize));
144 FollyMapThreading(AtomicUnorderedInsertMap,
145 s_nAtomicUnorderedInsertMapPassCount);
148 } // namespace folly_test