1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <benchmark/benchmark.h>
17 #include "safe_map.h"
18 #include <array>
19 #include <future>
20 #include <iostream>
21 #include <thread>
22 #include <chrono>
23 #include "benchmark_log.h"
24 #include "benchmark_assert.h"
25 using namespace std;
26 using std::chrono::system_clock;
27 
28 namespace OHOS {
29 namespace {
30 
31 class BenchmarkSafeMap : public benchmark::Fixture {
32 public:
SetUp(const::benchmark::State & state)33     void SetUp(const ::benchmark::State& state) override
34     {
35     }
36 
TearDown(const::benchmark::State & state)37     void TearDown(const ::benchmark::State& state) override
38     {
39     }
40 
BenchmarkSafeMap()41     BenchmarkSafeMap()
42     {
43         Iterations(iterations);
44         Repetitions(repetitions);
45         ReportAggregatesOnly();
46     }
47 
48     ~BenchmarkSafeMap() override = default;
49 
50 protected:
51     const int32_t repetitions = 3;
52     const int32_t iterations = 50;
53 };
54 
55 const int INSERT_ONE = 1;
56 const int INSERT_TWO = 2;
57 const int INSERT_THREE = 3;
58 const int INSERT_FOUR = 4;
59 const int INSERT_FIVE = 5;
60 const int INSERT_SIX = 6;
61 
62 /*
63  * @tc.name: testUtilsCopyAndAssign001
64  * @tc.desc: single thread test the normal feature insert and erase and EnsureInsert
65  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsCopyAndAssign001)66 BENCHMARK_F(BenchmarkSafeMap, testUtilsCopyAndAssign001)(benchmark::State& state)
67 {
68     BENCHMARK_LOGD("SafeMap testUtilsCopyAndAssign001 start.");
69     while (state.KeepRunning()) {
70         SafeMap<string, int> demoData;
71         // insert new
72         demoData.Insert("A", INSERT_ONE);
73         AssertFalse(demoData.IsEmpty(), "demoData.IsEmpty() did not equal false as expected.", state);
74         AssertEqual(demoData.Size(), INSERT_ONE, "demoData.Size() did not equal INSERT_ONE as expected.", state);
75 
76         SafeMap<string, int> newdemo = demoData;
77         int tar = -1;
78         AssertTrue(newdemo.Find("A", tar), "newdemo.Find(\"A\", tar) did not equal true as expected.", state);
79         AssertEqual(INSERT_ONE, tar, "INSERT_ONE did not equal tar as expected.", state);
80 
81         tar = -1;
82         SafeMap<string, int> newdemo2;
83         newdemo2 = demoData;
84         AssertTrue(newdemo2.Find("A", tar), "newdemo2.Find(\"A\", tar) did not equal true as expected.", state);
85         AssertEqual(INSERT_ONE, tar, "INSERT_ONE did not equal tar as expected.", state);
86     }
87     BENCHMARK_LOGD("SafeMap testUtilsCopyAndAssign001 end.");
88 }
89 
90 /*
91  * @tc.name: testUtilsoperator001
92  * @tc.desc: SafeMap
93  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsoperator001)94 BENCHMARK_F(BenchmarkSafeMap, testUtilsoperator001)(benchmark::State& state)
95 {
96     BENCHMARK_LOGD("SafeMap testUtilsoperator001 start.");
97     while (state.KeepRunning()) {
98         SafeMap<string, int> demoData;
99         // insert new
100         demoData.Insert("A", INSERT_ONE);
101         AssertFalse(demoData.IsEmpty(), "demoData.IsEmpty() did not equal false as expected.", state);
102         AssertEqual(demoData.Size(), INSERT_ONE, "demoData.Size() did not equal INSERT_ONE as expected.", state);
103 
104         int valueA;
105         bool foundA = demoData.Find("A", valueA);
106         AssertTrue(foundA, "demoData.Find(\"A\", valueA) did not return true as expected.", state);
107         AssertEqual(valueA, INSERT_ONE, "Value retrieved did not equal INSERT_ONE as expected.", state);
108 
109         SafeMap<string, int> newdemo = demoData;
110         int valueNewDemoA;
111         bool foundNewDemoA = newdemo.Find("A", valueNewDemoA);
112         AssertTrue(foundNewDemoA, "newdemo.Find(\"A\", valueNewDemoA) did not return true as expected.", state);
113         AssertEqual(valueNewDemoA, INSERT_ONE, "Value retrieved did not equal INSERT_ONE as expected.", state);
114 
115         int tar = -1;
116         newdemo.Insert("B", INSERT_SIX);
117         bool foundB = newdemo.Find("B", tar);
118         AssertTrue(foundB, "newdemo.Find(\"B\", tar) did not return true as expected.", state);
119         AssertEqual(INSERT_SIX, tar, "INSERT_SIX did not equal tar as expected.", state);
120 
121         SafeMap<string, int> newdemo2;
122         newdemo2 = newdemo;
123         int valueNewDemo2A;
124         bool foundNewDemo2A = newdemo2.Find("A", valueNewDemo2A);
125         AssertTrue(foundNewDemo2A, "newdemo2.Find(\"A\", valueNewDemo2A) did not return true as expected.", state);
126         AssertEqual(valueNewDemo2A, INSERT_ONE, "Value retrieved did not equal INSERT_ONE as expected.", state);
127     }
128     BENCHMARK_LOGD("SafeMap testUtilsoperator001 end.");
129 }
130 
131 /*
132  * @tc.name: testUtilsNormalFeatureInsert001
133  * @tc.desc: SafeMap
134  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsNormalFeatureInsert001)135 BENCHMARK_F(BenchmarkSafeMap, testUtilsNormalFeatureInsert001)(benchmark::State& state)
136 {
137     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureInsert001 start.");
138     while (state.KeepRunning()) {
139         SafeMap<string, int> demoData;
140         AssertTrue(demoData.IsEmpty(), "demoData.IsEmpty() did not equal true as expected.", state);
141 
142         // insert new
143         demoData.Insert("A", INSERT_ONE);
144         AssertFalse(demoData.IsEmpty(), "demoData.IsEmpty() did not equal false as expected.", state);
145         AssertEqual(demoData.Size(), INSERT_ONE, "demoData.Size() did not equal INSERT_ONE as expected.", state);
146 
147         // insert copy one should fail
148         AssertFalse(demoData.Insert("A", INSERT_TWO),
149             "demoData.Insert(\"A\", INSERT_TWO) did not equal false as expected.", state);
150         AssertEqual(demoData.Size(), INSERT_ONE, "demoData.Size() did not equal INSERT_ONE as expected.", state);
151     }
152     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureInsert001 end.");
153 }
154 
155 /*
156  * @tc.name: testUtilsNormalFeatureEnsureInsert001
157  * @tc.desc: SafeMap
158  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsNormalFeatureEnsureInsert001)159 BENCHMARK_F(BenchmarkSafeMap, testUtilsNormalFeatureEnsureInsert001)(benchmark::State& state)
160 {
161     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureEnsureInsert001 start.");
162     while (state.KeepRunning()) {
163         SafeMap<string, int> demoData;
164         AssertTrue(demoData.IsEmpty(), "demoData.IsEmpty() did not equal true as expected.", state);
165 
166         demoData.Insert("A", INSERT_ONE);
167         demoData.EnsureInsert("B", INSERT_TWO);
168 
169         AssertFalse(demoData.IsEmpty(), "demoData.IsEmpty() did not equal false as expected.", state);
170         AssertEqual(demoData.Size(), INSERT_TWO, "demoData.Size() did not equal INSERT_TWO as expected.", state);
171 
172         // insert copy one and new one
173         demoData.EnsureInsert("B", INSERT_FIVE);
174         demoData.EnsureInsert("C", INSERT_SIX);
175         AssertEqual(demoData.Size(), INSERT_THREE, "demoData.Size() did not equal INSERT_THREE as expected.", state);
176     }
177     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureEnsureInsert001 end.");
178 }
179 
180 /*
181  * @tc.name: testUtilsNormalFeatureFind001
182  * @tc.desc: SafeMap
183  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsNormalFeatureFind001)184 BENCHMARK_F(BenchmarkSafeMap, testUtilsNormalFeatureFind001)(benchmark::State& state)
185 {
186     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureFind001 start.");
187     while (state.KeepRunning()) {
188         SafeMap<string, int> demoData;
189         AssertTrue(demoData.IsEmpty(), "demoData.IsEmpty() did not equal true as expected.", state);
190 
191         demoData.Insert("A", INSERT_ONE);
192         demoData.Insert("B", 10000);
193         demoData.EnsureInsert("B", INSERT_TWO);
194         demoData.EnsureInsert("C", INSERT_SIX);
195 
196         AssertFalse(demoData.IsEmpty(), "demoData.IsEmpty() did not equal false as expected.", state);
197         AssertEqual(demoData.Size(), INSERT_THREE, "demoData.Size() did not equal INSERT_THREE as expected.", state);
198 
199         int i = 0;
200         AssertTrue(demoData.Find("A", i), "demoData.Find(\"A\", i) did not equal true as expected.", state);
201         AssertEqual(i, INSERT_ONE, "i did not equal INSERT_ONE as expected.", state);
202         AssertTrue(demoData.Find("B", i), "demoData.Find(\"B\", i) did not equal true as expected.", state);
203         AssertEqual(i, INSERT_TWO, "i did not equal INSERT_TWO as expected.", state);
204 
205         AssertTrue(demoData.Find("C", i), "demoData.Find(\"C\", i) did not equal true as expected.", state);
206         AssertEqual(i, INSERT_SIX, "i did not equal INSERT_SIX as expected.", state);
207     }
208     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureFind001 end.");
209 }
210 
211 /*
212  * @tc.name: testUtilsNormalFeatureFindAndSet001
213  * @tc.desc: SafeMap
214  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsNormalFeatureFindAndSet001)215 BENCHMARK_F(BenchmarkSafeMap, testUtilsNormalFeatureFindAndSet001)(benchmark::State& state)
216 {
217     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureFindAndSet001 start.");
218     while (state.KeepRunning()) {
219         SafeMap<string, int> demoData;
220         AssertTrue(demoData.IsEmpty(), "demoData.IsEmpty() did not equal true as expected.", state);
221 
222         demoData.Insert("A", INSERT_ONE);
223         demoData.EnsureInsert("B", INSERT_TWO);
224 
225         int oldvalue = 0;
226         int newvalue = 3;
227         AssertTrue(demoData.FindOldAndSetNew("A", oldvalue, newvalue),
228             "demoData.FindOldAndSetNew(\"A\", oldvalue, newvalue) did not equal true as expected.", state);
229 
230         // old value
231         AssertEqual(oldvalue, INSERT_ONE, "oldvalue did not equal INSERT_ONE as expected.", state);
232 
233         newvalue = 4;
234         AssertTrue(demoData.FindOldAndSetNew("B", oldvalue, newvalue),
235             "demoData.FindOldAndSetNew(\"B\", oldvalue, newvalue) did not equal true as expected.", state);
236 
237         // old value
238         AssertEqual(oldvalue, INSERT_TWO, "oldvalue did not equal INSERT_TWO as expected.", state);
239 
240         int i = -1;
241         AssertTrue(demoData.Find("A", i), "demoData.Find(\"A\", i) did not equal true as expected.", state);
242 
243         // new value
244         AssertEqual(i, INSERT_THREE, "i did not equal INSERT_THREE as expected.", state);
245         AssertTrue(demoData.Find("B", i), "demoData.Find(\"B\", i) did not equal true as expected.", state);
246 
247         // new value
248         AssertEqual(i, INSERT_FOUR, "i did not equal INSERT_FOUR as expected.", state);
249     }
250     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureFindAndSet001 end.");
251 }
252 
253 /*
254  * @tc.name: testUtilsNormalFeatureEraseAndClear001
255  * @tc.desc: SafeMap
256  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsNormalFeatureEraseAndClear001)257 BENCHMARK_F(BenchmarkSafeMap, testUtilsNormalFeatureEraseAndClear001)(benchmark::State& state)
258 {
259     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureEraseAndClear001 start.");
260     while (state.KeepRunning()) {
261         SafeMap<string, int> demoData;
262         AssertTrue(demoData.IsEmpty(), "demoData.IsEmpty() did not equal true as expected.", state);
263 
264         demoData.Insert("A", INSERT_ONE);
265         demoData.EnsureInsert("B", INSERT_TWO);
266 
267         AssertEqual(demoData.Size(), INSERT_TWO, "demoData.Size() did not equal INSERT_TWO as expected.", state);
268         demoData.Erase("A");
269         AssertEqual(demoData.Size(), INSERT_ONE, "demoData.Size() did not equal INSERT_ONE as expected.", state);
270 
271         demoData.Clear();
272         AssertEqual(demoData.Size(), 0, "demoData.Size() did not equal 0 as expected.", state);
273     }
274     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureEraseAndClear001 end.");
275 }
276 
277 /*
278  * @tc.name: testUtilsNormalFeatureIterate001
279  * @tc.desc: Using Iterate to change the second parameter of SafeMap
280  */
Callback(const std::string str,int & value)281 void Callback(const std::string str, int& value)
282 {
283     value++;
284 }
285 
BENCHMARK_F(BenchmarkSafeMap,testUtilsNormalFeatureIterate001)286 BENCHMARK_F(BenchmarkSafeMap, testUtilsNormalFeatureIterate001)(benchmark::State& state)
287 {
288     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureIterate001 start.");
289     while (state.KeepRunning()) {
290         SafeMap<string, int> demoData;
291         AssertTrue(demoData.IsEmpty(), "demoData.IsEmpty() did not equal true as expected.", state);
292 
293         demoData.Insert("A", INSERT_ONE);
294         demoData.Insert("B", INSERT_TWO);
295         demoData.Insert("C", INSERT_THREE);
296         demoData.Insert("D", INSERT_FOUR);
297         demoData.Iterate(Callback);
298 
299         AssertEqual(demoData.Size(), INSERT_FOUR, "demoData.Size() did not equal INSERT_FOUR as expected.", state);
300 
301         int valueA;
302         bool foundA = demoData.Find("A", valueA);
303         AssertTrue(foundA, "Key \"A\" was not found as expected.", state);
304         AssertEqual(valueA, INSERT_TWO, "Value for key \"A\" did not equal INSERT_TWO as expected.", state);
305 
306         int valueB;
307         bool foundB = demoData.Find("B", valueB);
308         AssertTrue(foundB, "Key \"B\" was not found as expected.", state);
309         AssertEqual(valueB, INSERT_THREE, "Value for key \"B\" did not equal INSERT_THREE as expected.", state);
310 
311         int valueC;
312         bool foundC = demoData.Find("C", valueC);
313         AssertTrue(foundC, "Key \"C\" was not found as expected.", state);
314         AssertEqual(valueC, INSERT_FOUR, "Value for key \"C\" did not equal INSERT_FOUR as expected.", state);
315 
316         int valueD;
317         bool foundD = demoData.Find("D", valueD);
318         AssertTrue(foundD, "Key \"D\" was not found as expected.", state);
319         AssertEqual(valueD, INSERT_FIVE, "Value for key \"D\" did not equal INSERT_FIVE as expected.", state);
320     }
321     BENCHMARK_LOGD("SafeMap testUtilsNormalFeatureIterate001 end.");
322 }
323 
324 /*
325  * @tc.name: testSafeMapConstructor001
326  * @tc.desc: SafeMapConstructor
327  */
BENCHMARK_F(BenchmarkSafeMap,testSafeMapConstructor001)328 BENCHMARK_F(BenchmarkSafeMap, testSafeMapConstructor001)(benchmark::State& state)
329 {
330     BENCHMARK_LOGD("SafeMap testSafeMapConstructor001 start.");
331     while (state.KeepRunning()) {
332         SafeMap<string, int> demoData;
333 
334         bool result = demoData.Insert("ONE", INSERT_ONE);
335         AssertEqual(result, true, "result did not equal true as expected.", state);
336         result = demoData.Insert("TWO", INSERT_TWO);
337         AssertEqual(result, true, "result did not equal true as expected.", state);
338 
339         SafeMap<string, int> demoData1(demoData);
340         int valueOne;
341         int valueTwo;
342         bool foundOne = demoData1.Find("ONE", valueOne);
343         bool foundTwo = demoData1.Find("TWO", valueTwo);
344         AssertTrue(foundOne && foundTwo, "Not all keys were found as expected.", state);
345         AssertEqual(valueOne, INSERT_ONE, "Value for key \"ONE\" did not match as expected.", state);
346         AssertEqual(valueTwo, INSERT_TWO, "Value for key \"TWO\" did not match as expected.", state);
347     }
348     BENCHMARK_LOGD("SafeMap testSafeMapConstructor001 end.");
349 }
350 
351 /*
352  * @tc.name: testSafeMapOperator001
353  * @tc.desc: SafeMapConstructor
354  */
BENCHMARK_F(BenchmarkSafeMap,testSafeMapOperator001)355 BENCHMARK_F(BenchmarkSafeMap, testSafeMapOperator001)(benchmark::State& state)
356 {
357     BENCHMARK_LOGD("SafeMap testSafeMapOperator001 start.");
358     while (state.KeepRunning()) {
359         SafeMap<string, int> demoData;
360 
361         bool result = demoData.Insert("ONE", INSERT_ONE);
362         AssertEqual(result, true, "result did not equal true as expected.", state);
363         result = demoData.Insert("TWO", INSERT_TWO);
364         AssertEqual(result, true, "result did not equal true as expected.", state);
365 
366         int valueOne;
367         int valueTwo;
368         bool foundOne = demoData.Find("ONE", valueOne);
369         bool foundTwo = demoData.Find("TWO", valueTwo);
370         AssertTrue(foundOne, "Key \"ONE\" was not found as expected.", state);
371         AssertTrue(foundTwo, "Key \"TWO\" was not found as expected.", state);
372         AssertEqual(valueOne, INSERT_ONE, "Value for key \"ONE\" did not equal INSERT_ONE as expected.", state);
373         AssertEqual(valueTwo, INSERT_TWO, "Value for key \"TWO\" did not equal INSERT_TWO as expected.", state);
374     }
375     BENCHMARK_LOGD("SafeMap testSafeMapOperator001 end.");
376 }
377 
378 /*
379  * @tc.name: testSafeMapOperator002
380  * @tc.desc: SafeMapConstructor
381  */
BENCHMARK_F(BenchmarkSafeMap,testSafeMapOperator002)382 BENCHMARK_F(BenchmarkSafeMap, testSafeMapOperator002)(benchmark::State& state)
383 {
384     BENCHMARK_LOGD("SafeMap testSafeMapOperator002 start.");
385     while (state.KeepRunning()) {
386         SafeMap<string, int> demoData;
387 
388         bool result = demoData.Insert("ONE", INSERT_ONE);
389         AssertEqual(result, true, "result did not equal true as expected.", state);
390 
391         SafeMap<string, int> demoData1;
392         result = demoData1.Insert("TWO", INSERT_ONE);
393         AssertEqual(result, true, "result did not equal true as expected.", state);
394 
395         int valueDemoData;
396         int valueDemoData1;
397         bool foundDemoData = demoData.Find("ONE", valueDemoData);
398         bool foundDemoData1 = demoData1.Find("TWO", valueDemoData1);
399         BENCHMARK_LOGD("SafeMap data1:%{public}d data2:%{public}d", foundDemoData, foundDemoData1);
400         AssertEqual(valueDemoData, valueDemoData1,
401             "Values for keys \"ONE\" in demoData and demoData1 did not match as expected.", state);
402     }
403     BENCHMARK_LOGD("SafeMap testSafeMapOperator002 end.");
404 }
405 
406 /*
407  * @tc.name: testUtilsConcurrentIterate001
408  * @tc.desc: 10 threads test in iterate operation to rewrite a SafeMap.
409  */
410 const int SLEEP_FOR_FIFTY_MILLISECOND = 50;
411 const int THREAD_NUM = 10;
412 const int DATA_NUM = 5;
BENCHMARK_F(BenchmarkSafeMap,testUtilsConcurrentIterate001)413 BENCHMARK_F(BenchmarkSafeMap, testUtilsConcurrentIterate001)(benchmark::State& state)
414 {
415     BENCHMARK_LOGD("SafeMap testUtilsConcurrentIterate001 start.");
416     while (state.KeepRunning()) {
417         SafeMap<string, int> demoData;
418         for (int i = 0; i < DATA_NUM; i++) {
419             demoData.Insert("A" + std::to_string(i), 0);
420         }
421         std::thread threads[THREAD_NUM];
422 
423         auto lamfuncIterate = [](SafeMap<string, int>& data, const int& cnt,
424             std::chrono::time_point<std::chrono::high_resolution_clock> absTime) {
425             auto callback_it = [cnt](const string data, int& value) {
426                 value = cnt;
427             };
428             std::this_thread::sleep_until(absTime);
429             data.Iterate(callback_it);
430         };
431 
432         auto timeT = std::chrono::high_resolution_clock::now();
433         timeT += std::chrono::milliseconds(SLEEP_FOR_FIFTY_MILLISECOND);
434 
435         for (int i = 0; i < THREAD_NUM; ++i) {
436             threads[i] = std::thread(lamfuncIterate, std::ref(demoData), i, timeT);
437         }
438 
439         for (auto& t : threads) {
440             t.join();
441         }
442 
443         for (int i = 0; i < DATA_NUM - 1; i++) {
444             int valueCurrent;
445             int valueNext;
446             bool foundCurrent = demoData.Find("A" + std::to_string(i), valueCurrent);
447             bool foundNext = demoData.Find("A" + std::to_string(i + 1), valueNext);
448 
449             AssertTrue(foundCurrent && foundNext, "Not all keys were found as expected.", state);
450             AssertEqual(valueCurrent, valueNext,
451                 ("Values for keys \"A" + std::to_string(i) + "\" and \"A" + std::to_string(i + 1) +
452                 "\" did not match as expected.").c_str(), state);
453         }
454     }
455     BENCHMARK_LOGD("SafeMap testUtilsConcurrentIterate001 end.");
456 }
457 
458 /*
459  * @tc.name: testUtilsConcurrentWriteAndRead001
460  * @tc.desc: 100 threads test in writein to the same key of the map, while read at same time  and no throw
461  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsConcurrentWriteAndRead001)462 BENCHMARK_F(BenchmarkSafeMap, testUtilsConcurrentWriteAndRead001)(benchmark::State& state)
463 {
464     BENCHMARK_LOGD("SafeMap testUtilsConcurrentWriteAndRead001 start.");
465     SafeMap<string, int> demoData;
466     std::thread threads[THREAD_NUM];
467     std::thread checkThread[THREAD_NUM];
468     while (state.KeepRunning()) {
469         auto lamfuncInsert = [](SafeMap<string, int>& data, const string& key,
470             const int& value, std::chrono::time_point<std::chrono::high_resolution_clock> absTime) {
471             std::this_thread::sleep_until(absTime);
472             data.EnsureInsert(key, value);
473         };
474 
475         auto lamfuncCheck = [](SafeMap<string, int>& data, const string& key,
476             std::chrono::time_point<std::chrono::high_resolution_clock> absTime) {
477             std::this_thread::sleep_until(absTime);
478             thread_local int i = -1;
479             data.Find(key, i);
480         };
481 
482         auto timeT = std::chrono::high_resolution_clock::now();
483         timeT += std::chrono::milliseconds(SLEEP_FOR_FIFTY_MILLISECOND);
484         string key("A");
485 
486         for (int i = 0; i < THREAD_NUM; ++i) {
487             threads[i] = std::thread(lamfuncInsert, std::ref(demoData), key, i, timeT);
488             checkThread[i] = std::thread(lamfuncCheck, std::ref(demoData), key, timeT);
489         }
490 
491         for (auto& t : threads) {
492             t.join();
493         }
494 
495         for (auto& t : checkThread) {
496             t.join();
497         }
498     }
499     BENCHMARK_LOGD("SafeMap testUtilsConcurrentWriteAndRead001 end.");
500 }
501 
ClearAllContainer(SafeMap<string,int> & demoData,std::vector<std::future<int>> & vcfi,vector<int> & result)502 void ClearAllContainer(SafeMap<string, int>& demoData, std::vector<std::future<int>>& vcfi, vector<int>& result)
503 {
504     demoData.Clear();
505     result.clear();
506     vcfi.clear();
507 }
508 
509 /*
510  * @tc.name: testUtilsConcurrentWriteAndFind001
511  * @tc.desc: 100 threads test in writein to the corresponding key of the map,
512  * while read at same time  and check the results
513  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsConcurrentWriteAndFind001)514 BENCHMARK_F(BenchmarkSafeMap, testUtilsConcurrentWriteAndFind001)(benchmark::State& state)
515 {
516     BENCHMARK_LOGD("SafeMap testUtilsConcurrentWriteAndFind001 start.");
517     SafeMap<string, int> demoData;
518     std::thread threads[THREAD_NUM];
519     std::vector<std::future<int>> vcfi;
520     while (state.KeepRunning()) {
521         auto lamfuncInsert = [](SafeMap<string, int>& data, const string& key, const int& value,
522             std::chrono::time_point<std::chrono::high_resolution_clock> absTime) {
523             std::this_thread::sleep_until(absTime);
524             data.EnsureInsert(key, value);
525         };
526         auto lamfuncCheckLoop = [](SafeMap<string, int>& data, const string& key,
527             std::chrono::time_point<std::chrono::high_resolution_clock> absTime) {
528             std::this_thread::sleep_until(absTime);
529             thread_local int i = -1;
530             while (!data.Find(key, i)) {
531                 std::this_thread::sleep_for(std::chrono::microseconds(10));
532             }
533             return i;
534         };
535         auto timeT = std::chrono::high_resolution_clock::now();
536         timeT += std::chrono::milliseconds(SLEEP_FOR_FIFTY_MILLISECOND);
537         string key("A");
538         for (int i = 0; i < THREAD_NUM; ++i) {
539             threads[i] = std::thread(lamfuncInsert, std::ref(demoData), key + std::to_string(i), i, timeT);
540             vcfi.push_back(std::async(std::launch::async, lamfuncCheckLoop,
541                 std::ref(demoData), key + std::to_string(i), timeT));
542         }
543         for (auto& t : threads) {
544             t.join();
545         }
546         vector<int> result;
547         for (auto& t : vcfi) {
548             result.push_back(t.get());
549         }
550         std::sort(result.begin(), result.end());
551         for (int i = 0; i < THREAD_NUM; ++i) {
552             AssertEqual(i, result[i], "tmp did not equal result[i+10] as expected.", state);
553         }
554         ClearAllContainer(demoData, vcfi, result);
555     }
556     BENCHMARK_LOGD("SafeMap testUtilsConcurrentWriteAndFind001 end.");
557 }
558 
559 /*
560  * @tc.name: testUtilsConcurrentWriteAndFindAndSet001
561  * @tc.desc: 100 threads test in writein to the corresponding key of the map,
562  * while findandfix at same time  and check the results
563  */
BENCHMARK_F(BenchmarkSafeMap,testUtilsConcurrentWriteAndFindAndSet001)564 BENCHMARK_F(BenchmarkSafeMap, testUtilsConcurrentWriteAndFindAndSet001)(benchmark::State& state)
565 {
566     SafeMap<string, int> demoData;
567     std::thread threads[THREAD_NUM];
568     std::vector<std::future<int>> vcfi;
569     while (state.KeepRunning()) {
570         auto lamfuncInsert = [](SafeMap<string, int>& data, const string& key,
571             const int& value, std::chrono::time_point<std::chrono::high_resolution_clock> absTime) {
572             std::this_thread::sleep_until(absTime);
573             data.EnsureInsert(key, value);
574         };
575         auto lamfuncCheckLoop = [](SafeMap<string, int>& data, const string& key,
576             const int& newvalue, std::chrono::time_point<std::chrono::high_resolution_clock> absTime) {
577             std::this_thread::sleep_until(absTime);
578             thread_local int i = -1;
579             while (!data.FindOldAndSetNew(key, i, newvalue)) {
580                 std::this_thread::sleep_for(std::chrono::microseconds(10));
581             }
582             return i;
583         };
584         auto timeT = std::chrono::high_resolution_clock::now();
585         timeT += std::chrono::milliseconds(SLEEP_FOR_FIFTY_MILLISECOND);
586         string key("A");
587         for (int i = 0; i < THREAD_NUM; ++i) {
588             threads[i] = std::thread(lamfuncInsert, std::ref(demoData),
589                 key + std::to_string(i), i, timeT);
590             vcfi.push_back(std::async(std::launch::async, lamfuncCheckLoop,
591                 std::ref(demoData), key + std::to_string(i), i + 1, timeT));
592         }
593         for (auto& t : threads)
594             t.join();
595         vector<int> result;
596         for (auto& t : vcfi)
597             result.push_back(t.get());
598         std::sort(result.begin(), result.end());
599         for (int i = 0; i < THREAD_NUM; ++i) {
600             AssertEqual(i, result[i], "i did not equal result[i] as expected.", state);
601         }
602         result.clear();
603         for (int i = 0; i < THREAD_NUM; ++i) {
604             int t = -1;
605             AssertTrue((demoData.Find("A" + std::to_string(i), t)), "demoData.Find did not equal true.", state);
606             result.push_back(t);
607         }
608         std::sort(result.begin(), result.end());
609         for (int i = 0; i < THREAD_NUM; ++i) {
610             AssertEqual(i + 1, result[i], "i + 1 did not equal result[i] as expected.", state);
611         }
612         ClearAllContainer(demoData, vcfi, result);
613     }
614 }
615 }  // namespace
616 }  // namespace OHOS
617 // Run the benchmark
618 BENCHMARK_MAIN();
619