1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // ResourceMap_unittest:
7*8975f5c5SAndroid Build Coastguard Worker // Unit tests for the ResourceMap template class.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include <gtest/gtest.h>
11*8975f5c5SAndroid Build Coastguard Worker #include <map>
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ResourceMap.h"
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard Worker using namespace gl;
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker namespace gl
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker template <>
GetIDValue(int id)20*8975f5c5SAndroid Build Coastguard Worker inline GLuint GetIDValue(int id)
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker return id;
23*8975f5c5SAndroid Build Coastguard Worker }
24*8975f5c5SAndroid Build Coastguard Worker template <>
GetIDValue(unsigned int id)25*8975f5c5SAndroid Build Coastguard Worker inline GLuint GetIDValue(unsigned int id)
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker return id;
28*8975f5c5SAndroid Build Coastguard Worker }
29*8975f5c5SAndroid Build Coastguard Worker } // namespace gl
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker namespace
32*8975f5c5SAndroid Build Coastguard Worker {
33*8975f5c5SAndroid Build Coastguard Worker // The resourceMap class uses a lock for "unsigned int" types to support this unit test.
34*8975f5c5SAndroid Build Coastguard Worker using LocklessType = int;
35*8975f5c5SAndroid Build Coastguard Worker using LockedType = unsigned int;
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Worker template <typename T>
AssignAndErase()38*8975f5c5SAndroid Build Coastguard Worker void AssignAndErase()
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kSize = 300;
41*8975f5c5SAndroid Build Coastguard Worker ResourceMap<size_t, T> resourceMap;
42*8975f5c5SAndroid Build Coastguard Worker std::vector<size_t> objects(kSize, 1);
43*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < kSize; ++index)
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker resourceMap.assign(index + 1, &objects[index]);
46*8975f5c5SAndroid Build Coastguard Worker }
47*8975f5c5SAndroid Build Coastguard Worker
48*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < kSize; ++index)
49*8975f5c5SAndroid Build Coastguard Worker {
50*8975f5c5SAndroid Build Coastguard Worker size_t *found = nullptr;
51*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(resourceMap.erase(index + 1, &found));
52*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(&objects[index], found);
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker
55*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
56*8975f5c5SAndroid Build Coastguard Worker }
57*8975f5c5SAndroid Build Coastguard Worker
58*8975f5c5SAndroid Build Coastguard Worker // Tests assigning slots in the map and then deleting elements.
TEST(ResourceMapTest,AssignAndEraseLockless)59*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, AssignAndEraseLockless)
60*8975f5c5SAndroid Build Coastguard Worker {
61*8975f5c5SAndroid Build Coastguard Worker AssignAndErase<LocklessType>();
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker // Tests assigning slots in the map and then deleting elements.
TEST(ResourceMapTest,AssignAndEraseLocked)64*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, AssignAndEraseLocked)
65*8975f5c5SAndroid Build Coastguard Worker {
66*8975f5c5SAndroid Build Coastguard Worker AssignAndErase<LockedType>();
67*8975f5c5SAndroid Build Coastguard Worker }
68*8975f5c5SAndroid Build Coastguard Worker
69*8975f5c5SAndroid Build Coastguard Worker template <typename T>
AssignAndClear()70*8975f5c5SAndroid Build Coastguard Worker void AssignAndClear()
71*8975f5c5SAndroid Build Coastguard Worker {
72*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kSize = 280;
73*8975f5c5SAndroid Build Coastguard Worker ResourceMap<size_t, T> resourceMap;
74*8975f5c5SAndroid Build Coastguard Worker std::vector<size_t> objects(kSize, 1);
75*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < kSize; ++index)
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker resourceMap.assign(index + 1, &objects[index]);
78*8975f5c5SAndroid Build Coastguard Worker }
79*8975f5c5SAndroid Build Coastguard Worker
80*8975f5c5SAndroid Build Coastguard Worker resourceMap.clear();
81*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
82*8975f5c5SAndroid Build Coastguard Worker }
83*8975f5c5SAndroid Build Coastguard Worker
84*8975f5c5SAndroid Build Coastguard Worker // Tests assigning slots in the map and then using clear() to free it.
TEST(ResourceMapTest,AssignAndClearLockless)85*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, AssignAndClearLockless)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker AssignAndClear<LocklessType>();
88*8975f5c5SAndroid Build Coastguard Worker }
89*8975f5c5SAndroid Build Coastguard Worker // Tests assigning slots in the map and then using clear() to free it.
TEST(ResourceMapTest,AssignAndClearLocked)90*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, AssignAndClearLocked)
91*8975f5c5SAndroid Build Coastguard Worker {
92*8975f5c5SAndroid Build Coastguard Worker AssignAndClear<LockedType>();
93*8975f5c5SAndroid Build Coastguard Worker }
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker template <typename T>
BigGrowth()96*8975f5c5SAndroid Build Coastguard Worker void BigGrowth()
97*8975f5c5SAndroid Build Coastguard Worker {
98*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kSize = 8;
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker ResourceMap<size_t, T> resourceMap;
101*8975f5c5SAndroid Build Coastguard Worker std::vector<size_t> objects;
102*8975f5c5SAndroid Build Coastguard Worker
103*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < kSize; ++index)
104*8975f5c5SAndroid Build Coastguard Worker {
105*8975f5c5SAndroid Build Coastguard Worker objects.push_back(index);
106*8975f5c5SAndroid Build Coastguard Worker }
107*8975f5c5SAndroid Build Coastguard Worker
108*8975f5c5SAndroid Build Coastguard Worker // Assign a large value.
109*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kLargeIndex = 128;
110*8975f5c5SAndroid Build Coastguard Worker objects.push_back(kLargeIndex);
111*8975f5c5SAndroid Build Coastguard Worker
112*8975f5c5SAndroid Build Coastguard Worker for (size_t &object : objects)
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker resourceMap.assign(object, &object);
115*8975f5c5SAndroid Build Coastguard Worker }
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Worker for (size_t object : objects)
118*8975f5c5SAndroid Build Coastguard Worker {
119*8975f5c5SAndroid Build Coastguard Worker size_t *found = nullptr;
120*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(resourceMap.erase(object, &found));
121*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(object, *found);
122*8975f5c5SAndroid Build Coastguard Worker }
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
125*8975f5c5SAndroid Build Coastguard Worker }
126*8975f5c5SAndroid Build Coastguard Worker
127*8975f5c5SAndroid Build Coastguard Worker // Tests growing a map more than double the size.
TEST(ResourceMapTest,BigGrowthLockless)128*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, BigGrowthLockless)
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker BigGrowth<LocklessType>();
131*8975f5c5SAndroid Build Coastguard Worker }
132*8975f5c5SAndroid Build Coastguard Worker // Tests growing a map more than double the size.
TEST(ResourceMapTest,BigGrowthLocked)133*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, BigGrowthLocked)
134*8975f5c5SAndroid Build Coastguard Worker {
135*8975f5c5SAndroid Build Coastguard Worker BigGrowth<LockedType>();
136*8975f5c5SAndroid Build Coastguard Worker }
137*8975f5c5SAndroid Build Coastguard Worker
138*8975f5c5SAndroid Build Coastguard Worker template <typename T>
QueryUnassigned()139*8975f5c5SAndroid Build Coastguard Worker void QueryUnassigned()
140*8975f5c5SAndroid Build Coastguard Worker {
141*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kSize = 8;
142*8975f5c5SAndroid Build Coastguard Worker constexpr T kZero = 0;
143*8975f5c5SAndroid Build Coastguard Worker constexpr T kIdInFlatRange = 10;
144*8975f5c5SAndroid Build Coastguard Worker constexpr T kIdOutOfFlatRange = 500;
145*8975f5c5SAndroid Build Coastguard Worker
146*8975f5c5SAndroid Build Coastguard Worker ResourceMap<size_t, T> resourceMap;
147*8975f5c5SAndroid Build Coastguard Worker std::vector<size_t> objects;
148*8975f5c5SAndroid Build Coastguard Worker
149*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < kSize; ++index)
150*8975f5c5SAndroid Build Coastguard Worker {
151*8975f5c5SAndroid Build Coastguard Worker objects.push_back(index);
152*8975f5c5SAndroid Build Coastguard Worker }
153*8975f5c5SAndroid Build Coastguard Worker
154*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(resourceMap.contains(kZero));
155*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, resourceMap.query(kZero));
156*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(resourceMap.contains(kIdOutOfFlatRange));
157*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, resourceMap.query(kIdOutOfFlatRange));
158*8975f5c5SAndroid Build Coastguard Worker
159*8975f5c5SAndroid Build Coastguard Worker for (size_t &object : objects)
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker resourceMap.assign(object, &object);
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker
164*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(UnsafeResourceMapIter(resourceMap).empty());
165*8975f5c5SAndroid Build Coastguard Worker
166*8975f5c5SAndroid Build Coastguard Worker for (size_t &object : objects)
167*8975f5c5SAndroid Build Coastguard Worker {
168*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(resourceMap.contains(object));
169*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(&object, resourceMap.query(object));
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker
172*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(resourceMap.contains(kIdInFlatRange));
173*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, resourceMap.query(kIdInFlatRange));
174*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(resourceMap.contains(kIdOutOfFlatRange));
175*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, resourceMap.query(kIdOutOfFlatRange));
176*8975f5c5SAndroid Build Coastguard Worker
177*8975f5c5SAndroid Build Coastguard Worker for (size_t object : objects)
178*8975f5c5SAndroid Build Coastguard Worker {
179*8975f5c5SAndroid Build Coastguard Worker size_t *found = nullptr;
180*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(resourceMap.erase(object, &found));
181*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(object, *found);
182*8975f5c5SAndroid Build Coastguard Worker }
183*8975f5c5SAndroid Build Coastguard Worker
184*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
185*8975f5c5SAndroid Build Coastguard Worker
186*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(resourceMap.contains(kZero));
187*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, resourceMap.query(kZero));
188*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(resourceMap.contains(kIdOutOfFlatRange));
189*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, resourceMap.query(kIdOutOfFlatRange));
190*8975f5c5SAndroid Build Coastguard Worker }
191*8975f5c5SAndroid Build Coastguard Worker
192*8975f5c5SAndroid Build Coastguard Worker // Tests querying unassigned or erased values.
TEST(ResourceMapTest,QueryUnassignedLockless)193*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, QueryUnassignedLockless)
194*8975f5c5SAndroid Build Coastguard Worker {
195*8975f5c5SAndroid Build Coastguard Worker QueryUnassigned<LocklessType>();
196*8975f5c5SAndroid Build Coastguard Worker }
197*8975f5c5SAndroid Build Coastguard Worker // Tests querying unassigned or erased values.
TEST(ResourceMapTest,QueryUnassignedLocked)198*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, QueryUnassignedLocked)
199*8975f5c5SAndroid Build Coastguard Worker {
200*8975f5c5SAndroid Build Coastguard Worker QueryUnassigned<LockedType>();
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker
ConcurrentAccess(size_t iterations,size_t idCycleSize)203*8975f5c5SAndroid Build Coastguard Worker void ConcurrentAccess(size_t iterations, size_t idCycleSize)
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker if (std::is_same_v<ResourceMapMutex, angle::NoOpMutex>)
206*8975f5c5SAndroid Build Coastguard Worker {
207*8975f5c5SAndroid Build Coastguard Worker GTEST_SKIP() << "Test skipped: Locking is disabled in build.";
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker
210*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kThreadCount = 13;
211*8975f5c5SAndroid Build Coastguard Worker
212*8975f5c5SAndroid Build Coastguard Worker ResourceMap<size_t, LockedType> resourceMap;
213*8975f5c5SAndroid Build Coastguard Worker
214*8975f5c5SAndroid Build Coastguard Worker std::array<std::thread, kThreadCount> threads;
215*8975f5c5SAndroid Build Coastguard Worker std::array<std::map<LockedType, size_t>, kThreadCount> insertedIds;
216*8975f5c5SAndroid Build Coastguard Worker
217*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < kThreadCount; ++i)
218*8975f5c5SAndroid Build Coastguard Worker {
219*8975f5c5SAndroid Build Coastguard Worker threads[i] = std::thread([&, i]() {
220*8975f5c5SAndroid Build Coastguard Worker // Each thread manipulates a different set of ids. The resource map guarantees that the
221*8975f5c5SAndroid Build Coastguard Worker // data structure itself is thread-safe, not accesses to the same id.
222*8975f5c5SAndroid Build Coastguard Worker for (size_t j = 0; j < iterations; ++j)
223*8975f5c5SAndroid Build Coastguard Worker {
224*8975f5c5SAndroid Build Coastguard Worker const LockedType id = (j % (idCycleSize / kThreadCount)) * kThreadCount + i;
225*8975f5c5SAndroid Build Coastguard Worker
226*8975f5c5SAndroid Build Coastguard Worker ASSERT_LE(id, 0xFFFFu);
227*8975f5c5SAndroid Build Coastguard Worker ASSERT_LE(j, 0xFFFFu);
228*8975f5c5SAndroid Build Coastguard Worker const size_t value = id | j << 16;
229*8975f5c5SAndroid Build Coastguard Worker
230*8975f5c5SAndroid Build Coastguard Worker size_t *valuePtr = reinterpret_cast<size_t *>(value);
231*8975f5c5SAndroid Build Coastguard Worker
232*8975f5c5SAndroid Build Coastguard Worker const size_t *queryResult = resourceMap.query(id);
233*8975f5c5SAndroid Build Coastguard Worker const bool containsResult = resourceMap.contains(id);
234*8975f5c5SAndroid Build Coastguard Worker
235*8975f5c5SAndroid Build Coastguard Worker const bool expectContains = insertedIds[i].count(id) > 0;
236*8975f5c5SAndroid Build Coastguard Worker if (expectContains)
237*8975f5c5SAndroid Build Coastguard Worker {
238*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(containsResult);
239*8975f5c5SAndroid Build Coastguard Worker const LockedType queryResultInt =
240*8975f5c5SAndroid Build Coastguard Worker static_cast<LockedType>(reinterpret_cast<size_t>(queryResult) & 0xFFFF);
241*8975f5c5SAndroid Build Coastguard Worker const size_t queryResultIteration = reinterpret_cast<size_t>(queryResult) >> 16;
242*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(queryResultInt, id);
243*8975f5c5SAndroid Build Coastguard Worker EXPECT_LT(queryResultIteration, j);
244*8975f5c5SAndroid Build Coastguard Worker
245*8975f5c5SAndroid Build Coastguard Worker size_t *erasedValue = nullptr;
246*8975f5c5SAndroid Build Coastguard Worker const bool erased = resourceMap.erase(id, &erasedValue);
247*8975f5c5SAndroid Build Coastguard Worker
248*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(erased);
249*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(erasedValue, queryResult);
250*8975f5c5SAndroid Build Coastguard Worker
251*8975f5c5SAndroid Build Coastguard Worker insertedIds[i].erase(id);
252*8975f5c5SAndroid Build Coastguard Worker }
253*8975f5c5SAndroid Build Coastguard Worker else
254*8975f5c5SAndroid Build Coastguard Worker {
255*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(containsResult);
256*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(queryResult, nullptr);
257*8975f5c5SAndroid Build Coastguard Worker
258*8975f5c5SAndroid Build Coastguard Worker resourceMap.assign(id, valuePtr);
259*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(resourceMap.contains(id));
260*8975f5c5SAndroid Build Coastguard Worker
261*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(insertedIds[i].count(id) == 0);
262*8975f5c5SAndroid Build Coastguard Worker insertedIds[i][id] = value;
263*8975f5c5SAndroid Build Coastguard Worker }
264*8975f5c5SAndroid Build Coastguard Worker }
265*8975f5c5SAndroid Build Coastguard Worker });
266*8975f5c5SAndroid Build Coastguard Worker }
267*8975f5c5SAndroid Build Coastguard Worker
268*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < kThreadCount; ++i)
269*8975f5c5SAndroid Build Coastguard Worker {
270*8975f5c5SAndroid Build Coastguard Worker threads[i].join();
271*8975f5c5SAndroid Build Coastguard Worker }
272*8975f5c5SAndroid Build Coastguard Worker
273*8975f5c5SAndroid Build Coastguard Worker // Verify that every value that is expected to be there is actually there
274*8975f5c5SAndroid Build Coastguard Worker std::map<size_t, size_t> allIds;
275*8975f5c5SAndroid Build Coastguard Worker size_t allIdsPrevSize = 0;
276*8975f5c5SAndroid Build Coastguard Worker
277*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < kThreadCount; ++i)
278*8975f5c5SAndroid Build Coastguard Worker {
279*8975f5c5SAndroid Build Coastguard Worker // Merge all the sets together. The sets are disjoint, which is verified by the ASSERT_EQ.
280*8975f5c5SAndroid Build Coastguard Worker allIds.insert(insertedIds[i].begin(), insertedIds[i].end());
281*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(allIds.size(), allIdsPrevSize + insertedIds[i].size());
282*8975f5c5SAndroid Build Coastguard Worker allIdsPrevSize = allIds.size();
283*8975f5c5SAndroid Build Coastguard Worker
284*8975f5c5SAndroid Build Coastguard Worker // Make sure every id that is expected to be there is actually there.
285*8975f5c5SAndroid Build Coastguard Worker for (auto &idValue : insertedIds[i])
286*8975f5c5SAndroid Build Coastguard Worker {
287*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(resourceMap.contains(idValue.first));
288*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(resourceMap.query(idValue.first), reinterpret_cast<size_t *>(idValue.second));
289*8975f5c5SAndroid Build Coastguard Worker }
290*8975f5c5SAndroid Build Coastguard Worker }
291*8975f5c5SAndroid Build Coastguard Worker
292*8975f5c5SAndroid Build Coastguard Worker // Verify that every value that is NOT expected to be there isn't actually there
293*8975f5c5SAndroid Build Coastguard Worker for (auto &idValue : UnsafeResourceMapIter(resourceMap))
294*8975f5c5SAndroid Build Coastguard Worker {
295*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(allIds.count(idValue.first) == 1);
296*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(idValue.second, reinterpret_cast<size_t *>(allIds[idValue.first]));
297*8975f5c5SAndroid Build Coastguard Worker }
298*8975f5c5SAndroid Build Coastguard Worker
299*8975f5c5SAndroid Build Coastguard Worker resourceMap.clear();
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker
302*8975f5c5SAndroid Build Coastguard Worker // Tests that concurrent access to thread-safe resource maps works for small ids that are mostly in
303*8975f5c5SAndroid Build Coastguard Worker // the flat map range.
TEST(ResourceMapTest,ConcurrentAccessSmallIds)304*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, ConcurrentAccessSmallIds)
305*8975f5c5SAndroid Build Coastguard Worker {
306*8975f5c5SAndroid Build Coastguard Worker ConcurrentAccess(50'000, 128);
307*8975f5c5SAndroid Build Coastguard Worker }
308*8975f5c5SAndroid Build Coastguard Worker // Tests that concurrent access to thread-safe resource maps works for a wider range of ids.
TEST(ResourceMapTest,ConcurrentAccessLargeIds)309*8975f5c5SAndroid Build Coastguard Worker TEST(ResourceMapTest, ConcurrentAccessLargeIds)
310*8975f5c5SAndroid Build Coastguard Worker {
311*8975f5c5SAndroid Build Coastguard Worker ConcurrentAccess(10'000, 20'000);
312*8975f5c5SAndroid Build Coastguard Worker }
313*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
314