1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
6 #include "db/compaction_picker.h"
10 #include "db/compaction.h"
11 #include "db/compaction_picker_universal.h"
13 #include "util/logging.h"
14 #include "util/string_util.h"
15 #include "util/testharness.h"
16 #include "util/testutil.h"
20 class CountingLogger
: public Logger
{
23 virtual void Logv(const char* /*format*/, va_list /*ap*/) override
{
29 class CompactionPickerTest
: public testing::Test
{
31 const Comparator
* ucmp_
;
32 InternalKeyComparator icmp_
;
34 ImmutableCFOptions ioptions_
;
35 MutableCFOptions mutable_cf_options_
;
36 LevelCompactionPicker level_compaction_picker
;
38 CountingLogger logger_
;
39 LogBuffer log_buffer_
;
41 CompactionOptionsFIFO fifo_options_
;
42 std::unique_ptr
<VersionStorageInfo
> vstorage_
;
43 std::vector
<std::unique_ptr
<FileMetaData
>> files_
;
44 // does not own FileMetaData
45 std::unordered_map
<uint32_t, std::pair
<FileMetaData
*, int>> file_map_
;
46 // input files to compaction process.
47 std::vector
<CompactionInputFiles
> input_files_
;
48 int compaction_level_start_
;
50 CompactionPickerTest()
51 : ucmp_(BytewiseComparator()),
54 mutable_cf_options_(options_
),
55 level_compaction_picker(ioptions_
, &icmp_
),
57 log_buffer_(InfoLogLevel::INFO_LEVEL
, &logger_
),
60 fifo_options_
.max_table_files_size
= 1;
61 mutable_cf_options_
.RefreshDerivedOptions(ioptions_
);
62 ioptions_
.cf_paths
.emplace_back("dummy",
63 std::numeric_limits
<uint64_t>::max());
66 ~CompactionPickerTest() {
69 void NewVersionStorage(int num_levels
, CompactionStyle style
) {
70 DeleteVersionStorage();
71 options_
.num_levels
= num_levels
;
72 vstorage_
.reset(new VersionStorageInfo(&icmp_
, ucmp_
, options_
.num_levels
,
73 style
, nullptr, false));
74 vstorage_
->CalculateBaseBytes(ioptions_
, mutable_cf_options_
);
77 void DeleteVersionStorage() {
84 void Add(int level
, uint32_t file_number
, const char* smallest
,
85 const char* largest
, uint64_t file_size
= 1, uint32_t path_id
= 0,
86 SequenceNumber smallest_seq
= 100,
87 SequenceNumber largest_seq
= 100) {
88 assert(level
< vstorage_
->num_levels());
89 FileMetaData
* f
= new FileMetaData
;
90 f
->fd
= FileDescriptor(file_number
, path_id
, file_size
);
91 f
->smallest
= InternalKey(smallest
, smallest_seq
, kTypeValue
);
92 f
->largest
= InternalKey(largest
, largest_seq
, kTypeValue
);
93 f
->fd
.smallest_seqno
= smallest_seq
;
94 f
->fd
.largest_seqno
= largest_seq
;
95 f
->compensated_file_size
= file_size
;
97 vstorage_
->AddFile(level
, f
);
98 files_
.emplace_back(f
);
99 file_map_
.insert({file_number
, {f
, level
}});
102 void SetCompactionInputFilesLevels(int level_count
, int start_level
) {
103 input_files_
.resize(level_count
);
104 for (int i
= 0; i
< level_count
; ++i
) {
105 input_files_
[i
].level
= start_level
+ i
;
107 compaction_level_start_
= start_level
;
110 void AddToCompactionFiles(uint32_t file_number
) {
111 auto iter
= file_map_
.find(file_number
);
112 assert(iter
!= file_map_
.end());
113 int level
= iter
->second
.second
;
114 assert(level
< vstorage_
->num_levels());
115 input_files_
[level
- compaction_level_start_
].files
.emplace_back(
119 void UpdateVersionStorageInfo() {
120 vstorage_
->CalculateBaseBytes(ioptions_
, mutable_cf_options_
);
121 vstorage_
->UpdateFilesByCompactionPri(ioptions_
.compaction_pri
);
122 vstorage_
->UpdateNumNonEmptyLevels();
123 vstorage_
->GenerateFileIndexer();
124 vstorage_
->GenerateLevelFilesBrief();
125 vstorage_
->ComputeCompactionScore(ioptions_
, mutable_cf_options_
);
126 vstorage_
->GenerateLevel0NonOverlapping();
127 vstorage_
->ComputeFilesMarkedForCompaction();
128 vstorage_
->SetFinalized();
132 TEST_F(CompactionPickerTest
, Empty
) {
133 NewVersionStorage(6, kCompactionStyleLevel
);
134 UpdateVersionStorageInfo();
135 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
136 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
137 ASSERT_TRUE(compaction
.get() == nullptr);
140 TEST_F(CompactionPickerTest
, Single
) {
141 NewVersionStorage(6, kCompactionStyleLevel
);
142 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
143 Add(0, 1U, "p", "q");
144 UpdateVersionStorageInfo();
146 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
147 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
148 ASSERT_TRUE(compaction
.get() == nullptr);
151 TEST_F(CompactionPickerTest
, Level0Trigger
) {
152 NewVersionStorage(6, kCompactionStyleLevel
);
153 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
154 Add(0, 1U, "150", "200");
155 Add(0, 2U, "200", "250");
157 UpdateVersionStorageInfo();
159 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
160 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
161 ASSERT_TRUE(compaction
.get() != nullptr);
162 ASSERT_EQ(2U, compaction
->num_input_files(0));
163 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
164 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
167 TEST_F(CompactionPickerTest
, Level1Trigger
) {
168 NewVersionStorage(6, kCompactionStyleLevel
);
169 Add(1, 66U, "150", "200", 1000000000U);
170 UpdateVersionStorageInfo();
172 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
173 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
174 ASSERT_TRUE(compaction
.get() != nullptr);
175 ASSERT_EQ(1U, compaction
->num_input_files(0));
176 ASSERT_EQ(66U, compaction
->input(0, 0)->fd
.GetNumber());
179 TEST_F(CompactionPickerTest
, Level1Trigger2
) {
180 mutable_cf_options_
.target_file_size_base
= 10000000000;
181 mutable_cf_options_
.RefreshDerivedOptions(ioptions_
);
182 NewVersionStorage(6, kCompactionStyleLevel
);
183 Add(1, 66U, "150", "200", 1000000001U);
184 Add(1, 88U, "201", "300", 1000000000U);
185 Add(2, 6U, "150", "179", 1000000000U);
186 Add(2, 7U, "180", "220", 1000000000U);
187 Add(2, 8U, "221", "300", 1000000000U);
188 UpdateVersionStorageInfo();
190 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
191 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
192 ASSERT_TRUE(compaction
.get() != nullptr);
193 ASSERT_EQ(1U, compaction
->num_input_files(0));
194 ASSERT_EQ(2U, compaction
->num_input_files(1));
195 ASSERT_EQ(66U, compaction
->input(0, 0)->fd
.GetNumber());
196 ASSERT_EQ(6U, compaction
->input(1, 0)->fd
.GetNumber());
197 ASSERT_EQ(7U, compaction
->input(1, 1)->fd
.GetNumber());
198 ASSERT_EQ(uint64_t{1073741824}, compaction
->OutputFilePreallocationSize());
201 TEST_F(CompactionPickerTest
, LevelMaxScore
) {
202 NewVersionStorage(6, kCompactionStyleLevel
);
203 mutable_cf_options_
.target_file_size_base
= 10000000;
204 mutable_cf_options_
.max_bytes_for_level_base
= 10 * 1024 * 1024;
205 mutable_cf_options_
.RefreshDerivedOptions(ioptions_
);
206 Add(0, 1U, "150", "200", 1000000U);
208 Add(1, 66U, "150", "200", 6000000U);
209 Add(1, 88U, "201", "300", 6000000U);
210 // Level 2 score 1.8. File 7 is the largest. Should be picked
211 Add(2, 6U, "150", "179", 60000000U);
212 Add(2, 7U, "180", "220", 60000001U);
213 Add(2, 8U, "221", "300", 60000000U);
214 // Level 3 score slightly larger than 1
215 Add(3, 26U, "150", "170", 260000000U);
216 Add(3, 27U, "171", "179", 260000000U);
217 Add(3, 28U, "191", "220", 260000000U);
218 Add(3, 29U, "221", "300", 260000000U);
219 UpdateVersionStorageInfo();
221 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
222 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
223 ASSERT_TRUE(compaction
.get() != nullptr);
224 ASSERT_EQ(1U, compaction
->num_input_files(0));
225 ASSERT_EQ(7U, compaction
->input(0, 0)->fd
.GetNumber());
226 ASSERT_EQ(mutable_cf_options_
.target_file_size_base
+
227 mutable_cf_options_
.target_file_size_base
/ 10,
228 compaction
->OutputFilePreallocationSize());
231 TEST_F(CompactionPickerTest
, NeedsCompactionLevel
) {
232 const int kLevels
= 6;
233 const int kFileCount
= 20;
235 for (int level
= 0; level
< kLevels
- 1; ++level
) {
236 NewVersionStorage(kLevels
, kCompactionStyleLevel
);
237 uint64_t file_size
= vstorage_
->MaxBytesForLevel(level
) * 2 / kFileCount
;
238 for (int file_count
= 1; file_count
<= kFileCount
; ++file_count
) {
239 // start a brand new version in each test.
240 NewVersionStorage(kLevels
, kCompactionStyleLevel
);
241 for (int i
= 0; i
< file_count
; ++i
) {
242 Add(level
, i
, ToString((i
+ 100) * 1000).c_str(),
243 ToString((i
+ 100) * 1000 + 999).c_str(),
244 file_size
, 0, i
* 100, i
* 100 + 99);
246 UpdateVersionStorageInfo();
247 ASSERT_EQ(vstorage_
->CompactionScoreLevel(0), level
);
248 ASSERT_EQ(level_compaction_picker
.NeedsCompaction(vstorage_
.get()),
249 vstorage_
->CompactionScore(0) >= 1);
250 // release the version storage
251 DeleteVersionStorage();
256 TEST_F(CompactionPickerTest
, Level0TriggerDynamic
) {
257 int num_levels
= ioptions_
.num_levels
;
258 ioptions_
.level_compaction_dynamic_level_bytes
= true;
259 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
260 mutable_cf_options_
.max_bytes_for_level_base
= 200;
261 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
262 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
263 Add(0, 1U, "150", "200");
264 Add(0, 2U, "200", "250");
266 UpdateVersionStorageInfo();
268 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
269 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
270 ASSERT_TRUE(compaction
.get() != nullptr);
271 ASSERT_EQ(2U, compaction
->num_input_files(0));
272 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
273 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
274 ASSERT_EQ(1, static_cast<int>(compaction
->num_input_levels()));
275 ASSERT_EQ(num_levels
- 1, compaction
->output_level());
278 TEST_F(CompactionPickerTest
, Level0TriggerDynamic2
) {
279 int num_levels
= ioptions_
.num_levels
;
280 ioptions_
.level_compaction_dynamic_level_bytes
= true;
281 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
282 mutable_cf_options_
.max_bytes_for_level_base
= 200;
283 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
284 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
285 Add(0, 1U, "150", "200");
286 Add(0, 2U, "200", "250");
287 Add(num_levels
- 1, 3U, "200", "250", 300U);
289 UpdateVersionStorageInfo();
290 ASSERT_EQ(vstorage_
->base_level(), num_levels
- 2);
292 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
293 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
294 ASSERT_TRUE(compaction
.get() != nullptr);
295 ASSERT_EQ(2U, compaction
->num_input_files(0));
296 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
297 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
298 ASSERT_EQ(1, static_cast<int>(compaction
->num_input_levels()));
299 ASSERT_EQ(num_levels
- 2, compaction
->output_level());
302 TEST_F(CompactionPickerTest
, Level0TriggerDynamic3
) {
303 int num_levels
= ioptions_
.num_levels
;
304 ioptions_
.level_compaction_dynamic_level_bytes
= true;
305 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
306 mutable_cf_options_
.max_bytes_for_level_base
= 200;
307 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
308 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
309 Add(0, 1U, "150", "200");
310 Add(0, 2U, "200", "250");
311 Add(num_levels
- 1, 3U, "200", "250", 300U);
312 Add(num_levels
- 1, 4U, "300", "350", 3000U);
314 UpdateVersionStorageInfo();
315 ASSERT_EQ(vstorage_
->base_level(), num_levels
- 3);
317 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
318 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
319 ASSERT_TRUE(compaction
.get() != nullptr);
320 ASSERT_EQ(2U, compaction
->num_input_files(0));
321 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
322 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
323 ASSERT_EQ(1, static_cast<int>(compaction
->num_input_levels()));
324 ASSERT_EQ(num_levels
- 3, compaction
->output_level());
327 TEST_F(CompactionPickerTest
, Level0TriggerDynamic4
) {
328 int num_levels
= ioptions_
.num_levels
;
329 ioptions_
.level_compaction_dynamic_level_bytes
= true;
330 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
331 mutable_cf_options_
.max_bytes_for_level_base
= 200;
332 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
334 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
335 Add(0, 1U, "150", "200");
336 Add(0, 2U, "200", "250");
337 Add(num_levels
- 1, 3U, "200", "250", 300U);
338 Add(num_levels
- 1, 4U, "300", "350", 3000U);
339 Add(num_levels
- 3, 5U, "150", "180", 3U);
340 Add(num_levels
- 3, 6U, "181", "300", 3U);
341 Add(num_levels
- 3, 7U, "400", "450", 3U);
343 UpdateVersionStorageInfo();
344 ASSERT_EQ(vstorage_
->base_level(), num_levels
- 3);
346 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
347 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
348 ASSERT_TRUE(compaction
.get() != nullptr);
349 ASSERT_EQ(2U, compaction
->num_input_files(0));
350 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
351 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
352 ASSERT_EQ(2U, compaction
->num_input_files(1));
353 ASSERT_EQ(num_levels
- 3, compaction
->level(1));
354 ASSERT_EQ(5U, compaction
->input(1, 0)->fd
.GetNumber());
355 ASSERT_EQ(6U, compaction
->input(1, 1)->fd
.GetNumber());
356 ASSERT_EQ(2, static_cast<int>(compaction
->num_input_levels()));
357 ASSERT_EQ(num_levels
- 3, compaction
->output_level());
360 TEST_F(CompactionPickerTest
, LevelTriggerDynamic4
) {
361 int num_levels
= ioptions_
.num_levels
;
362 ioptions_
.level_compaction_dynamic_level_bytes
= true;
363 ioptions_
.compaction_pri
= kMinOverlappingRatio
;
364 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
365 mutable_cf_options_
.max_bytes_for_level_base
= 200;
366 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
367 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
368 Add(0, 1U, "150", "200");
369 Add(num_levels
- 1, 3U, "200", "250", 300U);
370 Add(num_levels
- 1, 4U, "300", "350", 3000U);
371 Add(num_levels
- 1, 4U, "400", "450", 3U);
372 Add(num_levels
- 2, 5U, "150", "180", 300U);
373 Add(num_levels
- 2, 6U, "181", "350", 500U);
374 Add(num_levels
- 2, 7U, "400", "450", 200U);
376 UpdateVersionStorageInfo();
378 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
379 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
380 ASSERT_TRUE(compaction
.get() != nullptr);
381 ASSERT_EQ(1U, compaction
->num_input_files(0));
382 ASSERT_EQ(5U, compaction
->input(0, 0)->fd
.GetNumber());
383 ASSERT_EQ(0, compaction
->num_input_files(1));
384 ASSERT_EQ(1U, compaction
->num_input_levels());
385 ASSERT_EQ(num_levels
- 1, compaction
->output_level());
388 // Universal and FIFO Compactions are not supported in ROCKSDB_LITE
390 TEST_F(CompactionPickerTest
, NeedsCompactionUniversal
) {
391 NewVersionStorage(1, kCompactionStyleUniversal
);
392 UniversalCompactionPicker
universal_compaction_picker(
394 UpdateVersionStorageInfo();
395 // must return false when there's no files.
396 ASSERT_EQ(universal_compaction_picker
.NeedsCompaction(vstorage_
.get()),
399 // verify the trigger given different number of L0 files.
401 i
<= mutable_cf_options_
.level0_file_num_compaction_trigger
* 2; ++i
) {
402 NewVersionStorage(1, kCompactionStyleUniversal
);
403 Add(0, i
, ToString((i
+ 100) * 1000).c_str(),
404 ToString((i
+ 100) * 1000 + 999).c_str(), 1000000, 0, i
* 100,
406 UpdateVersionStorageInfo();
407 ASSERT_EQ(level_compaction_picker
.NeedsCompaction(vstorage_
.get()),
408 vstorage_
->CompactionScore(0) >= 1);
412 TEST_F(CompactionPickerTest
, CompactionUniversalIngestBehindReservedLevel
) {
413 const uint64_t kFileSize
= 100000;
414 NewVersionStorage(1, kCompactionStyleUniversal
);
415 ioptions_
.allow_ingest_behind
= true;
416 ioptions_
.num_levels
= 3;
417 UniversalCompactionPicker
universal_compaction_picker(ioptions_
, &icmp_
);
418 UpdateVersionStorageInfo();
419 // must return false when there's no files.
420 ASSERT_EQ(universal_compaction_picker
.NeedsCompaction(vstorage_
.get()),
423 NewVersionStorage(3, kCompactionStyleUniversal
);
425 Add(0, 1U, "150", "200", kFileSize
, 0, 500, 550);
426 Add(0, 2U, "201", "250", kFileSize
, 0, 401, 450);
427 Add(0, 4U, "260", "300", kFileSize
, 0, 260, 300);
428 Add(1, 5U, "100", "151", kFileSize
, 0, 200, 251);
429 Add(1, 3U, "301", "350", kFileSize
, 0, 101, 150);
430 Add(2, 6U, "120", "200", kFileSize
, 0, 20, 100);
432 UpdateVersionStorageInfo();
434 std::unique_ptr
<Compaction
> compaction(
435 universal_compaction_picker
.PickCompaction(
436 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
438 // output level should be the one above the bottom-most
439 ASSERT_EQ(1, compaction
->output_level());
441 // Tests if the files can be trivially moved in multi level
442 // universal compaction when allow_trivial_move option is set
443 // In this test as the input files overlaps, they cannot
444 // be trivially moved.
446 TEST_F(CompactionPickerTest
, CannotTrivialMoveUniversal
) {
447 const uint64_t kFileSize
= 100000;
449 mutable_cf_options_
.compaction_options_universal
.allow_trivial_move
= true;
450 NewVersionStorage(1, kCompactionStyleUniversal
);
451 UniversalCompactionPicker
universal_compaction_picker(ioptions_
, &icmp_
);
452 UpdateVersionStorageInfo();
453 // must return false when there's no files.
454 ASSERT_EQ(universal_compaction_picker
.NeedsCompaction(vstorage_
.get()),
457 NewVersionStorage(3, kCompactionStyleUniversal
);
459 Add(0, 1U, "150", "200", kFileSize
, 0, 500, 550);
460 Add(0, 2U, "201", "250", kFileSize
, 0, 401, 450);
461 Add(0, 4U, "260", "300", kFileSize
, 0, 260, 300);
462 Add(1, 5U, "100", "151", kFileSize
, 0, 200, 251);
463 Add(1, 3U, "301", "350", kFileSize
, 0, 101, 150);
464 Add(2, 6U, "120", "200", kFileSize
, 0, 20, 100);
466 UpdateVersionStorageInfo();
468 std::unique_ptr
<Compaction
> compaction(
469 universal_compaction_picker
.PickCompaction(
470 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
472 ASSERT_TRUE(!compaction
->is_trivial_move());
474 // Tests if the files can be trivially moved in multi level
475 // universal compaction when allow_trivial_move option is set
476 // In this test as the input files doesn't overlaps, they should
477 // be trivially moved.
478 TEST_F(CompactionPickerTest
, AllowsTrivialMoveUniversal
) {
479 const uint64_t kFileSize
= 100000;
481 mutable_cf_options_
.compaction_options_universal
.allow_trivial_move
= true;
482 UniversalCompactionPicker
universal_compaction_picker(ioptions_
, &icmp_
);
484 NewVersionStorage(3, kCompactionStyleUniversal
);
486 Add(0, 1U, "150", "200", kFileSize
, 0, 500, 550);
487 Add(0, 2U, "201", "250", kFileSize
, 0, 401, 450);
488 Add(0, 4U, "260", "300", kFileSize
, 0, 260, 300);
489 Add(1, 5U, "010", "080", kFileSize
, 0, 200, 251);
490 Add(2, 3U, "301", "350", kFileSize
, 0, 101, 150);
492 UpdateVersionStorageInfo();
494 std::unique_ptr
<Compaction
> compaction(
495 universal_compaction_picker
.PickCompaction(
496 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
498 ASSERT_TRUE(compaction
->is_trivial_move());
501 TEST_F(CompactionPickerTest
, NeedsCompactionFIFO
) {
502 NewVersionStorage(1, kCompactionStyleFIFO
);
503 const int kFileCount
=
504 mutable_cf_options_
.level0_file_num_compaction_trigger
* 3;
505 const uint64_t kFileSize
= 100000;
506 const uint64_t kMaxSize
= kFileSize
* kFileCount
/ 2;
508 fifo_options_
.max_table_files_size
= kMaxSize
;
509 mutable_cf_options_
.compaction_options_fifo
= fifo_options_
;
510 FIFOCompactionPicker
fifo_compaction_picker(ioptions_
, &icmp_
);
511 UpdateVersionStorageInfo();
512 // must return false when there's no files.
513 ASSERT_EQ(fifo_compaction_picker
.NeedsCompaction(vstorage_
.get()), false);
515 // verify whether compaction is needed based on the current
517 uint64_t current_size
= 0;
518 for (int i
= 1; i
<= kFileCount
; ++i
) {
519 NewVersionStorage(1, kCompactionStyleFIFO
);
520 Add(0, i
, ToString((i
+ 100) * 1000).c_str(),
521 ToString((i
+ 100) * 1000 + 999).c_str(),
522 kFileSize
, 0, i
* 100, i
* 100 + 99);
523 current_size
+= kFileSize
;
524 UpdateVersionStorageInfo();
525 ASSERT_EQ(fifo_compaction_picker
.NeedsCompaction(vstorage_
.get()),
526 vstorage_
->CompactionScore(0) >= 1);
529 #endif // ROCKSDB_LITE
531 TEST_F(CompactionPickerTest
, CompactionPriMinOverlapping1
) {
532 NewVersionStorage(6, kCompactionStyleLevel
);
533 ioptions_
.compaction_pri
= kMinOverlappingRatio
;
534 mutable_cf_options_
.target_file_size_base
= 100000000000;
535 mutable_cf_options_
.target_file_size_multiplier
= 10;
536 mutable_cf_options_
.max_bytes_for_level_base
= 10 * 1024 * 1024;
537 mutable_cf_options_
.RefreshDerivedOptions(ioptions_
);
539 Add(2, 6U, "150", "179", 50000000U);
540 Add(2, 7U, "180", "220", 50000000U);
541 Add(2, 8U, "321", "400", 50000000U); // File not overlapping
542 Add(2, 9U, "721", "800", 50000000U);
544 Add(3, 26U, "150", "170", 260000000U);
545 Add(3, 27U, "171", "179", 260000000U);
546 Add(3, 28U, "191", "220", 260000000U);
547 Add(3, 29U, "221", "300", 260000000U);
548 Add(3, 30U, "750", "900", 260000000U);
549 UpdateVersionStorageInfo();
551 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
552 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
553 ASSERT_TRUE(compaction
.get() != nullptr);
554 ASSERT_EQ(1U, compaction
->num_input_files(0));
555 // Pick file 8 because it overlaps with 0 files on level 3.
556 ASSERT_EQ(8U, compaction
->input(0, 0)->fd
.GetNumber());
557 // Compaction input size * 1.1
558 ASSERT_GE(uint64_t{55000000}, compaction
->OutputFilePreallocationSize());
561 TEST_F(CompactionPickerTest
, CompactionPriMinOverlapping2
) {
562 NewVersionStorage(6, kCompactionStyleLevel
);
563 ioptions_
.compaction_pri
= kMinOverlappingRatio
;
564 mutable_cf_options_
.target_file_size_base
= 10000000;
565 mutable_cf_options_
.target_file_size_multiplier
= 10;
566 mutable_cf_options_
.max_bytes_for_level_base
= 10 * 1024 * 1024;
568 Add(2, 6U, "150", "175",
569 60000000U); // Overlaps with file 26, 27, total size 521M
570 Add(2, 7U, "176", "200", 60000000U); // Overlaps with file 27, 28, total size
571 // 520M, the smalelst overlapping
572 Add(2, 8U, "201", "300",
573 60000000U); // Overlaps with file 28, 29, total size 521M
575 Add(3, 26U, "100", "110", 261000000U);
576 Add(3, 26U, "150", "170", 261000000U);
577 Add(3, 27U, "171", "179", 260000000U);
578 Add(3, 28U, "191", "220", 260000000U);
579 Add(3, 29U, "221", "300", 261000000U);
580 Add(3, 30U, "321", "400", 261000000U);
581 UpdateVersionStorageInfo();
583 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
584 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
585 ASSERT_TRUE(compaction
.get() != nullptr);
586 ASSERT_EQ(1U, compaction
->num_input_files(0));
587 // Picking file 7 because overlapping ratio is the biggest.
588 ASSERT_EQ(7U, compaction
->input(0, 0)->fd
.GetNumber());
591 TEST_F(CompactionPickerTest
, CompactionPriMinOverlapping3
) {
592 NewVersionStorage(6, kCompactionStyleLevel
);
593 ioptions_
.compaction_pri
= kMinOverlappingRatio
;
594 mutable_cf_options_
.max_bytes_for_level_base
= 10000000;
595 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
597 // file 7 and 8 over lap with the same file, but file 8 is smaller so
598 // it will be picked.
599 Add(2, 6U, "150", "167", 60000000U); // Overlaps with file 26, 27
600 Add(2, 7U, "168", "169", 60000000U); // Overlaps with file 27
601 Add(2, 8U, "201", "300", 61000000U); // Overlaps with file 28, but the file
602 // itself is larger. Should be picked.
604 Add(3, 26U, "160", "165", 260000000U);
605 Add(3, 27U, "166", "170", 260000000U);
606 Add(3, 28U, "180", "400", 260000000U);
607 Add(3, 29U, "401", "500", 260000000U);
608 UpdateVersionStorageInfo();
610 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
611 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
612 ASSERT_TRUE(compaction
.get() != nullptr);
613 ASSERT_EQ(1U, compaction
->num_input_files(0));
614 // Picking file 8 because overlapping ratio is the biggest.
615 ASSERT_EQ(8U, compaction
->input(0, 0)->fd
.GetNumber());
618 // This test exhibits the bug where we don't properly reset parent_index in
620 TEST_F(CompactionPickerTest
, ParentIndexResetBug
) {
621 int num_levels
= ioptions_
.num_levels
;
622 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
623 mutable_cf_options_
.max_bytes_for_level_base
= 200;
624 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
625 Add(0, 1U, "150", "200"); // <- marked for compaction
626 Add(1, 3U, "400", "500", 600); // <- this one needs compacting
627 Add(2, 4U, "150", "200");
628 Add(2, 5U, "201", "210");
629 Add(2, 6U, "300", "310");
630 Add(2, 7U, "400", "500"); // <- being compacted
632 vstorage_
->LevelFiles(2)[3]->being_compacted
= true;
633 vstorage_
->LevelFiles(0)[0]->marked_for_compaction
= true;
635 UpdateVersionStorageInfo();
637 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
638 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
641 // This test checks ExpandWhileOverlapping() by having overlapping user keys
642 // ranges (with different sequence numbers) in the input files.
643 TEST_F(CompactionPickerTest
, OverlappingUserKeys
) {
644 NewVersionStorage(6, kCompactionStyleLevel
);
645 ioptions_
.compaction_pri
= kByCompensatedSize
;
647 Add(1, 1U, "100", "150", 1U);
648 // Overlapping user keys
649 Add(1, 2U, "200", "400", 1U);
650 Add(1, 3U, "400", "500", 1000000000U, 0, 0);
651 Add(2, 4U, "600", "700", 1U);
652 UpdateVersionStorageInfo();
654 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
655 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
656 ASSERT_TRUE(compaction
.get() != nullptr);
657 ASSERT_EQ(1U, compaction
->num_input_levels());
658 ASSERT_EQ(2U, compaction
->num_input_files(0));
659 ASSERT_EQ(2U, compaction
->input(0, 0)->fd
.GetNumber());
660 ASSERT_EQ(3U, compaction
->input(0, 1)->fd
.GetNumber());
663 TEST_F(CompactionPickerTest
, OverlappingUserKeys2
) {
664 NewVersionStorage(6, kCompactionStyleLevel
);
665 // Overlapping user keys on same level and output level
666 Add(1, 1U, "200", "400", 1000000000U);
667 Add(1, 2U, "400", "500", 1U, 0, 0);
668 Add(2, 3U, "000", "100", 1U);
669 Add(2, 4U, "100", "600", 1U, 0, 0);
670 Add(2, 5U, "600", "700", 1U, 0, 0);
671 UpdateVersionStorageInfo();
673 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
674 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
675 ASSERT_TRUE(compaction
.get() != nullptr);
676 ASSERT_EQ(2U, compaction
->num_input_levels());
677 ASSERT_EQ(2U, compaction
->num_input_files(0));
678 ASSERT_EQ(3U, compaction
->num_input_files(1));
679 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
680 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
681 ASSERT_EQ(3U, compaction
->input(1, 0)->fd
.GetNumber());
682 ASSERT_EQ(4U, compaction
->input(1, 1)->fd
.GetNumber());
683 ASSERT_EQ(5U, compaction
->input(1, 2)->fd
.GetNumber());
686 TEST_F(CompactionPickerTest
, OverlappingUserKeys3
) {
687 NewVersionStorage(6, kCompactionStyleLevel
);
688 // Chain of overlapping user key ranges (forces ExpandWhileOverlapping() to
689 // expand multiple times)
690 Add(1, 1U, "100", "150", 1U);
691 Add(1, 2U, "150", "200", 1U, 0, 0);
692 Add(1, 3U, "200", "250", 1000000000U, 0, 0);
693 Add(1, 4U, "250", "300", 1U, 0, 0);
694 Add(1, 5U, "300", "350", 1U, 0, 0);
695 // Output level overlaps with the beginning and the end of the chain
696 Add(2, 6U, "050", "100", 1U);
697 Add(2, 7U, "350", "400", 1U);
698 UpdateVersionStorageInfo();
700 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
701 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
702 ASSERT_TRUE(compaction
.get() != nullptr);
703 ASSERT_EQ(2U, compaction
->num_input_levels());
704 ASSERT_EQ(5U, compaction
->num_input_files(0));
705 ASSERT_EQ(2U, compaction
->num_input_files(1));
706 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
707 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
708 ASSERT_EQ(3U, compaction
->input(0, 2)->fd
.GetNumber());
709 ASSERT_EQ(4U, compaction
->input(0, 3)->fd
.GetNumber());
710 ASSERT_EQ(5U, compaction
->input(0, 4)->fd
.GetNumber());
711 ASSERT_EQ(6U, compaction
->input(1, 0)->fd
.GetNumber());
712 ASSERT_EQ(7U, compaction
->input(1, 1)->fd
.GetNumber());
715 TEST_F(CompactionPickerTest
, OverlappingUserKeys4
) {
716 NewVersionStorage(6, kCompactionStyleLevel
);
717 mutable_cf_options_
.max_bytes_for_level_base
= 1000000;
719 Add(1, 1U, "100", "150", 1U);
720 Add(1, 2U, "150", "199", 1U, 0, 0);
721 Add(1, 3U, "200", "250", 1100000U, 0, 0);
722 Add(1, 4U, "251", "300", 1U, 0, 0);
723 Add(1, 5U, "300", "350", 1U, 0, 0);
725 Add(2, 6U, "100", "115", 1U);
726 Add(2, 7U, "125", "325", 1U);
727 Add(2, 8U, "350", "400", 1U);
728 UpdateVersionStorageInfo();
730 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
731 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
732 ASSERT_TRUE(compaction
.get() != nullptr);
733 ASSERT_EQ(2U, compaction
->num_input_levels());
734 ASSERT_EQ(1U, compaction
->num_input_files(0));
735 ASSERT_EQ(1U, compaction
->num_input_files(1));
736 ASSERT_EQ(3U, compaction
->input(0, 0)->fd
.GetNumber());
737 ASSERT_EQ(7U, compaction
->input(1, 0)->fd
.GetNumber());
740 TEST_F(CompactionPickerTest
, OverlappingUserKeys5
) {
741 NewVersionStorage(6, kCompactionStyleLevel
);
742 // Overlapping user keys on same level and output level
743 Add(1, 1U, "200", "400", 1000000000U);
744 Add(1, 2U, "400", "500", 1U, 0, 0);
745 Add(2, 3U, "000", "100", 1U);
746 Add(2, 4U, "100", "600", 1U, 0, 0);
747 Add(2, 5U, "600", "700", 1U, 0, 0);
749 vstorage_
->LevelFiles(2)[2]->being_compacted
= true;
751 UpdateVersionStorageInfo();
753 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
754 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
755 ASSERT_TRUE(compaction
.get() == nullptr);
758 TEST_F(CompactionPickerTest
, OverlappingUserKeys6
) {
759 NewVersionStorage(6, kCompactionStyleLevel
);
760 // Overlapping user keys on same level and output level
761 Add(1, 1U, "200", "400", 1U, 0, 0);
762 Add(1, 2U, "401", "500", 1U, 0, 0);
763 Add(2, 3U, "000", "100", 1U);
764 Add(2, 4U, "100", "300", 1U, 0, 0);
765 Add(2, 5U, "305", "450", 1U, 0, 0);
766 Add(2, 6U, "460", "600", 1U, 0, 0);
767 Add(2, 7U, "600", "700", 1U, 0, 0);
769 vstorage_
->LevelFiles(1)[0]->marked_for_compaction
= true;
770 vstorage_
->LevelFiles(1)[1]->marked_for_compaction
= true;
772 UpdateVersionStorageInfo();
774 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
775 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
776 ASSERT_TRUE(compaction
.get() != nullptr);
777 ASSERT_EQ(2U, compaction
->num_input_levels());
778 ASSERT_EQ(1U, compaction
->num_input_files(0));
779 ASSERT_EQ(3U, compaction
->num_input_files(1));
782 TEST_F(CompactionPickerTest
, OverlappingUserKeys7
) {
783 NewVersionStorage(6, kCompactionStyleLevel
);
784 mutable_cf_options_
.max_compaction_bytes
= 100000000000u;
785 // Overlapping user keys on same level and output level
786 Add(1, 1U, "200", "400", 1U, 0, 0);
787 Add(1, 2U, "401", "500", 1000000000U, 0, 0);
788 Add(2, 3U, "100", "250", 1U);
789 Add(2, 4U, "300", "600", 1U, 0, 0);
790 Add(2, 5U, "600", "800", 1U, 0, 0);
792 UpdateVersionStorageInfo();
794 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
795 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
796 ASSERT_TRUE(compaction
.get() != nullptr);
797 ASSERT_EQ(2U, compaction
->num_input_levels());
798 ASSERT_GE(1U, compaction
->num_input_files(0));
799 ASSERT_GE(2U, compaction
->num_input_files(1));
800 // File 5 has to be included in the compaction
801 ASSERT_EQ(5U, compaction
->inputs(1)->back()->fd
.GetNumber());
804 TEST_F(CompactionPickerTest
, OverlappingUserKeys8
) {
805 NewVersionStorage(6, kCompactionStyleLevel
);
806 mutable_cf_options_
.max_compaction_bytes
= 100000000000u;
807 // grow the number of inputs in "level" without
808 // changing the number of "level+1" files we pick up
809 // Expand input level as much as possible
810 // no overlapping case
811 Add(1, 1U, "101", "150", 1U);
812 Add(1, 2U, "151", "200", 1U);
813 Add(1, 3U, "201", "300", 1000000000U);
814 Add(1, 4U, "301", "400", 1U);
815 Add(1, 5U, "401", "500", 1U);
816 Add(2, 6U, "150", "200", 1U);
817 Add(2, 7U, "200", "450", 1U, 0, 0);
818 Add(2, 8U, "500", "600", 1U);
820 UpdateVersionStorageInfo();
822 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
823 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
824 ASSERT_TRUE(compaction
.get() != nullptr);
825 ASSERT_EQ(2U, compaction
->num_input_levels());
826 ASSERT_EQ(3U, compaction
->num_input_files(0));
827 ASSERT_EQ(2U, compaction
->num_input_files(1));
828 ASSERT_EQ(2U, compaction
->input(0, 0)->fd
.GetNumber());
829 ASSERT_EQ(3U, compaction
->input(0, 1)->fd
.GetNumber());
830 ASSERT_EQ(4U, compaction
->input(0, 2)->fd
.GetNumber());
831 ASSERT_EQ(6U, compaction
->input(1, 0)->fd
.GetNumber());
832 ASSERT_EQ(7U, compaction
->input(1, 1)->fd
.GetNumber());
835 TEST_F(CompactionPickerTest
, OverlappingUserKeys9
) {
836 NewVersionStorage(6, kCompactionStyleLevel
);
837 mutable_cf_options_
.max_compaction_bytes
= 100000000000u;
838 // grow the number of inputs in "level" without
839 // changing the number of "level+1" files we pick up
840 // Expand input level as much as possible
842 Add(1, 1U, "121", "150", 1U);
843 Add(1, 2U, "151", "200", 1U);
844 Add(1, 3U, "201", "300", 1000000000U);
845 Add(1, 4U, "301", "400", 1U);
846 Add(1, 5U, "401", "500", 1U);
847 Add(2, 6U, "100", "120", 1U);
848 Add(2, 7U, "150", "200", 1U);
849 Add(2, 8U, "200", "450", 1U, 0, 0);
850 Add(2, 9U, "501", "600", 1U);
852 UpdateVersionStorageInfo();
854 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
855 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
856 ASSERT_TRUE(compaction
.get() != nullptr);
857 ASSERT_EQ(2U, compaction
->num_input_levels());
858 ASSERT_EQ(5U, compaction
->num_input_files(0));
859 ASSERT_EQ(2U, compaction
->num_input_files(1));
860 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
861 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
862 ASSERT_EQ(3U, compaction
->input(0, 2)->fd
.GetNumber());
863 ASSERT_EQ(4U, compaction
->input(0, 3)->fd
.GetNumber());
864 ASSERT_EQ(7U, compaction
->input(1, 0)->fd
.GetNumber());
865 ASSERT_EQ(8U, compaction
->input(1, 1)->fd
.GetNumber());
868 TEST_F(CompactionPickerTest
, OverlappingUserKeys10
) {
869 // Locked file encountered when pulling in extra input-level files with same
870 // user keys. Verify we pick the next-best file from the same input level.
871 NewVersionStorage(6, kCompactionStyleLevel
);
872 mutable_cf_options_
.max_compaction_bytes
= 100000000000u;
874 // file_number 2U is largest and thus first choice. But it overlaps with
875 // file_number 1U which is being compacted. So instead we pick the next-
876 // biggest file, 3U, which is eligible for compaction.
877 Add(1 /* level */, 1U /* file_number */, "100" /* smallest */,
878 "150" /* largest */, 1U /* file_size */);
879 file_map_
[1U].first
->being_compacted
= true;
880 Add(1 /* level */, 2U /* file_number */, "150" /* smallest */,
881 "200" /* largest */, 1000000000U /* file_size */, 0 /* smallest_seq */,
882 0 /* largest_seq */);
883 Add(1 /* level */, 3U /* file_number */, "201" /* smallest */,
884 "250" /* largest */, 900000000U /* file_size */);
885 Add(2 /* level */, 4U /* file_number */, "100" /* smallest */,
886 "150" /* largest */, 1U /* file_size */);
887 Add(2 /* level */, 5U /* file_number */, "151" /* smallest */,
888 "200" /* largest */, 1U /* file_size */);
889 Add(2 /* level */, 6U /* file_number */, "201" /* smallest */,
890 "250" /* largest */, 1U /* file_size */);
892 UpdateVersionStorageInfo();
894 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
895 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
896 ASSERT_TRUE(compaction
.get() != nullptr);
897 ASSERT_EQ(2U, compaction
->num_input_levels());
898 ASSERT_EQ(1U, compaction
->num_input_files(0));
899 ASSERT_EQ(1U, compaction
->num_input_files(1));
900 ASSERT_EQ(3U, compaction
->input(0, 0)->fd
.GetNumber());
901 ASSERT_EQ(6U, compaction
->input(1, 0)->fd
.GetNumber());
904 TEST_F(CompactionPickerTest
, OverlappingUserKeys11
) {
905 // Locked file encountered when pulling in extra output-level files with same
906 // user keys. Expected to skip that compaction and pick the next-best choice.
907 NewVersionStorage(6, kCompactionStyleLevel
);
908 mutable_cf_options_
.max_compaction_bytes
= 100000000000u;
912 // There is no eligible file in L1 to compact since both candidates pull in
913 // file_number 5U, which overlaps with a file pending compaction (6U). The
914 // first eligible compaction is from L2->L3.
915 Add(1 /* level */, 2U /* file_number */, "151" /* smallest */,
916 "200" /* largest */, 1000000000U /* file_size */);
917 Add(1 /* level */, 3U /* file_number */, "201" /* smallest */,
918 "250" /* largest */, 1U /* file_size */);
919 Add(2 /* level */, 4U /* file_number */, "100" /* smallest */,
920 "149" /* largest */, 5000000000U /* file_size */);
921 Add(2 /* level */, 5U /* file_number */, "150" /* smallest */,
922 "201" /* largest */, 1U /* file_size */);
923 Add(2 /* level */, 6U /* file_number */, "201" /* smallest */,
924 "249" /* largest */, 1U /* file_size */, 0 /* smallest_seq */,
925 0 /* largest_seq */);
926 file_map_
[6U].first
->being_compacted
= true;
927 Add(3 /* level */, 7U /* file_number */, "100" /* smallest */,
928 "149" /* largest */, 1U /* file_size */);
930 UpdateVersionStorageInfo();
932 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
933 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
934 ASSERT_TRUE(compaction
.get() != nullptr);
935 ASSERT_EQ(2U, compaction
->num_input_levels());
936 ASSERT_EQ(1U, compaction
->num_input_files(0));
937 ASSERT_EQ(1U, compaction
->num_input_files(1));
938 ASSERT_EQ(4U, compaction
->input(0, 0)->fd
.GetNumber());
939 ASSERT_EQ(7U, compaction
->input(1, 0)->fd
.GetNumber());
942 TEST_F(CompactionPickerTest
, NotScheduleL1IfL0WithHigherPri1
) {
943 NewVersionStorage(6, kCompactionStyleLevel
);
944 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
945 mutable_cf_options_
.max_bytes_for_level_base
= 900000000U;
947 // 6 L0 files, score 3.
948 Add(0, 1U, "000", "400", 1U);
949 Add(0, 2U, "001", "400", 1U, 0, 0);
950 Add(0, 3U, "001", "400", 1000000000U, 0, 0);
951 Add(0, 31U, "001", "400", 1000000000U, 0, 0);
952 Add(0, 32U, "001", "400", 1000000000U, 0, 0);
953 Add(0, 33U, "001", "400", 1000000000U, 0, 0);
955 // L1 total size 2GB, score 2.2. If one file being comapcted, score 1.1.
956 Add(1, 4U, "050", "300", 1000000000U, 0, 0);
957 file_map_
[4u].first
->being_compacted
= true;
958 Add(1, 5U, "301", "350", 1000000000U, 0, 0);
960 // Output level overlaps with the beginning and the end of the chain
961 Add(2, 6U, "050", "100", 1U);
962 Add(2, 7U, "300", "400", 1U);
964 // No compaction should be scheduled, if L0 has higher priority than L1
965 // but L0->L1 compaction is blocked by a file in L1 being compacted.
966 UpdateVersionStorageInfo();
967 ASSERT_EQ(0, vstorage_
->CompactionScoreLevel(0));
968 ASSERT_EQ(1, vstorage_
->CompactionScoreLevel(1));
969 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
970 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
971 ASSERT_TRUE(compaction
.get() == nullptr);
974 TEST_F(CompactionPickerTest
, NotScheduleL1IfL0WithHigherPri2
) {
975 NewVersionStorage(6, kCompactionStyleLevel
);
976 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
977 mutable_cf_options_
.max_bytes_for_level_base
= 900000000U;
979 // 6 L0 files, score 3.
980 Add(0, 1U, "000", "400", 1U);
981 Add(0, 2U, "001", "400", 1U, 0, 0);
982 Add(0, 3U, "001", "400", 1000000000U, 0, 0);
983 Add(0, 31U, "001", "400", 1000000000U, 0, 0);
984 Add(0, 32U, "001", "400", 1000000000U, 0, 0);
985 Add(0, 33U, "001", "400", 1000000000U, 0, 0);
987 // L1 total size 2GB, score 2.2. If one file being comapcted, score 1.1.
988 Add(1, 4U, "050", "300", 1000000000U, 0, 0);
989 Add(1, 5U, "301", "350", 1000000000U, 0, 0);
991 // Output level overlaps with the beginning and the end of the chain
992 Add(2, 6U, "050", "100", 1U);
993 Add(2, 7U, "300", "400", 1U);
995 // If no file in L1 being compacted, L0->L1 compaction will be scheduled.
996 UpdateVersionStorageInfo(); // being_compacted flag is cleared here.
997 ASSERT_EQ(0, vstorage_
->CompactionScoreLevel(0));
998 ASSERT_EQ(1, vstorage_
->CompactionScoreLevel(1));
999 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
1000 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1001 ASSERT_TRUE(compaction
.get() != nullptr);
1004 TEST_F(CompactionPickerTest
, NotScheduleL1IfL0WithHigherPri3
) {
1005 NewVersionStorage(6, kCompactionStyleLevel
);
1006 mutable_cf_options_
.level0_file_num_compaction_trigger
= 2;
1007 mutable_cf_options_
.max_bytes_for_level_base
= 900000000U;
1009 // 6 L0 files, score 3.
1010 Add(0, 1U, "000", "400", 1U);
1011 Add(0, 2U, "001", "400", 1U, 0, 0);
1012 Add(0, 3U, "001", "400", 1000000000U, 0, 0);
1013 Add(0, 31U, "001", "400", 1000000000U, 0, 0);
1014 Add(0, 32U, "001", "400", 1000000000U, 0, 0);
1015 Add(0, 33U, "001", "400", 1000000000U, 0, 0);
1017 // L1 score more than 6.
1018 Add(1, 4U, "050", "300", 1000000000U, 0, 0);
1019 file_map_
[4u].first
->being_compacted
= true;
1020 Add(1, 5U, "301", "350", 1000000000U, 0, 0);
1021 Add(1, 51U, "351", "400", 6000000000U, 0, 0);
1023 // Output level overlaps with the beginning and the end of the chain
1024 Add(2, 6U, "050", "100", 1U);
1025 Add(2, 7U, "300", "400", 1U);
1027 // If score in L1 is larger than L0, L1 compaction goes through despite
1028 // there is pending L0 compaction.
1029 UpdateVersionStorageInfo();
1030 ASSERT_EQ(1, vstorage_
->CompactionScoreLevel(0));
1031 ASSERT_EQ(0, vstorage_
->CompactionScoreLevel(1));
1032 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
1033 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1034 ASSERT_TRUE(compaction
.get() != nullptr);
1037 TEST_F(CompactionPickerTest
, EstimateCompactionBytesNeeded1
) {
1038 int num_levels
= ioptions_
.num_levels
;
1039 ioptions_
.level_compaction_dynamic_level_bytes
= false;
1040 mutable_cf_options_
.level0_file_num_compaction_trigger
= 4;
1041 mutable_cf_options_
.max_bytes_for_level_base
= 1000;
1042 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
1043 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
1044 Add(0, 1U, "150", "200", 200);
1045 Add(0, 2U, "150", "200", 200);
1046 Add(0, 3U, "150", "200", 200);
1047 // Level 1 is over target by 200
1048 Add(1, 4U, "400", "500", 600);
1049 Add(1, 5U, "600", "700", 600);
1050 // Level 2 is less than target 10000 even added size of level 1
1051 // Size ratio of L2/L1 is 9600 / 1200 = 8
1052 Add(2, 6U, "150", "200", 2500);
1053 Add(2, 7U, "201", "210", 2000);
1054 Add(2, 8U, "300", "310", 2600);
1055 Add(2, 9U, "400", "500", 2500);
1056 // Level 3 exceeds target 100,000 of 1000
1057 Add(3, 10U, "400", "500", 101000);
1058 // Level 4 exceeds target 1,000,000 by 900 after adding size from level 3
1059 // Size ratio L4/L3 is 9.9
1060 // After merge from L3, L4 size is 1000900
1061 Add(4, 11U, "400", "500", 999900);
1062 Add(5, 11U, "400", "500", 8007200);
1064 UpdateVersionStorageInfo();
1066 ASSERT_EQ(200u * 9u + 10900u + 900u * 9,
1067 vstorage_
->estimated_compaction_needed_bytes());
1070 TEST_F(CompactionPickerTest
, EstimateCompactionBytesNeeded2
) {
1071 int num_levels
= ioptions_
.num_levels
;
1072 ioptions_
.level_compaction_dynamic_level_bytes
= false;
1073 mutable_cf_options_
.level0_file_num_compaction_trigger
= 3;
1074 mutable_cf_options_
.max_bytes_for_level_base
= 1000;
1075 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
1076 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
1077 Add(0, 1U, "150", "200", 200);
1078 Add(0, 2U, "150", "200", 200);
1079 Add(0, 4U, "150", "200", 200);
1080 Add(0, 5U, "150", "200", 200);
1081 Add(0, 6U, "150", "200", 200);
1082 // Level 1 size will be 1400 after merging with L0
1083 Add(1, 7U, "400", "500", 200);
1084 Add(1, 8U, "600", "700", 200);
1085 // Level 2 is less than target 10000 even added size of level 1
1086 Add(2, 9U, "150", "200", 9100);
1087 // Level 3 over the target, but since level 4 is empty, we assume it will be
1089 Add(3, 10U, "400", "500", 101000);
1091 UpdateVersionStorageInfo();
1093 // estimated L1->L2 merge: 400 * (9100.0 / 1400.0 + 1.0)
1094 ASSERT_EQ(1400u + 3000u, vstorage_
->estimated_compaction_needed_bytes());
1097 TEST_F(CompactionPickerTest
, EstimateCompactionBytesNeeded3
) {
1098 int num_levels
= ioptions_
.num_levels
;
1099 ioptions_
.level_compaction_dynamic_level_bytes
= false;
1100 mutable_cf_options_
.level0_file_num_compaction_trigger
= 3;
1101 mutable_cf_options_
.max_bytes_for_level_base
= 1000;
1102 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
1103 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
1104 Add(0, 1U, "150", "200", 2000);
1105 Add(0, 2U, "150", "200", 2000);
1106 Add(0, 4U, "150", "200", 2000);
1107 Add(0, 5U, "150", "200", 2000);
1108 Add(0, 6U, "150", "200", 1000);
1109 // Level 1 size will be 10000 after merging with L0
1110 Add(1, 7U, "400", "500", 500);
1111 Add(1, 8U, "600", "700", 500);
1113 Add(2, 9U, "150", "200", 10000);
1115 UpdateVersionStorageInfo();
1117 ASSERT_EQ(10000u + 18000u, vstorage_
->estimated_compaction_needed_bytes());
1120 TEST_F(CompactionPickerTest
, EstimateCompactionBytesNeededDynamicLevel
) {
1121 int num_levels
= ioptions_
.num_levels
;
1122 ioptions_
.level_compaction_dynamic_level_bytes
= true;
1123 mutable_cf_options_
.level0_file_num_compaction_trigger
= 3;
1124 mutable_cf_options_
.max_bytes_for_level_base
= 1000;
1125 mutable_cf_options_
.max_bytes_for_level_multiplier
= 10;
1126 NewVersionStorage(num_levels
, kCompactionStyleLevel
);
1128 // Set Last level size 50000
1129 // num_levels - 1 target 5000
1130 // num_levels - 2 is base level with target 1000 (rounded up to
1131 // max_bytes_for_level_base).
1132 Add(num_levels
- 1, 10U, "400", "500", 50000);
1134 Add(0, 1U, "150", "200", 200);
1135 Add(0, 2U, "150", "200", 200);
1136 Add(0, 4U, "150", "200", 200);
1137 Add(0, 5U, "150", "200", 200);
1138 Add(0, 6U, "150", "200", 200);
1139 // num_levels - 3 is over target by 100 + 1000
1140 Add(num_levels
- 3, 7U, "400", "500", 550);
1141 Add(num_levels
- 3, 8U, "600", "700", 550);
1142 // num_levels - 2 is over target by 1100 + 200
1143 Add(num_levels
- 2, 9U, "150", "200", 5200);
1145 UpdateVersionStorageInfo();
1147 // Merging to the second last level: (5200 / 2100 + 1) * 1100
1148 // Merging to the last level: (50000 / 6300 + 1) * 1300
1149 ASSERT_EQ(2100u + 3823u + 11617u,
1150 vstorage_
->estimated_compaction_needed_bytes());
1153 TEST_F(CompactionPickerTest
, IsBottommostLevelTest
) {
1154 // case 1: Higher levels are empty
1155 NewVersionStorage(6, kCompactionStyleLevel
);
1156 Add(0, 1U, "a", "m");
1157 Add(0, 2U, "c", "z");
1158 Add(1, 3U, "d", "e");
1159 Add(1, 4U, "l", "p");
1160 Add(2, 5U, "g", "i");
1161 Add(2, 6U, "x", "z");
1162 UpdateVersionStorageInfo();
1163 SetCompactionInputFilesLevels(2, 1);
1164 AddToCompactionFiles(3U);
1165 AddToCompactionFiles(5U);
1167 Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1168 ASSERT_TRUE(result
);
1170 // case 2: Higher levels have no overlap
1171 NewVersionStorage(6, kCompactionStyleLevel
);
1172 Add(0, 1U, "a", "m");
1173 Add(0, 2U, "c", "z");
1174 Add(1, 3U, "d", "e");
1175 Add(1, 4U, "l", "p");
1176 Add(2, 5U, "g", "i");
1177 Add(2, 6U, "x", "z");
1178 Add(3, 7U, "k", "p");
1179 Add(3, 8U, "t", "w");
1180 Add(4, 9U, "a", "b");
1181 Add(5, 10U, "c", "cc");
1182 UpdateVersionStorageInfo();
1183 SetCompactionInputFilesLevels(2, 1);
1184 AddToCompactionFiles(3U);
1185 AddToCompactionFiles(5U);
1186 result
= Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1187 ASSERT_TRUE(result
);
1189 // case 3.1: Higher levels (level 3) have overlap
1190 NewVersionStorage(6, kCompactionStyleLevel
);
1191 Add(0, 1U, "a", "m");
1192 Add(0, 2U, "c", "z");
1193 Add(1, 3U, "d", "e");
1194 Add(1, 4U, "l", "p");
1195 Add(2, 5U, "g", "i");
1196 Add(2, 6U, "x", "z");
1197 Add(3, 7U, "e", "g");
1198 Add(3, 8U, "h", "k");
1199 Add(4, 9U, "a", "b");
1200 Add(5, 10U, "c", "cc");
1201 UpdateVersionStorageInfo();
1202 SetCompactionInputFilesLevels(2, 1);
1203 AddToCompactionFiles(3U);
1204 AddToCompactionFiles(5U);
1205 result
= Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1206 ASSERT_FALSE(result
);
1208 // case 3.2: Higher levels (level 5) have overlap
1209 DeleteVersionStorage();
1210 NewVersionStorage(6, kCompactionStyleLevel
);
1211 Add(0, 1U, "a", "m");
1212 Add(0, 2U, "c", "z");
1213 Add(1, 3U, "d", "e");
1214 Add(1, 4U, "l", "p");
1215 Add(2, 5U, "g", "i");
1216 Add(2, 6U, "x", "z");
1217 Add(3, 7U, "j", "k");
1218 Add(3, 8U, "l", "m");
1219 Add(4, 9U, "a", "b");
1220 Add(5, 10U, "c", "cc");
1221 Add(5, 11U, "h", "k");
1222 Add(5, 12U, "y", "yy");
1223 Add(5, 13U, "z", "zz");
1224 UpdateVersionStorageInfo();
1225 SetCompactionInputFilesLevels(2, 1);
1226 AddToCompactionFiles(3U);
1227 AddToCompactionFiles(5U);
1228 result
= Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1229 ASSERT_FALSE(result
);
1231 // case 3.3: Higher levels (level 5) have overlap, but it's only overlapping
1233 NewVersionStorage(6, kCompactionStyleLevel
);
1234 Add(0, 1U, "a", "m");
1235 Add(0, 2U, "c", "z");
1236 Add(1, 3U, "d", "e");
1237 Add(1, 4U, "l", "p");
1238 Add(2, 5U, "g", "i");
1239 Add(2, 6U, "x", "z");
1240 Add(3, 7U, "j", "k");
1241 Add(3, 8U, "l", "m");
1242 Add(4, 9U, "a", "b");
1243 Add(5, 10U, "c", "cc");
1244 Add(5, 11U, "ccc", "d");
1245 Add(5, 12U, "y", "yy");
1246 Add(5, 13U, "z", "zz");
1247 UpdateVersionStorageInfo();
1248 SetCompactionInputFilesLevels(2, 1);
1249 AddToCompactionFiles(3U);
1250 AddToCompactionFiles(5U);
1251 result
= Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1252 ASSERT_FALSE(result
);
1254 // Level 0 files overlap
1255 NewVersionStorage(6, kCompactionStyleLevel
);
1256 Add(0, 1U, "s", "t");
1257 Add(0, 2U, "a", "m");
1258 Add(0, 3U, "b", "z");
1259 Add(0, 4U, "e", "f");
1260 Add(5, 10U, "y", "z");
1261 UpdateVersionStorageInfo();
1262 SetCompactionInputFilesLevels(1, 0);
1263 AddToCompactionFiles(1U);
1264 AddToCompactionFiles(2U);
1265 AddToCompactionFiles(3U);
1266 AddToCompactionFiles(4U);
1267 result
= Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1268 ASSERT_FALSE(result
);
1270 // Level 0 files don't overlap
1271 NewVersionStorage(6, kCompactionStyleLevel
);
1272 Add(0, 1U, "s", "t");
1273 Add(0, 2U, "a", "m");
1274 Add(0, 3U, "b", "k");
1275 Add(0, 4U, "e", "f");
1276 Add(5, 10U, "y", "z");
1277 UpdateVersionStorageInfo();
1278 SetCompactionInputFilesLevels(1, 0);
1279 AddToCompactionFiles(1U);
1280 AddToCompactionFiles(2U);
1281 AddToCompactionFiles(3U);
1282 AddToCompactionFiles(4U);
1283 result
= Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1284 ASSERT_TRUE(result
);
1286 // Level 1 files overlap
1287 NewVersionStorage(6, kCompactionStyleLevel
);
1288 Add(0, 1U, "s", "t");
1289 Add(0, 2U, "a", "m");
1290 Add(0, 3U, "b", "k");
1291 Add(0, 4U, "e", "f");
1292 Add(1, 5U, "a", "m");
1293 Add(1, 6U, "n", "o");
1294 Add(1, 7U, "w", "y");
1295 Add(5, 10U, "y", "z");
1296 UpdateVersionStorageInfo();
1297 SetCompactionInputFilesLevels(2, 0);
1298 AddToCompactionFiles(1U);
1299 AddToCompactionFiles(2U);
1300 AddToCompactionFiles(3U);
1301 AddToCompactionFiles(4U);
1302 AddToCompactionFiles(5U);
1303 AddToCompactionFiles(6U);
1304 AddToCompactionFiles(7U);
1305 result
= Compaction::TEST_IsBottommostLevel(2, vstorage_
.get(), input_files_
);
1306 ASSERT_FALSE(result
);
1308 DeleteVersionStorage();
1311 TEST_F(CompactionPickerTest
, MaxCompactionBytesHit
) {
1312 mutable_cf_options_
.max_bytes_for_level_base
= 1000000u;
1313 mutable_cf_options_
.max_compaction_bytes
= 800000u;
1314 ioptions_
.level_compaction_dynamic_level_bytes
= false;
1315 NewVersionStorage(6, kCompactionStyleLevel
);
1316 // A compaction should be triggered and pick file 2 and 5.
1317 // It can expand because adding file 1 and 3, the compaction size will
1318 // exceed mutable_cf_options_.max_bytes_for_level_base.
1319 Add(1, 1U, "100", "150", 300000U);
1320 Add(1, 2U, "151", "200", 300001U, 0, 0);
1321 Add(1, 3U, "201", "250", 300000U, 0, 0);
1322 Add(1, 4U, "251", "300", 300000U, 0, 0);
1323 Add(2, 5U, "100", "256", 1U);
1324 UpdateVersionStorageInfo();
1326 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
1327 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1328 ASSERT_TRUE(compaction
.get() != nullptr);
1329 ASSERT_EQ(2U, compaction
->num_input_levels());
1330 ASSERT_EQ(1U, compaction
->num_input_files(0));
1331 ASSERT_EQ(1U, compaction
->num_input_files(1));
1332 ASSERT_EQ(2U, compaction
->input(0, 0)->fd
.GetNumber());
1333 ASSERT_EQ(5U, compaction
->input(1, 0)->fd
.GetNumber());
1336 TEST_F(CompactionPickerTest
, MaxCompactionBytesNotHit
) {
1337 mutable_cf_options_
.max_bytes_for_level_base
= 800000u;
1338 mutable_cf_options_
.max_compaction_bytes
= 1000000u;
1339 ioptions_
.level_compaction_dynamic_level_bytes
= false;
1340 NewVersionStorage(6, kCompactionStyleLevel
);
1341 // A compaction should be triggered and pick file 2 and 5.
1342 // and it expands to file 1 and 3 too.
1343 Add(1, 1U, "100", "150", 300000U);
1344 Add(1, 2U, "151", "200", 300001U, 0, 0);
1345 Add(1, 3U, "201", "250", 300000U, 0, 0);
1346 Add(1, 4U, "251", "300", 300000U, 0, 0);
1347 Add(2, 5U, "000", "251", 1U);
1348 UpdateVersionStorageInfo();
1350 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
1351 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1352 ASSERT_TRUE(compaction
.get() != nullptr);
1353 ASSERT_EQ(2U, compaction
->num_input_levels());
1354 ASSERT_EQ(3U, compaction
->num_input_files(0));
1355 ASSERT_EQ(1U, compaction
->num_input_files(1));
1356 ASSERT_EQ(1U, compaction
->input(0, 0)->fd
.GetNumber());
1357 ASSERT_EQ(2U, compaction
->input(0, 1)->fd
.GetNumber());
1358 ASSERT_EQ(3U, compaction
->input(0, 2)->fd
.GetNumber());
1359 ASSERT_EQ(5U, compaction
->input(1, 0)->fd
.GetNumber());
1362 TEST_F(CompactionPickerTest
, IsTrivialMoveOn
) {
1363 mutable_cf_options_
.max_bytes_for_level_base
= 10000u;
1364 mutable_cf_options_
.max_compaction_bytes
= 10001u;
1365 ioptions_
.level_compaction_dynamic_level_bytes
= false;
1366 NewVersionStorage(6, kCompactionStyleLevel
);
1367 // A compaction should be triggered and pick file 2
1368 Add(1, 1U, "100", "150", 3000U);
1369 Add(1, 2U, "151", "200", 3001U);
1370 Add(1, 3U, "201", "250", 3000U);
1371 Add(1, 4U, "251", "300", 3000U);
1373 Add(3, 5U, "120", "130", 7000U);
1374 Add(3, 6U, "170", "180", 7000U);
1375 Add(3, 5U, "220", "230", 7000U);
1376 Add(3, 5U, "270", "280", 7000U);
1377 UpdateVersionStorageInfo();
1379 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
1380 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1381 ASSERT_TRUE(compaction
.get() != nullptr);
1382 ASSERT_TRUE(compaction
->IsTrivialMove());
1385 TEST_F(CompactionPickerTest
, IsTrivialMoveOff
) {
1386 mutable_cf_options_
.max_bytes_for_level_base
= 1000000u;
1387 mutable_cf_options_
.max_compaction_bytes
= 10000u;
1388 ioptions_
.level_compaction_dynamic_level_bytes
= false;
1389 NewVersionStorage(6, kCompactionStyleLevel
);
1390 // A compaction should be triggered and pick all files from level 1
1391 Add(1, 1U, "100", "150", 300000U, 0, 0);
1392 Add(1, 2U, "150", "200", 300000U, 0, 0);
1393 Add(1, 3U, "200", "250", 300000U, 0, 0);
1394 Add(1, 4U, "250", "300", 300000U, 0, 0);
1396 Add(3, 5U, "120", "130", 6000U);
1397 Add(3, 6U, "140", "150", 6000U);
1398 UpdateVersionStorageInfo();
1400 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
1401 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1402 ASSERT_TRUE(compaction
.get() != nullptr);
1403 ASSERT_FALSE(compaction
->IsTrivialMove());
1406 TEST_F(CompactionPickerTest
, CacheNextCompactionIndex
) {
1407 NewVersionStorage(6, kCompactionStyleLevel
);
1408 mutable_cf_options_
.max_compaction_bytes
= 100000000000u;
1410 Add(1 /* level */, 1U /* file_number */, "100" /* smallest */,
1411 "149" /* largest */, 1000000000U /* file_size */);
1412 file_map_
[1U].first
->being_compacted
= true;
1413 Add(1 /* level */, 2U /* file_number */, "150" /* smallest */,
1414 "199" /* largest */, 900000000U /* file_size */);
1415 Add(1 /* level */, 3U /* file_number */, "200" /* smallest */,
1416 "249" /* largest */, 800000000U /* file_size */);
1417 Add(1 /* level */, 4U /* file_number */, "250" /* smallest */,
1418 "299" /* largest */, 700000000U /* file_size */);
1419 Add(2 /* level */, 5U /* file_number */, "150" /* smallest */,
1420 "199" /* largest */, 1U /* file_size */);
1421 file_map_
[5U].first
->being_compacted
= true;
1423 UpdateVersionStorageInfo();
1425 std::unique_ptr
<Compaction
> compaction(level_compaction_picker
.PickCompaction(
1426 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1427 ASSERT_TRUE(compaction
.get() != nullptr);
1428 ASSERT_EQ(1U, compaction
->num_input_levels());
1429 ASSERT_EQ(1U, compaction
->num_input_files(0));
1430 ASSERT_EQ(0U, compaction
->num_input_files(1));
1431 ASSERT_EQ(3U, compaction
->input(0, 0)->fd
.GetNumber());
1432 ASSERT_EQ(2, vstorage_
->NextCompactionIndex(1 /* level */));
1434 compaction
.reset(level_compaction_picker
.PickCompaction(
1435 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1436 ASSERT_TRUE(compaction
.get() != nullptr);
1437 ASSERT_EQ(1U, compaction
->num_input_levels());
1438 ASSERT_EQ(1U, compaction
->num_input_files(0));
1439 ASSERT_EQ(0U, compaction
->num_input_files(1));
1440 ASSERT_EQ(4U, compaction
->input(0, 0)->fd
.GetNumber());
1441 ASSERT_EQ(3, vstorage_
->NextCompactionIndex(1 /* level */));
1443 compaction
.reset(level_compaction_picker
.PickCompaction(
1444 cf_name_
, mutable_cf_options_
, vstorage_
.get(), &log_buffer_
));
1445 ASSERT_TRUE(compaction
.get() == nullptr);
1446 ASSERT_EQ(4, vstorage_
->NextCompactionIndex(1 /* level */));
1449 } // namespace rocksdb
1451 int main(int argc
, char** argv
) {
1452 ::testing::InitGoogleTest(&argc
, argv
);
1453 return RUN_ALL_TESTS();