YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/db/file_indexer_test.cc
Line
Count
Source (jump to first uncovered line)
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.
5
//
6
// The following only applies to changes made to this file as part of YugaByte development.
7
//
8
// Portions Copyright (c) YugaByte, Inc.
9
//
10
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
11
// in compliance with the License.  You may obtain a copy of the License at
12
//
13
// http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software distributed under the License
16
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
// or implied.  See the License for the specific language governing permissions and limitations
18
// under the License.
19
//
20
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
21
// Use of this source code is governed by a BSD-style license that can be
22
// found in the LICENSE file. See the AUTHORS file for names of contributors.
23
24
#include <string>
25
26
#include <gtest/gtest.h>
27
28
#include "yb/rocksdb/db/dbformat.h"
29
#include "yb/rocksdb/db/file_indexer.h"
30
#include "yb/rocksdb/db/version_edit.h"
31
#include "yb/rocksdb/port/stack_trace.h"
32
33
#include "yb/rocksdb/util/testutil.h"
34
35
namespace rocksdb {
36
37
class IntComparator : public Comparator {
38
 public:
39
93
  int Compare(const Slice& a, const Slice& b) const override {
40
93
    assert(a.size() == 8);
41
93
    assert(b.size() == 8);
42
93
    int64_t diff = *reinterpret_cast<const int64_t*>(a.data()) -
43
93
                   *reinterpret_cast<const int64_t*>(b.data());
44
93
    if (diff < 0) {
45
39
      return -1;
46
54
    } else if (diff == 0) {
47
7
      return 0;
48
47
    } else {
49
47
      return 1;
50
47
    }
51
93
  }
52
53
0
  const char* Name() const override { return "IntComparator"; }
54
55
  void FindShortestSeparator(std::string* start,
56
0
                             const Slice& limit) const override {}
57
58
0
  void FindShortSuccessor(std::string* key) const override {}
59
};
60
61
class FileIndexerTest : public RocksDBTest {
62
 public:
63
  FileIndexerTest()
64
5
      : kNumLevels(4), files(new std::vector<FileMetaData*>[kNumLevels]) {}
65
66
5
  ~FileIndexerTest() {
67
5
    ClearFiles();
68
5
    delete[] files;
69
5
  }
70
71
35
  void AddFile(int level, int64_t smallest, int64_t largest) {
72
35
    auto* f = new FileMetaData();
73
35
    f->smallest = BoundaryValues(smallest);
74
35
    f->largest = BoundaryValues(largest);
75
35
    files[level].push_back(f);
76
35
  }
77
78
70
  FileBoundaryValues<InternalKey> BoundaryValues(int64_t v) {
79
70
    return MakeFileBoundaryValues(std::string(reinterpret_cast<char*>(&v), 8), 0, kTypeValue);
80
70
  }
81
82
8
  void ClearFiles() {
83
40
    for (uint32_t i = 0; i < kNumLevels; ++i) {
84
35
      for (auto* f : files[i]) {
85
35
        delete f;
86
35
      }
87
32
      files[i].clear();
88
32
    }
89
8
  }
90
91
  void GetNextLevelIndex(const uint32_t level, const uint32_t file_index,
92
      const int cmp_smallest, const int cmp_largest, int32_t* left_index,
93
124
      int32_t* right_index) {
94
124
    *left_index = 100;
95
124
    *right_index = 100;
96
124
    indexer->GetNextLevelIndex(level, file_index, cmp_smallest, cmp_largest,
97
124
                               left_index, right_index);
98
124
  }
99
100
  int32_t left = 100;
101
  int32_t right = 100;
102
  const uint32_t kNumLevels;
103
  IntComparator ucmp;
104
  FileIndexer* indexer;
105
106
  std::vector<FileMetaData*>* files;
107
};
108
109
// Case 0: Empty
110
1
TEST_F(FileIndexerTest, Empty) {
111
1
  Arena arena;
112
1
  indexer = new FileIndexer(&ucmp);
113
1
  indexer->UpdateIndex(&arena, 0, files);
114
1
  delete indexer;
115
1
}
116
117
// Case 1: no overlap, files are on the left of next level files
118
1
TEST_F(FileIndexerTest, no_overlap_left) {
119
1
  Arena arena;
120
1
  indexer = new FileIndexer(&ucmp);
121
  // level 1
122
1
  AddFile(1, 100, 200);
123
1
  AddFile(1, 300, 400);
124
1
  AddFile(1, 500, 600);
125
  // level 2
126
1
  AddFile(2, 1500, 1600);
127
1
  AddFile(2, 1601, 1699);
128
1
  AddFile(2, 1700, 1800);
129
  // level 3
130
1
  AddFile(3, 2500, 2600);
131
1
  AddFile(3, 2601, 2699);
132
1
  AddFile(3, 2700, 2800);
133
1
  indexer->UpdateIndex(&arena, kNumLevels, files);
134
3
  for (uint32_t level = 1; level < 3; ++level) {
135
8
    for (uint32_t f = 0; f < 3; ++f) {
136
6
      GetNextLevelIndex(level, f, -1, -1, &left, &right);
137
6
      ASSERT_EQ(0, left);
138
6
      ASSERT_EQ(-1, right);
139
6
      GetNextLevelIndex(level, f, 0, -1, &left, &right);
140
6
      ASSERT_EQ(0, left);
141
6
      ASSERT_EQ(-1, right);
142
6
      GetNextLevelIndex(level, f, 1, -1, &left, &right);
143
6
      ASSERT_EQ(0, left);
144
6
      ASSERT_EQ(-1, right);
145
6
      GetNextLevelIndex(level, f, 1, 0, &left, &right);
146
6
      ASSERT_EQ(0, left);
147
6
      ASSERT_EQ(-1, right);
148
6
      GetNextLevelIndex(level, f, 1, 1, &left, &right);
149
6
      ASSERT_EQ(0, left);
150
6
      ASSERT_EQ(2, right);
151
6
    }
152
2
  }
153
1
  delete indexer;
154
1
  ClearFiles();
155
1
}
156
157
// Case 2: no overlap, files are on the right of next level files
158
1
TEST_F(FileIndexerTest, no_overlap_right) {
159
1
  Arena arena;
160
1
  indexer = new FileIndexer(&ucmp);
161
  // level 1
162
1
  AddFile(1, 2100, 2200);
163
1
  AddFile(1, 2300, 2400);
164
1
  AddFile(1, 2500, 2600);
165
  // level 2
166
1
  AddFile(2, 1500, 1600);
167
1
  AddFile(2, 1501, 1699);
168
1
  AddFile(2, 1700, 1800);
169
  // level 3
170
1
  AddFile(3, 500, 600);
171
1
  AddFile(3, 501, 699);
172
1
  AddFile(3, 700, 800);
173
1
  indexer->UpdateIndex(&arena, kNumLevels, files);
174
3
  for (uint32_t level = 1; level < 3; ++level) {
175
8
    for (uint32_t f = 0; f < 3; ++f) {
176
6
      GetNextLevelIndex(level, f, -1, -1, &left, &right);
177
6
      ASSERT_EQ(f == 0 ? 0 : 3, left);
178
6
      ASSERT_EQ(2, right);
179
6
      GetNextLevelIndex(level, f, 0, -1, &left, &right);
180
6
      ASSERT_EQ(3, left);
181
6
      ASSERT_EQ(2, right);
182
6
      GetNextLevelIndex(level, f, 1, -1, &left, &right);
183
6
      ASSERT_EQ(3, left);
184
6
      ASSERT_EQ(2, right);
185
6
      GetNextLevelIndex(level, f, 1, -1, &left, &right);
186
6
      ASSERT_EQ(3, left);
187
6
      ASSERT_EQ(2, right);
188
6
      GetNextLevelIndex(level, f, 1, 0, &left, &right);
189
6
      ASSERT_EQ(3, left);
190
6
      ASSERT_EQ(2, right);
191
6
      GetNextLevelIndex(level, f, 1, 1, &left, &right);
192
6
      ASSERT_EQ(3, left);
193
6
      ASSERT_EQ(2, right);
194
6
    }
195
2
  }
196
1
  delete indexer;
197
1
}
198
199
// Case 3: empty L2
200
1
TEST_F(FileIndexerTest, empty_L2) {
201
1
  Arena arena;
202
1
  indexer = new FileIndexer(&ucmp);
203
4
  for (uint32_t i = 1; i < kNumLevels; ++i) {
204
3
    ASSERT_EQ(0U, indexer->LevelIndexSize(i));
205
3
  }
206
  // level 1
207
1
  AddFile(1, 2100, 2200);
208
1
  AddFile(1, 2300, 2400);
209
1
  AddFile(1, 2500, 2600);
210
  // level 3
211
1
  AddFile(3, 500, 600);
212
1
  AddFile(3, 501, 699);
213
1
  AddFile(3, 700, 800);
214
1
  indexer->UpdateIndex(&arena, kNumLevels, files);
215
4
  for (uint32_t f = 0; f < 3; ++f) {
216
3
    GetNextLevelIndex(1, f, -1, -1, &left, &right);
217
3
    ASSERT_EQ(0, left);
218
3
    ASSERT_EQ(-1, right);
219
3
    GetNextLevelIndex(1, f, 0, -1, &left, &right);
220
3
    ASSERT_EQ(0, left);
221
3
    ASSERT_EQ(-1, right);
222
3
    GetNextLevelIndex(1, f, 1, -1, &left, &right);
223
3
    ASSERT_EQ(0, left);
224
3
    ASSERT_EQ(-1, right);
225
3
    GetNextLevelIndex(1, f, 1, -1, &left, &right);
226
3
    ASSERT_EQ(0, left);
227
3
    ASSERT_EQ(-1, right);
228
3
    GetNextLevelIndex(1, f, 1, 0, &left, &right);
229
3
    ASSERT_EQ(0, left);
230
3
    ASSERT_EQ(-1, right);
231
3
    GetNextLevelIndex(1, f, 1, 1, &left, &right);
232
3
    ASSERT_EQ(0, left);
233
3
    ASSERT_EQ(-1, right);
234
3
  }
235
1
  delete indexer;
236
1
  ClearFiles();
237
1
}
238
239
// Case 4: mixed
240
1
TEST_F(FileIndexerTest, mixed) {
241
1
  Arena arena;
242
1
  indexer = new FileIndexer(&ucmp);
243
  // level 1
244
1
  AddFile(1, 100, 200);
245
1
  AddFile(1, 250, 400);
246
1
  AddFile(1, 450, 500);
247
  // level 2
248
1
  AddFile(2, 100, 150);  // 0
249
1
  AddFile(2, 200, 250);  // 1
250
1
  AddFile(2, 251, 300);  // 2
251
1
  AddFile(2, 301, 350);  // 3
252
1
  AddFile(2, 500, 600);  // 4
253
  // level 3
254
1
  AddFile(3, 0, 50);
255
1
  AddFile(3, 100, 200);
256
1
  AddFile(3, 201, 250);
257
1
  indexer->UpdateIndex(&arena, kNumLevels, files);
258
  // level 1, 0
259
1
  GetNextLevelIndex(1, 0, -1, -1, &left, &right);
260
1
  ASSERT_EQ(0, left);
261
1
  ASSERT_EQ(0, right);
262
1
  GetNextLevelIndex(1, 0, 0, -1, &left, &right);
263
1
  ASSERT_EQ(0, left);
264
1
  ASSERT_EQ(0, right);
265
1
  GetNextLevelIndex(1, 0, 1, -1, &left, &right);
266
1
  ASSERT_EQ(0, left);
267
1
  ASSERT_EQ(1, right);
268
1
  GetNextLevelIndex(1, 0, 1, 0, &left, &right);
269
1
  ASSERT_EQ(1, left);
270
1
  ASSERT_EQ(1, right);
271
1
  GetNextLevelIndex(1, 0, 1, 1, &left, &right);
272
1
  ASSERT_EQ(1, left);
273
1
  ASSERT_EQ(4, right);
274
  // level 1, 1
275
1
  GetNextLevelIndex(1, 1, -1, -1, &left, &right);
276
1
  ASSERT_EQ(1, left);
277
1
  ASSERT_EQ(1, right);
278
1
  GetNextLevelIndex(1, 1, 0, -1, &left, &right);
279
1
  ASSERT_EQ(1, left);
280
1
  ASSERT_EQ(1, right);
281
1
  GetNextLevelIndex(1, 1, 1, -1, &left, &right);
282
1
  ASSERT_EQ(1, left);
283
1
  ASSERT_EQ(3, right);
284
1
  GetNextLevelIndex(1, 1, 1, 0, &left, &right);
285
1
  ASSERT_EQ(4, left);
286
1
  ASSERT_EQ(3, right);
287
1
  GetNextLevelIndex(1, 1, 1, 1, &left, &right);
288
1
  ASSERT_EQ(4, left);
289
1
  ASSERT_EQ(4, right);
290
  // level 1, 2
291
1
  GetNextLevelIndex(1, 2, -1, -1, &left, &right);
292
1
  ASSERT_EQ(4, left);
293
1
  ASSERT_EQ(3, right);
294
1
  GetNextLevelIndex(1, 2, 0, -1, &left, &right);
295
1
  ASSERT_EQ(4, left);
296
1
  ASSERT_EQ(3, right);
297
1
  GetNextLevelIndex(1, 2, 1, -1, &left, &right);
298
1
  ASSERT_EQ(4, left);
299
1
  ASSERT_EQ(4, right);
300
1
  GetNextLevelIndex(1, 2, 1, 0, &left, &right);
301
1
  ASSERT_EQ(4, left);
302
1
  ASSERT_EQ(4, right);
303
1
  GetNextLevelIndex(1, 2, 1, 1, &left, &right);
304
1
  ASSERT_EQ(4, left);
305
1
  ASSERT_EQ(4, right);
306
  // level 2, 0
307
1
  GetNextLevelIndex(2, 0, -1, -1, &left, &right);
308
1
  ASSERT_EQ(0, left);
309
1
  ASSERT_EQ(1, right);
310
1
  GetNextLevelIndex(2, 0, 0, -1, &left, &right);
311
1
  ASSERT_EQ(1, left);
312
1
  ASSERT_EQ(1, right);
313
1
  GetNextLevelIndex(2, 0, 1, -1, &left, &right);
314
1
  ASSERT_EQ(1, left);
315
1
  ASSERT_EQ(1, right);
316
1
  GetNextLevelIndex(2, 0, 1, 0, &left, &right);
317
1
  ASSERT_EQ(1, left);
318
1
  ASSERT_EQ(1, right);
319
1
  GetNextLevelIndex(2, 0, 1, 1, &left, &right);
320
1
  ASSERT_EQ(1, left);
321
1
  ASSERT_EQ(2, right);
322
  // level 2, 1
323
1
  GetNextLevelIndex(2, 1, -1, -1, &left, &right);
324
1
  ASSERT_EQ(1, left);
325
1
  ASSERT_EQ(1, right);
326
1
  GetNextLevelIndex(2, 1, 0, -1, &left, &right);
327
1
  ASSERT_EQ(1, left);
328
1
  ASSERT_EQ(1, right);
329
1
  GetNextLevelIndex(2, 1, 1, -1, &left, &right);
330
1
  ASSERT_EQ(1, left);
331
1
  ASSERT_EQ(2, right);
332
1
  GetNextLevelIndex(2, 1, 1, 0, &left, &right);
333
1
  ASSERT_EQ(2, left);
334
1
  ASSERT_EQ(2, right);
335
1
  GetNextLevelIndex(2, 1, 1, 1, &left, &right);
336
1
  ASSERT_EQ(2, left);
337
1
  ASSERT_EQ(2, right);
338
  // level 2, [2 - 4], no overlap
339
4
  for (uint32_t f = 2; f <= 4; ++f) {
340
3
    GetNextLevelIndex(2, f, -1, -1, &left, &right);
341
3
    ASSERT_EQ(f == 2 ? 2 : 3, left);
342
3
    ASSERT_EQ(2, right);
343
3
    GetNextLevelIndex(2, f, 0, -1, &left, &right);
344
3
    ASSERT_EQ(3, left);
345
3
    ASSERT_EQ(2, right);
346
3
    GetNextLevelIndex(2, f, 1, -1, &left, &right);
347
3
    ASSERT_EQ(3, left);
348
3
    ASSERT_EQ(2, right);
349
3
    GetNextLevelIndex(2, f, 1, 0, &left, &right);
350
3
    ASSERT_EQ(3, left);
351
3
    ASSERT_EQ(2, right);
352
3
    GetNextLevelIndex(2, f, 1, 1, &left, &right);
353
3
    ASSERT_EQ(3, left);
354
3
    ASSERT_EQ(2, right);
355
3
  }
356
1
  delete indexer;
357
1
  ClearFiles();
358
1
}
359
360
}  // namespace rocksdb
361
362
13.2k
int main(int argc, char** argv) {
363
13.2k
  rocksdb::port::InstallStackTraceHandler();
364
13.2k
  ::testing::InitGoogleTest(&argc, argv);
365
13.2k
  return RUN_ALL_TESTS();
366
13.2k
}