]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/test_pageset.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / test_pageset.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include "gtest/gtest.h"
4
5 #include "os/memstore/PageSet.h"
6
7 template <typename T>
8 bool is_aligned(T* ptr) {
9 const auto align_mask = alignof(T) - 1;
10 return (reinterpret_cast<uintptr_t>(ptr) & align_mask) == 0;
11 }
12
13 TEST(PageSet, AllocAligned)
14 {
15 PageSet pages(1);
16 PageSet::page_vector range;
17
18 pages.alloc_range(0, 4, range);
19 ASSERT_EQ(4u, range.size());
20 ASSERT_EQ(0u, range[0]->offset);
21 ASSERT_EQ(1u, range[1]->offset);
22 ASSERT_EQ(2u, range[2]->offset);
23 ASSERT_EQ(3u, range[3]->offset);
24
25 // verify that the Page pointers are properly aligned
26 ASSERT_TRUE(is_aligned(range[0].get()));
27 ASSERT_TRUE(is_aligned(range[1].get()));
28 ASSERT_TRUE(is_aligned(range[2].get()));
29 ASSERT_TRUE(is_aligned(range[3].get()));
30 }
31
32 TEST(PageSet, AllocUnaligned)
33 {
34 PageSet pages(2);
35 PageSet::page_vector range;
36
37 // front of first page
38 pages.alloc_range(0, 1, range);
39 ASSERT_EQ(1u, range.size());
40 ASSERT_EQ(0u, range[0]->offset);
41 range.clear();
42
43 // back of first page
44 pages.alloc_range(1, 1, range);
45 ASSERT_EQ(1u, range.size());
46 ASSERT_EQ(0u, range[0]->offset);
47 range.clear();
48
49 // back of first page and front of second
50 pages.alloc_range(1, 2, range);
51 ASSERT_EQ(2u, range.size());
52 ASSERT_EQ(0u, range[0]->offset);
53 ASSERT_EQ(2u, range[1]->offset);
54 range.clear();
55
56 // back of first page and all of second
57 pages.alloc_range(1, 3, range);
58 ASSERT_EQ(2u, range.size());
59 ASSERT_EQ(0u, range[0]->offset);
60 ASSERT_EQ(2u, range[1]->offset);
61 range.clear();
62
63 // back of first page, all of second, and front of third
64 pages.alloc_range(1, 4, range);
65 ASSERT_EQ(3u, range.size());
66 ASSERT_EQ(0u, range[0]->offset);
67 ASSERT_EQ(2u, range[1]->offset);
68 ASSERT_EQ(4u, range[2]->offset);
69 }
70
71 TEST(PageSet, GetAligned)
72 {
73 // allocate 4 pages
74 PageSet pages(1);
75 PageSet::page_vector range;
76 pages.alloc_range(0, 4, range);
77 range.clear();
78
79 // get first page
80 pages.get_range(0, 1, range);
81 ASSERT_EQ(1u, range.size());
82 ASSERT_EQ(0u, range[0]->offset);
83 range.clear();
84
85 // get second and third pages
86 pages.get_range(1, 2, range);
87 ASSERT_EQ(2u, range.size());
88 ASSERT_EQ(1u, range[0]->offset);
89 ASSERT_EQ(2u, range[1]->offset);
90 range.clear();
91
92 // get all four pages
93 pages.get_range(0, 4, range);
94 ASSERT_EQ(4u, range.size());
95 ASSERT_EQ(0u, range[0]->offset);
96 ASSERT_EQ(1u, range[1]->offset);
97 ASSERT_EQ(2u, range[2]->offset);
98 ASSERT_EQ(3u, range[3]->offset);
99 range.clear();
100 }
101
102 TEST(PageSet, GetUnaligned)
103 {
104 // allocate 3 pages
105 PageSet pages(2);
106 PageSet::page_vector range;
107 pages.alloc_range(0, 6, range);
108 range.clear();
109
110 // front of first page
111 pages.get_range(0, 1, range);
112 ASSERT_EQ(1u, range.size());
113 ASSERT_EQ(0u, range[0]->offset);
114 range.clear();
115
116 // back of first page
117 pages.get_range(1, 1, range);
118 ASSERT_EQ(1u, range.size());
119 ASSERT_EQ(0u, range[0]->offset);
120 range.clear();
121
122 // back of first page and front of second
123 pages.get_range(1, 2, range);
124 ASSERT_EQ(2u, range.size());
125 ASSERT_EQ(0u, range[0]->offset);
126 ASSERT_EQ(2u, range[1]->offset);
127 range.clear();
128
129 // back of first page and all of second
130 pages.get_range(1, 3, range);
131 ASSERT_EQ(2u, range.size());
132 ASSERT_EQ(0u, range[0]->offset);
133 ASSERT_EQ(2u, range[1]->offset);
134 range.clear();
135
136 // back of first page, all of second, and front of third
137 pages.get_range(1, 4, range);
138 ASSERT_EQ(3u, range.size());
139 ASSERT_EQ(0u, range[0]->offset);
140 ASSERT_EQ(2u, range[1]->offset);
141 ASSERT_EQ(4u, range[2]->offset);
142 range.clear();
143
144 // back of third page with nothing beyond
145 pages.get_range(5, 999, range);
146 ASSERT_EQ(1u, range.size());
147 ASSERT_EQ(4u, range[0]->offset);
148 range.clear();
149 }
150
151 TEST(PageSet, GetHoles)
152 {
153 // allocate pages at offsets 1, 2, 5, and 7
154 PageSet pages(1);
155 PageSet::page_vector range;
156 for (uint64_t i : {1, 2, 5, 7})
157 pages.alloc_range(i, 1, range);
158 range.clear();
159
160 // nothing at offset 0, page at offset 1
161 pages.get_range(0, 2, range);
162 ASSERT_EQ(1u, range.size());
163 ASSERT_EQ(1u, range[0]->offset);
164 range.clear();
165
166 // nothing at offset 0, pages at offset 1 and 2, nothing at offset 3
167 pages.get_range(0, 4, range);
168 ASSERT_EQ(2u, range.size());
169 ASSERT_EQ(1u, range[0]->offset);
170 ASSERT_EQ(2u, range[1]->offset);
171 range.clear();
172
173 // page at offset 2, nothing at offset 3 or 4
174 pages.get_range(2, 3, range);
175 ASSERT_EQ(1u, range.size());
176 ASSERT_EQ(2u, range[0]->offset);
177 range.clear();
178
179 // get the full range
180 pages.get_range(0, 999, range);
181 ASSERT_EQ(4u, range.size());
182 ASSERT_EQ(1u, range[0]->offset);
183 ASSERT_EQ(2u, range[1]->offset);
184 ASSERT_EQ(5u, range[2]->offset);
185 ASSERT_EQ(7u, range[3]->offset);
186 range.clear();
187 }
188
189 TEST(PageSet, FreeAligned)
190 {
191 // allocate 4 pages
192 PageSet pages(1);
193 PageSet::page_vector range;
194 pages.alloc_range(0, 4, range);
195 range.clear();
196
197 // get the full range
198 pages.get_range(0, 4, range);
199 ASSERT_EQ(4u, range.size());
200 range.clear();
201
202 // free after offset 4 has no effect
203 pages.free_pages_after(4);
204 pages.get_range(0, 4, range);
205 ASSERT_EQ(4u, range.size());
206 range.clear();
207
208 // free page 4
209 pages.free_pages_after(3);
210 pages.get_range(0, 4, range);
211 ASSERT_EQ(3u, range.size());
212 range.clear();
213
214 // free pages 2 and 3
215 pages.free_pages_after(1);
216 pages.get_range(0, 4, range);
217 ASSERT_EQ(1u, range.size());
218 range.clear();
219 }
220
221 TEST(PageSet, FreeUnaligned)
222 {
223 // allocate 4 pages
224 PageSet pages(2);
225 PageSet::page_vector range;
226 pages.alloc_range(0, 8, range);
227 range.clear();
228
229 // get the full range
230 pages.get_range(0, 8, range);
231 ASSERT_EQ(4u, range.size());
232 range.clear();
233
234 // free after offset 7 has no effect
235 pages.free_pages_after(7);
236 pages.get_range(0, 8, range);
237 ASSERT_EQ(4u, range.size());
238 range.clear();
239
240 // free page 4
241 pages.free_pages_after(5);
242 pages.get_range(0, 8, range);
243 ASSERT_EQ(3u, range.size());
244 range.clear();
245
246 // free pages 2 and 3
247 pages.free_pages_after(1);
248 pages.get_range(0, 8, range);
249 ASSERT_EQ(1u, range.size());
250 range.clear();
251 }
252
253 TEST(PageSet, FreeHoles)
254 {
255 // allocate pages at offsets 1, 2, 5, and 7
256 PageSet pages(1);
257 PageSet::page_vector range;
258 for (uint64_t i : {1, 2, 5, 7})
259 pages.alloc_range(i, 1, range);
260 range.clear();
261
262 // get the full range
263 pages.get_range(0, 8, range);
264 ASSERT_EQ(4u, range.size());
265 range.clear();
266
267 // free page 7
268 pages.free_pages_after(6);
269 pages.get_range(0, 8, range);
270 ASSERT_EQ(3u, range.size());
271 range.clear();
272
273 // free page 5
274 pages.free_pages_after(3);
275 pages.get_range(0, 8, range);
276 ASSERT_EQ(2u, range.size());
277 range.clear();
278
279 // free pages 1 and 2
280 pages.free_pages_after(0);
281 pages.get_range(0, 8, range);
282 ASSERT_EQ(0u, range.size());
283 }