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