1 /**
2 * Copyright (c) 2021-2024 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 "util/obj_pool.h"
17
18 #include <gtest/gtest.h>
19
20 #include <vector>
21
22 namespace ark::verifier::test {
23
24 namespace {
25
26 struct S {
27 int a;
28 int b;
29 };
30
31 template <typename I, typename C>
32 struct Pool : public ObjPool<S, std::vector, I, C> {
Poolark::verifier::test::__anon222b91f00111::Pool33 Pool(I i, C c) : ObjPool<S, std::vector, I, C> {i, c} {}
34 };
35
36 } // namespace
37
38 template <typename I, typename C>
VerifierTestObjPool1(Pool<I,C> & pool,int & result)39 static void VerifierTestObjPool1(Pool<I, C> &pool, int &result)
40 {
41 {
42 auto q = pool.New();
43 auto p = pool.New();
44 EXPECT_EQ(pool.Count(), 2U);
45 EXPECT_EQ(pool.FreeCount(), 0U);
46 EXPECT_EQ(pool.AccCount(), 2U);
47 EXPECT_EQ(result, 1U);
48 }
49
50 EXPECT_EQ(pool.Count(), 2U);
51 EXPECT_EQ(pool.FreeCount(), 2U);
52 EXPECT_EQ(pool.AccCount(), 0U);
53 EXPECT_EQ(result, 0U);
54
55 {
56 auto q = pool.New();
57 auto w = pool.New();
58 EXPECT_EQ(pool.Count(), 2U);
59 EXPECT_EQ(pool.FreeCount(), 0U);
60 EXPECT_EQ(pool.AccCount(), 2U);
61 EXPECT_EQ(result, 1U);
62 }
63
64 {
65 auto q = pool.New();
66 auto w = pool.New();
67 EXPECT_EQ(pool.Count(), 2U);
68 EXPECT_EQ(pool.FreeCount(), 0U);
69 EXPECT_EQ(pool.AccCount(), 2U);
70 EXPECT_EQ(result, 1U);
71 {
72 auto p = pool.New();
73 EXPECT_EQ(pool.Count(), 3U);
74 EXPECT_EQ(pool.FreeCount(), 0U);
75 EXPECT_EQ(pool.AccCount(), 3U);
76 EXPECT_EQ(result, 3U);
77 }
78 EXPECT_EQ(pool.Count(), 3U);
79 EXPECT_EQ(pool.FreeCount(), 1U);
80 EXPECT_EQ(pool.AccCount(), 2U);
81 EXPECT_EQ(result, 1U);
82 {
83 auto p = pool.New();
84 EXPECT_EQ(pool.Count(), 3U);
85 EXPECT_EQ(pool.FreeCount(), 0U);
86 EXPECT_EQ(pool.AccCount(), 3U);
87 EXPECT_EQ(result, 3U);
88 }
89 }
90 }
91
92 template <typename I, typename C>
VerifierTestObjPool2(Pool<I,C> & pool,int & result)93 static void VerifierTestObjPool2(Pool<I, C> &pool, int &result)
94 {
95 EXPECT_EQ(pool.Count(), 3U);
96 EXPECT_EQ(pool.FreeCount(), 3U);
97 EXPECT_EQ(pool.AccCount(), 0U);
98 EXPECT_EQ(result, 0U);
99
100 {
101 auto q = pool.New();
102 auto w = pool.New();
103 pool.ShrinkToFit();
104 EXPECT_EQ(pool.Count(), 2U);
105 EXPECT_EQ(pool.FreeCount(), 0U);
106 EXPECT_EQ(pool.AccCount(), 2U);
107 EXPECT_EQ(result, 1U);
108 }
109
110 EXPECT_EQ(pool.Count(), 2U);
111 EXPECT_EQ(pool.FreeCount(), 2U);
112 EXPECT_EQ(pool.AccCount(), 0U);
113 EXPECT_EQ(result, 0U);
114 }
115
116 template <typename I, typename C>
VerifierTestObjPool3(Pool<I,C> & pool,int & result)117 static void VerifierTestObjPool3(Pool<I, C> &pool, int &result)
118 {
119 auto q = pool.New();
120 auto w = pool.New();
121 auto p = pool.New();
122 EXPECT_EQ(pool.Count(), 3U);
123 EXPECT_EQ(pool.FreeCount(), 0U);
124 EXPECT_EQ(pool.AccCount(), 3U);
125 EXPECT_EQ(result, 3U);
126
127 auto u {p};
128
129 EXPECT_EQ(pool.Count(), 3U);
130 EXPECT_EQ(pool.FreeCount(), 0U);
131 EXPECT_EQ(pool.AccCount(), 4U);
132 EXPECT_EQ(result, 3U);
133
134 auto e {std::move(p)};
135
136 EXPECT_EQ(pool.Count(), 3U);
137 EXPECT_EQ(pool.FreeCount(), 0U);
138 EXPECT_EQ(pool.AccCount(), 4U);
139 EXPECT_EQ(result, 3U);
140 // NOLINTNEXTLINE(bugprone-use-after-move)
141 EXPECT_FALSE(p);
142 EXPECT_TRUE(u);
143
144 p = e;
145
146 EXPECT_EQ(pool.Count(), 3U);
147 EXPECT_EQ(pool.FreeCount(), 0U);
148 EXPECT_EQ(pool.AccCount(), 5U);
149 EXPECT_EQ(result, 3U);
150 EXPECT_TRUE(p);
151
152 q = e;
153
154 EXPECT_EQ(pool.Count(), 3U);
155 EXPECT_EQ(pool.FreeCount(), 1U);
156 EXPECT_EQ(pool.AccCount(), 5U);
157 EXPECT_EQ(result, 3U);
158
159 w = std::move(e);
160
161 EXPECT_EQ(pool.Count(), 3U);
162 EXPECT_EQ(pool.FreeCount(), 2U);
163 EXPECT_EQ(pool.AccCount(), 4U);
164 EXPECT_EQ(result, 2U);
165 // NOLINTNEXTLINE(bugprone-use-after-move)
166 EXPECT_FALSE(e);
167
168 EXPECT_EQ((*w).a, 2U);
169 }
170
TEST(VerifierTest_ObjPool,Basic)171 TEST(VerifierTest_ObjPool, Basic)
172 {
173 int result = 0;
174 auto &&h = [&result](S &s, size_t idx) {
175 s.a = idx;
176 result += idx;
177 };
178 Pool pool {h, [&result](S &s) { result -= s.a; }};
179 VerifierTestObjPool1(pool, result);
180 VerifierTestObjPool2(pool, result);
181 VerifierTestObjPool3(pool, result);
182
183 EXPECT_EQ(pool.Count(), 3U);
184 EXPECT_EQ(pool.FreeCount(), 3U);
185 EXPECT_EQ(pool.AccCount(), 0U);
186 EXPECT_EQ(result, 0U);
187
188 pool.ShrinkToFit();
189 EXPECT_EQ(pool.Count(), 0U);
190 EXPECT_EQ(pool.FreeCount(), 0U);
191 EXPECT_EQ(pool.AccCount(), 0U);
192 EXPECT_EQ(result, 0U);
193
194 {
195 auto q = pool.New();
196 auto w = pool.New();
197 auto p = pool.New();
198 q = std::move(w);
199 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
200 auto e = p;
201
202 EXPECT_EQ(pool.Count(), 3U);
203 EXPECT_EQ(pool.FreeCount(), 1U);
204 EXPECT_EQ(pool.AccCount(), 3U);
205 EXPECT_EQ(result, 3U);
206
207 int sum = 0;
208 int prod = 1;
209 int num = 0;
210
211 while (auto acc = pool.AllObjects()()) {
212 const S &obj = *(*acc);
213 sum += obj.a;
214 prod *= obj.a;
215 ++num;
216 }
217
218 EXPECT_EQ(sum, 3U);
219 EXPECT_EQ(prod, 2U);
220 EXPECT_EQ(num, 2U);
221 }
222
223 EXPECT_EQ(pool.Count(), 3U);
224 EXPECT_EQ(pool.FreeCount(), 3U);
225 EXPECT_EQ(pool.AccCount(), 0U);
226 EXPECT_EQ(result, 0U);
227 }
228
229 } // namespace ark::verifier::test
230