3 namespace junction_test {
5 class JunctionMapInsDelFindTest_Parallel : public cds_test::stress_fixture {
7 static unsigned s_nInsertPercentage;
8 static unsigned s_nDeletePercentage;
9 static size_t s_nGCFrequency; // Run GC after "s_nGCFrequency" operations.
10 static size_t s_nThreadCount;
11 static size_t s_nMapKeyRange;
12 static size_t s_nCrudeMapCapacity;
14 enum actions { do_find, do_insert, do_delete };
15 static const unsigned int kShuffleSize = 100;
16 static actions s_arrShuffle[kShuffleSize];
18 static size_t s_nCrudePassCount;
19 static size_t s_nGrampaPassCount;
20 static size_t s_nLinearPassCount;
21 static size_t s_nLeapfrogPassCount;
23 static void InitShuffleArray() {
24 // Build an array of shuffled actions.
25 EXPECT_LE(s_nInsertPercentage + s_nDeletePercentage, 100);
26 actions* pFirst = s_arrShuffle;
27 actions* pLast = s_arrShuffle + s_nInsertPercentage;
28 std::fill(pFirst, pLast, do_insert);
30 pLast += s_nDeletePercentage;
31 std::fill(pFirst, pLast, do_delete);
33 pLast = s_arrShuffle + sizeof(s_arrShuffle) / sizeof(s_arrShuffle[0]);
35 std::fill(pFirst, pLast, do_find);
37 std::random_device rd;
39 std::shuffle(s_arrShuffle, pLast, g);
42 static void SetUpTestCase() {
44 const cds_test::config& cfg = get_config("ParallelJunction");
45 GetConfigNonZeroExpected(InsertPercentage, 5);
46 GetConfigNonZeroExpected(DeletePercentage, 5);
47 GetConfigNonZeroExpected(ThreadCount, 4);
48 GetConfigNonZeroExpected(MapKeyRange, 20000);
49 // CrudeMap may need a big enough capacity in case may insertion operations
51 GetConfigNonZeroExpected(CrudeMapCapacity, s_nMapKeyRange * 1024);
52 GetConfigNonZeroExpected(GCFrequency, 1500);
53 GetConfigNonZeroExpected(CrudePassCount, 1500000000);
54 GetConfigNonZeroExpected(GrampaPassCount, 650000000);
55 GetConfigNonZeroExpected(LinearPassCount, 900000000);
56 GetConfigNonZeroExpected(LeapfrogPassCount, 850000000);
59 template <typename Map>
60 static void run_test(Map* map, size_t pass_count, size_t* inserted_num,
61 size_t* deleted_num) {
62 auto qsbrContext = junction::DefaultQSBR.createContext();
64 std::random_device rd;
65 std::mt19937 gen(rd());
66 std::uniform_int_distribution<size_t> dis(2, s_nMapKeyRange);
68 unsigned action_index = 0;
69 size_t nInsertedNum = 0;
70 size_t nDeletedNum = 0;
71 size_t nFindSuccess = 0;
72 size_t nOperations = 0;
74 for (size_t count = 0; count < pass_count; count++) {
75 // The number to operate on the map.
76 size_t key = dis(gen);
77 switch (s_arrShuffle[action_index]) {
79 size_t val = dis(gen);
80 if (map_insert(map, key, val)) {
86 if (map_delete(map, key)) {
92 if (map_find(map, key)) {
99 if (++action_index >= kShuffleSize) {
102 if (++nOperations > s_nGCFrequency) {
103 junction::DefaultQSBR.update(qsbrContext);
107 junction::DefaultQSBR.update(qsbrContext);
108 junction::DefaultQSBR.destroyContext(qsbrContext);
109 *inserted_num = nInsertedNum;
110 *deleted_num = nDeletedNum;
113 template <typename Map>
114 void JunctionThreading(Map* map, size_t pass_count) {
115 std::unique_ptr<std::thread[]> threads(new std::thread[s_nThreadCount]);
116 std::unique_ptr<size_t[]> inserted_nums(new size_t[s_nThreadCount]);
117 std::unique_ptr<size_t[]> deleted_nums(new size_t[s_nThreadCount]);
118 for (size_t i = 0; i < s_nThreadCount; i++) {
119 threads[i] = std::thread(run_test<Map>, map, pass_count,
120 &inserted_nums[i], &deleted_nums[i]);
122 size_t inserted_sum = 0;
123 size_t deleted_sum = 0;
124 for (size_t i = 0; i < s_nThreadCount; i++) {
126 inserted_sum += inserted_nums[i];
127 deleted_sum += deleted_nums[i];
129 EXPECT_LE(deleted_sum, inserted_sum);
133 size_t JunctionMapInsDelFindTest_Parallel::s_nThreadCount;
134 size_t JunctionMapInsDelFindTest_Parallel::s_nMapKeyRange;
135 size_t JunctionMapInsDelFindTest_Parallel::s_nCrudeMapCapacity;
136 size_t JunctionMapInsDelFindTest_Parallel::s_nGCFrequency;
137 unsigned JunctionMapInsDelFindTest_Parallel::s_nInsertPercentage;
138 unsigned JunctionMapInsDelFindTest_Parallel::s_nDeletePercentage;
139 const unsigned int JunctionMapInsDelFindTest_Parallel::kShuffleSize;
140 JunctionMapInsDelFindTest_Parallel::actions JunctionMapInsDelFindTest_Parallel::
141 s_arrShuffle[JunctionMapInsDelFindTest_Parallel::kShuffleSize];
142 size_t JunctionMapInsDelFindTest_Parallel::s_nCrudePassCount;
143 size_t JunctionMapInsDelFindTest_Parallel::s_nGrampaPassCount;
144 size_t JunctionMapInsDelFindTest_Parallel::s_nLinearPassCount;
145 size_t JunctionMapInsDelFindTest_Parallel::s_nLeapfrogPassCount;
147 TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapCrude) {
148 std::unique_ptr<CrudeMap> map(new CrudeMap(s_nCrudeMapCapacity));
149 JunctionThreading(map.get(), s_nCrudePassCount);
152 TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapLeapfrog) {
153 std::unique_ptr<LeapfrogMap> map(new LeapfrogMap());
154 JunctionThreading(map.get(), s_nLeapfrogPassCount);
157 TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapLinear) {
158 std::unique_ptr<LinearMap> map(new LinearMap());
159 JunctionThreading(map.get(), s_nLinearPassCount);
162 TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapGrampa) {
163 std::unique_ptr<GrampaMap> map(new GrampaMap());
164 JunctionThreading(map.get(), s_nGrampaPassCount);
167 } // namespace junction_test