1 // Copyright 2021 gRPC authors.
2 //
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 #include "src/core/util/chunked_vector.h"
16
17 #include <grpc/event_engine/memory_allocator.h>
18
19 #include <algorithm>
20 #include <memory>
21
22 #include "gtest/gtest.h"
23 #include "src/core/lib/resource_quota/memory_quota.h"
24 #include "src/core/lib/resource_quota/resource_quota.h"
25 #include "src/core/util/ref_counted_ptr.h"
26
27 namespace grpc_core {
28 namespace testing {
29
30 static constexpr size_t kInitialArenaSize = 1024;
31 static constexpr size_t kChunkSize = 3;
32
TEST(ChunkedVectorTest,Noop)33 TEST(ChunkedVectorTest, Noop) {
34 auto arena = SimpleArenaAllocator(kInitialArenaSize)->MakeArena();
35 ChunkedVector<int, kChunkSize> v(arena.get());
36 EXPECT_EQ(0, v.size());
37 }
38
TEST(ChunkedVectorTest,Stack)39 TEST(ChunkedVectorTest, Stack) {
40 auto arena = SimpleArenaAllocator(kInitialArenaSize)->MakeArena();
41 ChunkedVector<int, kChunkSize> v(arena.get());
42
43 // Populate 2 chunks of memory, and 2/3 of a final chunk.
44 EXPECT_EQ(0, v.size());
45 v.EmplaceBack(1);
46 EXPECT_EQ(1, v.size());
47 v.EmplaceBack(2);
48 EXPECT_EQ(2, v.size());
49 v.EmplaceBack(3);
50 EXPECT_EQ(3, v.size());
51 v.EmplaceBack(4);
52 EXPECT_EQ(4, v.size());
53 v.EmplaceBack(5);
54 EXPECT_EQ(5, v.size());
55 v.EmplaceBack(6);
56 EXPECT_EQ(6, v.size());
57 v.EmplaceBack(7);
58 EXPECT_EQ(7, v.size());
59 v.EmplaceBack(8);
60 EXPECT_EQ(8, v.size());
61
62 // Now pop all of them out and check the expected ordering.
63 EXPECT_EQ(8, v.PopBack());
64 EXPECT_EQ(7, v.size());
65 EXPECT_EQ(7, v.PopBack());
66 EXPECT_EQ(6, v.size());
67 EXPECT_EQ(6, v.PopBack());
68 EXPECT_EQ(5, v.size());
69 EXPECT_EQ(5, v.PopBack());
70 EXPECT_EQ(4, v.size());
71 EXPECT_EQ(4, v.PopBack());
72 EXPECT_EQ(3, v.size());
73 EXPECT_EQ(3, v.PopBack());
74 EXPECT_EQ(2, v.size());
75 EXPECT_EQ(2, v.PopBack());
76 EXPECT_EQ(1, v.size());
77 EXPECT_EQ(1, v.PopBack());
78 EXPECT_EQ(0, v.size());
79 }
80
TEST(ChunkedVectorTest,Iterate)81 TEST(ChunkedVectorTest, Iterate) {
82 auto arena = SimpleArenaAllocator(kInitialArenaSize)->MakeArena();
83 ChunkedVector<int, kChunkSize> v(arena.get());
84 v.EmplaceBack(1);
85 v.EmplaceBack(2);
86 v.EmplaceBack(3);
87 v.EmplaceBack(4);
88 v.EmplaceBack(5);
89 v.EmplaceBack(6);
90 v.EmplaceBack(7);
91 v.EmplaceBack(8);
92
93 auto it = v.begin();
94 EXPECT_EQ(1, *it);
95 ++it;
96 EXPECT_EQ(2, *it);
97 ++it;
98 EXPECT_EQ(3, *it);
99 ++it;
100 EXPECT_EQ(4, *it);
101 ++it;
102 EXPECT_EQ(5, *it);
103 ++it;
104 EXPECT_EQ(6, *it);
105 ++it;
106 EXPECT_EQ(7, *it);
107 ++it;
108 EXPECT_EQ(8, *it);
109 ++it;
110 EXPECT_EQ(v.end(), it);
111 }
112
TEST(ChunkedVectorTest,ConstIterate)113 TEST(ChunkedVectorTest, ConstIterate) {
114 auto arena = SimpleArenaAllocator(kInitialArenaSize)->MakeArena();
115 ChunkedVector<int, kChunkSize> v(arena.get());
116 v.EmplaceBack(1);
117 v.EmplaceBack(2);
118 v.EmplaceBack(3);
119 v.EmplaceBack(4);
120 v.EmplaceBack(5);
121 v.EmplaceBack(6);
122 v.EmplaceBack(7);
123 v.EmplaceBack(8);
124
125 auto it = v.cbegin();
126 EXPECT_EQ(1, *it);
127 ++it;
128 EXPECT_EQ(2, *it);
129 ++it;
130 EXPECT_EQ(3, *it);
131 ++it;
132 EXPECT_EQ(4, *it);
133 ++it;
134 EXPECT_EQ(5, *it);
135 ++it;
136 EXPECT_EQ(6, *it);
137 ++it;
138 EXPECT_EQ(7, *it);
139 ++it;
140 EXPECT_EQ(8, *it);
141 ++it;
142 EXPECT_EQ(v.cend(), it);
143 }
144
TEST(ChunkedVectorTest,Clear)145 TEST(ChunkedVectorTest, Clear) {
146 auto arena = SimpleArenaAllocator(kInitialArenaSize)->MakeArena();
147 ChunkedVector<int, kChunkSize> v(arena.get());
148 v.EmplaceBack(1);
149 EXPECT_EQ(v.size(), 1);
150 v.Clear();
151 EXPECT_EQ(v.size(), 0);
152 EXPECT_EQ(v.begin(), v.end());
153 }
154
TEST(ChunkedVectorTest,RemoveIf)155 TEST(ChunkedVectorTest, RemoveIf) {
156 auto arena = SimpleArenaAllocator(kInitialArenaSize)->MakeArena();
157 ChunkedVector<int, kChunkSize> v(arena.get());
158 v.EmplaceBack(1);
159 v.SetEnd(std::remove_if(v.begin(), v.end(), [](int i) { return i == 1; }));
160 EXPECT_EQ(v.size(), 0);
161 }
162
163 } // namespace testing
164
165 } // namespace grpc_core
166
main(int argc,char ** argv)167 int main(int argc, char** argv) {
168 ::testing::InitGoogleTest(&argc, argv);
169 return RUN_ALL_TESTS();
170 }
171