]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/db/file_indexer_test.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
11 #include "db/file_indexer.h"
12 #include "db/dbformat.h"
13 #include "db/version_edit.h"
14 #include "port/stack_trace.h"
15 #include "rocksdb/comparator.h"
16 #include "util/testharness.h"
17 #include "util/testutil.h"
21 class IntComparator
: public Comparator
{
23 int Compare(const Slice
& a
, const Slice
& b
) const override
{
24 assert(a
.size() == 8);
25 assert(b
.size() == 8);
26 int64_t diff
= *reinterpret_cast<const int64_t*>(a
.data()) -
27 *reinterpret_cast<const int64_t*>(b
.data());
30 } else if (diff
== 0) {
37 const char* Name() const override
{ return "IntComparator"; }
39 void FindShortestSeparator(std::string
* start
,
40 const Slice
& limit
) const override
{}
42 void FindShortSuccessor(std::string
* key
) const override
{}
45 class FileIndexerTest
: public testing::Test
{
48 : kNumLevels(4), files(new std::vector
<FileMetaData
*>[kNumLevels
]) {}
55 void AddFile(int level
, int64_t smallest
, int64_t largest
) {
56 auto* f
= new FileMetaData();
57 f
->smallest
= IntKey(smallest
);
58 f
->largest
= IntKey(largest
);
59 files
[level
].push_back(f
);
62 InternalKey
IntKey(int64_t v
) {
63 return InternalKey(Slice(reinterpret_cast<char*>(&v
), 8), 0, kTypeValue
);
67 for (uint32_t i
= 0; i
< kNumLevels
; ++i
) {
68 for (auto* f
: files
[i
]) {
75 void GetNextLevelIndex(const uint32_t level
, const uint32_t file_index
,
76 const int cmp_smallest
, const int cmp_largest
, int32_t* left_index
,
77 int32_t* right_index
) {
80 indexer
->GetNextLevelIndex(level
, file_index
, cmp_smallest
, cmp_largest
,
81 left_index
, right_index
);
86 const uint32_t kNumLevels
;
90 std::vector
<FileMetaData
*>* files
;
94 TEST_F(FileIndexerTest
, Empty
) {
96 indexer
= new FileIndexer(&ucmp
);
97 indexer
->UpdateIndex(&arena
, 0, files
);
101 // Case 1: no overlap, files are on the left of next level files
102 TEST_F(FileIndexerTest
, no_overlap_left
) {
104 indexer
= new FileIndexer(&ucmp
);
106 AddFile(1, 100, 200);
107 AddFile(1, 300, 400);
108 AddFile(1, 500, 600);
110 AddFile(2, 1500, 1600);
111 AddFile(2, 1601, 1699);
112 AddFile(2, 1700, 1800);
114 AddFile(3, 2500, 2600);
115 AddFile(3, 2601, 2699);
116 AddFile(3, 2700, 2800);
117 indexer
->UpdateIndex(&arena
, kNumLevels
, files
);
118 for (uint32_t level
= 1; level
< 3; ++level
) {
119 for (uint32_t f
= 0; f
< 3; ++f
) {
120 GetNextLevelIndex(level
, f
, -1, -1, &left
, &right
);
122 ASSERT_EQ(-1, right
);
123 GetNextLevelIndex(level
, f
, 0, -1, &left
, &right
);
125 ASSERT_EQ(-1, right
);
126 GetNextLevelIndex(level
, f
, 1, -1, &left
, &right
);
128 ASSERT_EQ(-1, right
);
129 GetNextLevelIndex(level
, f
, 1, 0, &left
, &right
);
131 ASSERT_EQ(-1, right
);
132 GetNextLevelIndex(level
, f
, 1, 1, &left
, &right
);
141 // Case 2: no overlap, files are on the right of next level files
142 TEST_F(FileIndexerTest
, no_overlap_right
) {
144 indexer
= new FileIndexer(&ucmp
);
146 AddFile(1, 2100, 2200);
147 AddFile(1, 2300, 2400);
148 AddFile(1, 2500, 2600);
150 AddFile(2, 1500, 1600);
151 AddFile(2, 1501, 1699);
152 AddFile(2, 1700, 1800);
154 AddFile(3, 500, 600);
155 AddFile(3, 501, 699);
156 AddFile(3, 700, 800);
157 indexer
->UpdateIndex(&arena
, kNumLevels
, files
);
158 for (uint32_t level
= 1; level
< 3; ++level
) {
159 for (uint32_t f
= 0; f
< 3; ++f
) {
160 GetNextLevelIndex(level
, f
, -1, -1, &left
, &right
);
161 ASSERT_EQ(f
== 0 ? 0 : 3, left
);
163 GetNextLevelIndex(level
, f
, 0, -1, &left
, &right
);
166 GetNextLevelIndex(level
, f
, 1, -1, &left
, &right
);
169 GetNextLevelIndex(level
, f
, 1, -1, &left
, &right
);
172 GetNextLevelIndex(level
, f
, 1, 0, &left
, &right
);
175 GetNextLevelIndex(level
, f
, 1, 1, &left
, &right
);
184 TEST_F(FileIndexerTest
, empty_L2
) {
186 indexer
= new FileIndexer(&ucmp
);
187 for (uint32_t i
= 1; i
< kNumLevels
; ++i
) {
188 ASSERT_EQ(0U, indexer
->LevelIndexSize(i
));
191 AddFile(1, 2100, 2200);
192 AddFile(1, 2300, 2400);
193 AddFile(1, 2500, 2600);
195 AddFile(3, 500, 600);
196 AddFile(3, 501, 699);
197 AddFile(3, 700, 800);
198 indexer
->UpdateIndex(&arena
, kNumLevels
, files
);
199 for (uint32_t f
= 0; f
< 3; ++f
) {
200 GetNextLevelIndex(1, f
, -1, -1, &left
, &right
);
202 ASSERT_EQ(-1, right
);
203 GetNextLevelIndex(1, f
, 0, -1, &left
, &right
);
205 ASSERT_EQ(-1, right
);
206 GetNextLevelIndex(1, f
, 1, -1, &left
, &right
);
208 ASSERT_EQ(-1, right
);
209 GetNextLevelIndex(1, f
, 1, -1, &left
, &right
);
211 ASSERT_EQ(-1, right
);
212 GetNextLevelIndex(1, f
, 1, 0, &left
, &right
);
214 ASSERT_EQ(-1, right
);
215 GetNextLevelIndex(1, f
, 1, 1, &left
, &right
);
217 ASSERT_EQ(-1, right
);
224 TEST_F(FileIndexerTest
, mixed
) {
226 indexer
= new FileIndexer(&ucmp
);
228 AddFile(1, 100, 200);
229 AddFile(1, 250, 400);
230 AddFile(1, 450, 500);
232 AddFile(2, 100, 150); // 0
233 AddFile(2, 200, 250); // 1
234 AddFile(2, 251, 300); // 2
235 AddFile(2, 301, 350); // 3
236 AddFile(2, 500, 600); // 4
239 AddFile(3, 100, 200);
240 AddFile(3, 201, 250);
241 indexer
->UpdateIndex(&arena
, kNumLevels
, files
);
243 GetNextLevelIndex(1, 0, -1, -1, &left
, &right
);
246 GetNextLevelIndex(1, 0, 0, -1, &left
, &right
);
249 GetNextLevelIndex(1, 0, 1, -1, &left
, &right
);
252 GetNextLevelIndex(1, 0, 1, 0, &left
, &right
);
255 GetNextLevelIndex(1, 0, 1, 1, &left
, &right
);
259 GetNextLevelIndex(1, 1, -1, -1, &left
, &right
);
262 GetNextLevelIndex(1, 1, 0, -1, &left
, &right
);
265 GetNextLevelIndex(1, 1, 1, -1, &left
, &right
);
268 GetNextLevelIndex(1, 1, 1, 0, &left
, &right
);
271 GetNextLevelIndex(1, 1, 1, 1, &left
, &right
);
275 GetNextLevelIndex(1, 2, -1, -1, &left
, &right
);
278 GetNextLevelIndex(1, 2, 0, -1, &left
, &right
);
281 GetNextLevelIndex(1, 2, 1, -1, &left
, &right
);
284 GetNextLevelIndex(1, 2, 1, 0, &left
, &right
);
287 GetNextLevelIndex(1, 2, 1, 1, &left
, &right
);
291 GetNextLevelIndex(2, 0, -1, -1, &left
, &right
);
294 GetNextLevelIndex(2, 0, 0, -1, &left
, &right
);
297 GetNextLevelIndex(2, 0, 1, -1, &left
, &right
);
300 GetNextLevelIndex(2, 0, 1, 0, &left
, &right
);
303 GetNextLevelIndex(2, 0, 1, 1, &left
, &right
);
307 GetNextLevelIndex(2, 1, -1, -1, &left
, &right
);
310 GetNextLevelIndex(2, 1, 0, -1, &left
, &right
);
313 GetNextLevelIndex(2, 1, 1, -1, &left
, &right
);
316 GetNextLevelIndex(2, 1, 1, 0, &left
, &right
);
319 GetNextLevelIndex(2, 1, 1, 1, &left
, &right
);
322 // level 2, [2 - 4], no overlap
323 for (uint32_t f
= 2; f
<= 4; ++f
) {
324 GetNextLevelIndex(2, f
, -1, -1, &left
, &right
);
325 ASSERT_EQ(f
== 2 ? 2 : 3, left
);
327 GetNextLevelIndex(2, f
, 0, -1, &left
, &right
);
330 GetNextLevelIndex(2, f
, 1, -1, &left
, &right
);
333 GetNextLevelIndex(2, f
, 1, 0, &left
, &right
);
336 GetNextLevelIndex(2, f
, 1, 1, &left
, &right
);
344 } // namespace rocksdb
346 int main(int argc
, char** argv
) {
347 rocksdb::port::InstallStackTraceHandler();
348 ::testing::InitGoogleTest(&argc
, argv
);
349 return RUN_ALL_TESTS();