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).
5 
6 
7 #include <limits>
8 #include <string>
9 #include <utility>
10 #include "db/compaction/compaction.h"
11 #include "db/compaction/compaction_picker_fifo.h"
12 #include "db/compaction/compaction_picker_level.h"
13 #include "db/compaction/compaction_picker_universal.h"
14 
15 #include "logging/logging.h"
16 #include "test_util/testharness.h"
17 #include "test_util/testutil.h"
18 #include "util/string_util.h"
19 
20 namespace ROCKSDB_NAMESPACE {
21 
22 class CountingLogger : public Logger {
23  public:
24   using Logger::Logv;
Logv(const char *,va_list)25   void Logv(const char* /*format*/, va_list /*ap*/) override { log_count++; }
26   size_t log_count;
27 };
28 
29 class CompactionPickerTest : public testing::Test {
30  public:
31   const Comparator* ucmp_;
32   InternalKeyComparator icmp_;
33   Options options_;
34   ImmutableCFOptions ioptions_;
35   MutableCFOptions mutable_cf_options_;
36   LevelCompactionPicker level_compaction_picker;
37   std::string cf_name_;
38   CountingLogger logger_;
39   LogBuffer log_buffer_;
40   uint32_t file_num_;
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_;
49 
CompactionPickerTest()50   CompactionPickerTest()
51       : ucmp_(BytewiseComparator()),
52         icmp_(ucmp_),
53         ioptions_(options_),
54         mutable_cf_options_(options_),
55         level_compaction_picker(ioptions_, &icmp_),
56         cf_name_("dummy"),
57         log_buffer_(InfoLogLevel::INFO_LEVEL, &logger_),
58         file_num_(1),
59         vstorage_(nullptr) {
60     mutable_cf_options_.ttl = 0;
61     mutable_cf_options_.periodic_compaction_seconds = 0;
62     // ioptions_.compaction_pri = kMinOverlappingRatio has its own set of
63     // tests to cover.
64     ioptions_.compaction_pri = kByCompensatedSize;
65     fifo_options_.max_table_files_size = 1;
66     mutable_cf_options_.RefreshDerivedOptions(ioptions_);
67     ioptions_.cf_paths.emplace_back("dummy",
68                                     std::numeric_limits<uint64_t>::max());
69   }
70 
~CompactionPickerTest()71   ~CompactionPickerTest() override {}
72 
NewVersionStorage(int num_levels,CompactionStyle style)73   void NewVersionStorage(int num_levels, CompactionStyle style) {
74     DeleteVersionStorage();
75     options_.num_levels = num_levels;
76     vstorage_.reset(new VersionStorageInfo(&icmp_, ucmp_, options_.num_levels,
77                                            style, nullptr, false));
78     vstorage_->CalculateBaseBytes(ioptions_, mutable_cf_options_);
79   }
80 
DeleteVersionStorage()81   void DeleteVersionStorage() {
82     vstorage_.reset();
83     files_.clear();
84     file_map_.clear();
85     input_files_.clear();
86   }
87 
Add(int level,uint32_t file_number,const char * smallest,const char * largest,uint64_t file_size=1,uint32_t path_id=0,SequenceNumber smallest_seq=100,SequenceNumber largest_seq=100,size_t compensated_file_size=0)88   void Add(int level, uint32_t file_number, const char* smallest,
89            const char* largest, uint64_t file_size = 1, uint32_t path_id = 0,
90            SequenceNumber smallest_seq = 100, SequenceNumber largest_seq = 100,
91            size_t compensated_file_size = 0) {
92     assert(level < vstorage_->num_levels());
93     FileMetaData* f = new FileMetaData(
94         file_number, path_id, file_size,
95         InternalKey(smallest, smallest_seq, kTypeValue),
96         InternalKey(largest, largest_seq, kTypeValue), smallest_seq,
97         largest_seq, /* marked_for_compact */ false, kInvalidBlobFileNumber,
98         kUnknownOldestAncesterTime, kUnknownFileCreationTime,
99         kUnknownFileChecksum, kUnknownFileChecksumFuncName);
100     f->compensated_file_size =
101         (compensated_file_size != 0) ? compensated_file_size : file_size;
102     vstorage_->AddFile(level, f);
103     files_.emplace_back(f);
104     file_map_.insert({file_number, {f, level}});
105   }
106 
SetCompactionInputFilesLevels(int level_count,int start_level)107   void SetCompactionInputFilesLevels(int level_count, int start_level) {
108     input_files_.resize(level_count);
109     for (int i = 0; i < level_count; ++i) {
110       input_files_[i].level = start_level + i;
111     }
112     compaction_level_start_ = start_level;
113   }
114 
AddToCompactionFiles(uint32_t file_number)115   void AddToCompactionFiles(uint32_t file_number) {
116     auto iter = file_map_.find(file_number);
117     assert(iter != file_map_.end());
118     int level = iter->second.second;
119     assert(level < vstorage_->num_levels());
120     input_files_[level - compaction_level_start_].files.emplace_back(
121         iter->second.first);
122   }
123 
UpdateVersionStorageInfo()124   void UpdateVersionStorageInfo() {
125     vstorage_->CalculateBaseBytes(ioptions_, mutable_cf_options_);
126     vstorage_->UpdateFilesByCompactionPri(ioptions_.compaction_pri);
127     vstorage_->UpdateNumNonEmptyLevels();
128     vstorage_->GenerateFileIndexer();
129     vstorage_->GenerateLevelFilesBrief();
130     vstorage_->ComputeCompactionScore(ioptions_, mutable_cf_options_);
131     vstorage_->GenerateLevel0NonOverlapping();
132     vstorage_->ComputeFilesMarkedForCompaction();
133     vstorage_->SetFinalized();
134   }
135 };
136 
TEST_F(CompactionPickerTest,Empty)137 TEST_F(CompactionPickerTest, Empty) {
138   NewVersionStorage(6, kCompactionStyleLevel);
139   UpdateVersionStorageInfo();
140   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
141       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
142   ASSERT_TRUE(compaction.get() == nullptr);
143 }
144 
TEST_F(CompactionPickerTest,Single)145 TEST_F(CompactionPickerTest, Single) {
146   NewVersionStorage(6, kCompactionStyleLevel);
147   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
148   Add(0, 1U, "p", "q");
149   UpdateVersionStorageInfo();
150 
151   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
152       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
153   ASSERT_TRUE(compaction.get() == nullptr);
154 }
155 
TEST_F(CompactionPickerTest,Level0Trigger)156 TEST_F(CompactionPickerTest, Level0Trigger) {
157   NewVersionStorage(6, kCompactionStyleLevel);
158   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
159   Add(0, 1U, "150", "200");
160   Add(0, 2U, "200", "250");
161 
162   UpdateVersionStorageInfo();
163 
164   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
165       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
166   ASSERT_TRUE(compaction.get() != nullptr);
167   ASSERT_EQ(2U, compaction->num_input_files(0));
168   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
169   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
170 }
171 
TEST_F(CompactionPickerTest,Level1Trigger)172 TEST_F(CompactionPickerTest, Level1Trigger) {
173   NewVersionStorage(6, kCompactionStyleLevel);
174   Add(1, 66U, "150", "200", 1000000000U);
175   UpdateVersionStorageInfo();
176 
177   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
178       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
179   ASSERT_TRUE(compaction.get() != nullptr);
180   ASSERT_EQ(1U, compaction->num_input_files(0));
181   ASSERT_EQ(66U, compaction->input(0, 0)->fd.GetNumber());
182 }
183 
TEST_F(CompactionPickerTest,Level1Trigger2)184 TEST_F(CompactionPickerTest, Level1Trigger2) {
185   mutable_cf_options_.target_file_size_base = 10000000000;
186   mutable_cf_options_.RefreshDerivedOptions(ioptions_);
187   NewVersionStorage(6, kCompactionStyleLevel);
188   Add(1, 66U, "150", "200", 1000000001U);
189   Add(1, 88U, "201", "300", 1000000000U);
190   Add(2, 6U, "150", "179", 1000000000U);
191   Add(2, 7U, "180", "220", 1000000000U);
192   Add(2, 8U, "221", "300", 1000000000U);
193   UpdateVersionStorageInfo();
194 
195   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
196       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
197   ASSERT_TRUE(compaction.get() != nullptr);
198   ASSERT_EQ(1U, compaction->num_input_files(0));
199   ASSERT_EQ(2U, compaction->num_input_files(1));
200   ASSERT_EQ(66U, compaction->input(0, 0)->fd.GetNumber());
201   ASSERT_EQ(6U, compaction->input(1, 0)->fd.GetNumber());
202   ASSERT_EQ(7U, compaction->input(1, 1)->fd.GetNumber());
203   ASSERT_EQ(uint64_t{1073741824}, compaction->OutputFilePreallocationSize());
204 }
205 
TEST_F(CompactionPickerTest,LevelMaxScore)206 TEST_F(CompactionPickerTest, LevelMaxScore) {
207   NewVersionStorage(6, kCompactionStyleLevel);
208   mutable_cf_options_.target_file_size_base = 10000000;
209   mutable_cf_options_.max_bytes_for_level_base = 10 * 1024 * 1024;
210   mutable_cf_options_.RefreshDerivedOptions(ioptions_);
211   Add(0, 1U, "150", "200", 1000000U);
212   // Level 1 score 1.2
213   Add(1, 66U, "150", "200", 6000000U);
214   Add(1, 88U, "201", "300", 6000000U);
215   // Level 2 score 1.8. File 7 is the largest. Should be picked
216   Add(2, 6U, "150", "179", 60000000U);
217   Add(2, 7U, "180", "220", 60000001U);
218   Add(2, 8U, "221", "300", 60000000U);
219   // Level 3 score slightly larger than 1
220   Add(3, 26U, "150", "170", 260000000U);
221   Add(3, 27U, "171", "179", 260000000U);
222   Add(3, 28U, "191", "220", 260000000U);
223   Add(3, 29U, "221", "300", 260000000U);
224   UpdateVersionStorageInfo();
225 
226   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
227       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
228   ASSERT_TRUE(compaction.get() != nullptr);
229   ASSERT_EQ(1U, compaction->num_input_files(0));
230   ASSERT_EQ(7U, compaction->input(0, 0)->fd.GetNumber());
231   ASSERT_EQ(mutable_cf_options_.target_file_size_base +
232                 mutable_cf_options_.target_file_size_base / 10,
233             compaction->OutputFilePreallocationSize());
234 }
235 
TEST_F(CompactionPickerTest,NeedsCompactionLevel)236 TEST_F(CompactionPickerTest, NeedsCompactionLevel) {
237   const int kLevels = 6;
238   const int kFileCount = 20;
239 
240   for (int level = 0; level < kLevels - 1; ++level) {
241     NewVersionStorage(kLevels, kCompactionStyleLevel);
242     uint64_t file_size = vstorage_->MaxBytesForLevel(level) * 2 / kFileCount;
243     for (int file_count = 1; file_count <= kFileCount; ++file_count) {
244       // start a brand new version in each test.
245       NewVersionStorage(kLevels, kCompactionStyleLevel);
246       for (int i = 0; i < file_count; ++i) {
247         Add(level, i, ToString((i + 100) * 1000).c_str(),
248             ToString((i + 100) * 1000 + 999).c_str(),
249             file_size, 0, i * 100, i * 100 + 99);
250       }
251       UpdateVersionStorageInfo();
252       ASSERT_EQ(vstorage_->CompactionScoreLevel(0), level);
253       ASSERT_EQ(level_compaction_picker.NeedsCompaction(vstorage_.get()),
254                 vstorage_->CompactionScore(0) >= 1);
255       // release the version storage
256       DeleteVersionStorage();
257     }
258   }
259 }
260 
TEST_F(CompactionPickerTest,Level0TriggerDynamic)261 TEST_F(CompactionPickerTest, Level0TriggerDynamic) {
262   int num_levels = ioptions_.num_levels;
263   ioptions_.level_compaction_dynamic_level_bytes = true;
264   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
265   mutable_cf_options_.max_bytes_for_level_base = 200;
266   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
267   NewVersionStorage(num_levels, kCompactionStyleLevel);
268   Add(0, 1U, "150", "200");
269   Add(0, 2U, "200", "250");
270 
271   UpdateVersionStorageInfo();
272 
273   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
274       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
275   ASSERT_TRUE(compaction.get() != nullptr);
276   ASSERT_EQ(2U, compaction->num_input_files(0));
277   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
278   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
279   ASSERT_EQ(1, static_cast<int>(compaction->num_input_levels()));
280   ASSERT_EQ(num_levels - 1, compaction->output_level());
281 }
282 
TEST_F(CompactionPickerTest,Level0TriggerDynamic2)283 TEST_F(CompactionPickerTest, Level0TriggerDynamic2) {
284   int num_levels = ioptions_.num_levels;
285   ioptions_.level_compaction_dynamic_level_bytes = true;
286   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
287   mutable_cf_options_.max_bytes_for_level_base = 200;
288   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
289   NewVersionStorage(num_levels, kCompactionStyleLevel);
290   Add(0, 1U, "150", "200");
291   Add(0, 2U, "200", "250");
292   Add(num_levels - 1, 3U, "200", "250", 300U);
293 
294   UpdateVersionStorageInfo();
295   ASSERT_EQ(vstorage_->base_level(), num_levels - 2);
296 
297   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
298       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
299   ASSERT_TRUE(compaction.get() != nullptr);
300   ASSERT_EQ(2U, compaction->num_input_files(0));
301   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
302   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
303   ASSERT_EQ(1, static_cast<int>(compaction->num_input_levels()));
304   ASSERT_EQ(num_levels - 2, compaction->output_level());
305 }
306 
TEST_F(CompactionPickerTest,Level0TriggerDynamic3)307 TEST_F(CompactionPickerTest, Level0TriggerDynamic3) {
308   int num_levels = ioptions_.num_levels;
309   ioptions_.level_compaction_dynamic_level_bytes = true;
310   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
311   mutable_cf_options_.max_bytes_for_level_base = 200;
312   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
313   NewVersionStorage(num_levels, kCompactionStyleLevel);
314   Add(0, 1U, "150", "200");
315   Add(0, 2U, "200", "250");
316   Add(num_levels - 1, 3U, "200", "250", 300U);
317   Add(num_levels - 1, 4U, "300", "350", 3000U);
318 
319   UpdateVersionStorageInfo();
320   ASSERT_EQ(vstorage_->base_level(), num_levels - 3);
321 
322   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
323       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
324   ASSERT_TRUE(compaction.get() != nullptr);
325   ASSERT_EQ(2U, compaction->num_input_files(0));
326   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
327   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
328   ASSERT_EQ(1, static_cast<int>(compaction->num_input_levels()));
329   ASSERT_EQ(num_levels - 3, compaction->output_level());
330 }
331 
TEST_F(CompactionPickerTest,Level0TriggerDynamic4)332 TEST_F(CompactionPickerTest, Level0TriggerDynamic4) {
333   int num_levels = ioptions_.num_levels;
334   ioptions_.level_compaction_dynamic_level_bytes = true;
335   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
336   mutable_cf_options_.max_bytes_for_level_base = 200;
337   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
338 
339   NewVersionStorage(num_levels, kCompactionStyleLevel);
340   Add(0, 1U, "150", "200");
341   Add(0, 2U, "200", "250");
342   Add(num_levels - 1, 3U, "200", "250", 300U);
343   Add(num_levels - 1, 4U, "300", "350", 3000U);
344   Add(num_levels - 3, 5U, "150", "180", 3U);
345   Add(num_levels - 3, 6U, "181", "300", 3U);
346   Add(num_levels - 3, 7U, "400", "450", 3U);
347 
348   UpdateVersionStorageInfo();
349   ASSERT_EQ(vstorage_->base_level(), num_levels - 3);
350 
351   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
352       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
353   ASSERT_TRUE(compaction.get() != nullptr);
354   ASSERT_EQ(2U, compaction->num_input_files(0));
355   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
356   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
357   ASSERT_EQ(2U, compaction->num_input_files(1));
358   ASSERT_EQ(num_levels - 3, compaction->level(1));
359   ASSERT_EQ(5U, compaction->input(1, 0)->fd.GetNumber());
360   ASSERT_EQ(6U, compaction->input(1, 1)->fd.GetNumber());
361   ASSERT_EQ(2, static_cast<int>(compaction->num_input_levels()));
362   ASSERT_EQ(num_levels - 3, compaction->output_level());
363 }
364 
TEST_F(CompactionPickerTest,LevelTriggerDynamic4)365 TEST_F(CompactionPickerTest, LevelTriggerDynamic4) {
366   int num_levels = ioptions_.num_levels;
367   ioptions_.level_compaction_dynamic_level_bytes = true;
368   ioptions_.compaction_pri = kMinOverlappingRatio;
369   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
370   mutable_cf_options_.max_bytes_for_level_base = 200;
371   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
372   NewVersionStorage(num_levels, kCompactionStyleLevel);
373   Add(0, 1U, "150", "200");
374   Add(num_levels - 1, 3U, "200", "250", 300U);
375   Add(num_levels - 1, 4U, "300", "350", 3000U);
376   Add(num_levels - 1, 4U, "400", "450", 3U);
377   Add(num_levels - 2, 5U, "150", "180", 300U);
378   Add(num_levels - 2, 6U, "181", "350", 500U);
379   Add(num_levels - 2, 7U, "400", "450", 200U);
380 
381   UpdateVersionStorageInfo();
382 
383   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
384       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
385   ASSERT_TRUE(compaction.get() != nullptr);
386   ASSERT_EQ(1U, compaction->num_input_files(0));
387   ASSERT_EQ(5U, compaction->input(0, 0)->fd.GetNumber());
388   ASSERT_EQ(0, compaction->num_input_files(1));
389   ASSERT_EQ(1U, compaction->num_input_levels());
390   ASSERT_EQ(num_levels - 1, compaction->output_level());
391 }
392 
393 // Universal and FIFO Compactions are not supported in ROCKSDB_LITE
394 #ifndef ROCKSDB_LITE
TEST_F(CompactionPickerTest,NeedsCompactionUniversal)395 TEST_F(CompactionPickerTest, NeedsCompactionUniversal) {
396   NewVersionStorage(1, kCompactionStyleUniversal);
397   UniversalCompactionPicker universal_compaction_picker(
398       ioptions_, &icmp_);
399   UpdateVersionStorageInfo();
400   // must return false when there's no files.
401   ASSERT_EQ(universal_compaction_picker.NeedsCompaction(vstorage_.get()),
402             false);
403 
404   // verify the trigger given different number of L0 files.
405   for (int i = 1;
406        i <= mutable_cf_options_.level0_file_num_compaction_trigger * 2; ++i) {
407     NewVersionStorage(1, kCompactionStyleUniversal);
408     Add(0, i, ToString((i + 100) * 1000).c_str(),
409         ToString((i + 100) * 1000 + 999).c_str(), 1000000, 0, i * 100,
410         i * 100 + 99);
411     UpdateVersionStorageInfo();
412     ASSERT_EQ(level_compaction_picker.NeedsCompaction(vstorage_.get()),
413               vstorage_->CompactionScore(0) >= 1);
414   }
415 }
416 
TEST_F(CompactionPickerTest,CompactionUniversalIngestBehindReservedLevel)417 TEST_F(CompactionPickerTest, CompactionUniversalIngestBehindReservedLevel) {
418   const uint64_t kFileSize = 100000;
419   NewVersionStorage(1, kCompactionStyleUniversal);
420   ioptions_.allow_ingest_behind = true;
421   ioptions_.num_levels = 3;
422   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
423   UpdateVersionStorageInfo();
424   // must return false when there's no files.
425   ASSERT_EQ(universal_compaction_picker.NeedsCompaction(vstorage_.get()),
426             false);
427 
428   NewVersionStorage(3, kCompactionStyleUniversal);
429 
430   Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
431   Add(0, 2U, "201", "250", kFileSize, 0, 401, 450);
432   Add(0, 4U, "260", "300", kFileSize, 0, 260, 300);
433   Add(1, 5U, "100", "151", kFileSize, 0, 200, 251);
434   Add(1, 3U, "301", "350", kFileSize, 0, 101, 150);
435   Add(2, 6U, "120", "200", kFileSize, 0, 20, 100);
436 
437   UpdateVersionStorageInfo();
438 
439   std::unique_ptr<Compaction> compaction(
440       universal_compaction_picker.PickCompaction(
441           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
442 
443   // output level should be the one above the bottom-most
444   ASSERT_EQ(1, compaction->output_level());
445 }
446 // Tests if the files can be trivially moved in multi level
447 // universal compaction when allow_trivial_move option is set
448 // In this test as the input files overlaps, they cannot
449 // be trivially moved.
450 
TEST_F(CompactionPickerTest,CannotTrivialMoveUniversal)451 TEST_F(CompactionPickerTest, CannotTrivialMoveUniversal) {
452   const uint64_t kFileSize = 100000;
453 
454   mutable_cf_options_.compaction_options_universal.allow_trivial_move = true;
455   NewVersionStorage(1, kCompactionStyleUniversal);
456   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
457   UpdateVersionStorageInfo();
458   // must return false when there's no files.
459   ASSERT_EQ(universal_compaction_picker.NeedsCompaction(vstorage_.get()),
460             false);
461 
462   NewVersionStorage(3, kCompactionStyleUniversal);
463 
464   Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
465   Add(0, 2U, "201", "250", kFileSize, 0, 401, 450);
466   Add(0, 4U, "260", "300", kFileSize, 0, 260, 300);
467   Add(1, 5U, "100", "151", kFileSize, 0, 200, 251);
468   Add(1, 3U, "301", "350", kFileSize, 0, 101, 150);
469   Add(2, 6U, "120", "200", kFileSize, 0, 20, 100);
470 
471   UpdateVersionStorageInfo();
472 
473   std::unique_ptr<Compaction> compaction(
474       universal_compaction_picker.PickCompaction(
475           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
476 
477   ASSERT_TRUE(!compaction->is_trivial_move());
478 }
479 // Tests if the files can be trivially moved in multi level
480 // universal compaction when allow_trivial_move option is set
481 // In this test as the input files doesn't overlaps, they should
482 // be trivially moved.
TEST_F(CompactionPickerTest,AllowsTrivialMoveUniversal)483 TEST_F(CompactionPickerTest, AllowsTrivialMoveUniversal) {
484   const uint64_t kFileSize = 100000;
485 
486   mutable_cf_options_.compaction_options_universal.allow_trivial_move = true;
487   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
488 
489   NewVersionStorage(3, kCompactionStyleUniversal);
490 
491   Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
492   Add(0, 2U, "201", "250", kFileSize, 0, 401, 450);
493   Add(0, 4U, "260", "300", kFileSize, 0, 260, 300);
494   Add(1, 5U, "010", "080", kFileSize, 0, 200, 251);
495   Add(2, 3U, "301", "350", kFileSize, 0, 101, 150);
496 
497   UpdateVersionStorageInfo();
498 
499   std::unique_ptr<Compaction> compaction(
500       universal_compaction_picker.PickCompaction(
501           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
502 
503   ASSERT_TRUE(compaction->is_trivial_move());
504 }
505 
TEST_F(CompactionPickerTest,UniversalPeriodicCompaction1)506 TEST_F(CompactionPickerTest, UniversalPeriodicCompaction1) {
507   // The case where universal periodic compaction can be picked
508   // with some newer files being compacted.
509   const uint64_t kFileSize = 100000;
510 
511   mutable_cf_options_.periodic_compaction_seconds = 1000;
512   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
513 
514   NewVersionStorage(5, kCompactionStyleUniversal);
515 
516   Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
517   Add(0, 2U, "201", "250", kFileSize, 0, 401, 450);
518   Add(0, 4U, "260", "300", kFileSize, 0, 260, 300);
519   Add(3, 5U, "010", "080", kFileSize, 0, 200, 251);
520   Add(4, 3U, "301", "350", kFileSize, 0, 101, 150);
521   Add(4, 6U, "501", "750", kFileSize, 0, 101, 150);
522 
523   file_map_[2].first->being_compacted = true;
524   UpdateVersionStorageInfo();
525   vstorage_->TEST_AddFileMarkedForPeriodicCompaction(4, file_map_[3].first);
526 
527   std::unique_ptr<Compaction> compaction(
528       universal_compaction_picker.PickCompaction(
529           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
530 
531   ASSERT_TRUE(compaction);
532   ASSERT_EQ(4, compaction->output_level());
533   ASSERT_EQ(0, compaction->start_level());
534   ASSERT_EQ(1U, compaction->num_input_files(0));
535 }
536 
TEST_F(CompactionPickerTest,UniversalPeriodicCompaction2)537 TEST_F(CompactionPickerTest, UniversalPeriodicCompaction2) {
538   // The case where universal periodic compaction does not
539   // pick up only level to compact if it doesn't cover
540   // any file marked as periodic compaction.
541   const uint64_t kFileSize = 100000;
542 
543   mutable_cf_options_.periodic_compaction_seconds = 1000;
544   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
545 
546   NewVersionStorage(5, kCompactionStyleUniversal);
547 
548   Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
549   Add(3, 5U, "010", "080", kFileSize, 0, 200, 251);
550   Add(4, 3U, "301", "350", kFileSize, 0, 101, 150);
551   Add(4, 6U, "501", "750", kFileSize, 0, 101, 150);
552 
553   file_map_[5].first->being_compacted = true;
554   UpdateVersionStorageInfo();
555   vstorage_->TEST_AddFileMarkedForPeriodicCompaction(0, file_map_[1].first);
556 
557   std::unique_ptr<Compaction> compaction(
558       universal_compaction_picker.PickCompaction(
559           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
560 
561   ASSERT_FALSE(compaction);
562 }
563 
TEST_F(CompactionPickerTest,UniversalPeriodicCompaction3)564 TEST_F(CompactionPickerTest, UniversalPeriodicCompaction3) {
565   // The case where universal periodic compaction does not
566   // pick up only the last sorted run which is an L0 file if it isn't
567   // marked as periodic compaction.
568   const uint64_t kFileSize = 100000;
569 
570   mutable_cf_options_.periodic_compaction_seconds = 1000;
571   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
572 
573   NewVersionStorage(5, kCompactionStyleUniversal);
574 
575   Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
576   Add(0, 5U, "010", "080", kFileSize, 0, 200, 251);
577   Add(0, 6U, "501", "750", kFileSize, 0, 101, 150);
578 
579   file_map_[5].first->being_compacted = true;
580   UpdateVersionStorageInfo();
581   vstorage_->TEST_AddFileMarkedForPeriodicCompaction(0, file_map_[1].first);
582 
583   std::unique_ptr<Compaction> compaction(
584       universal_compaction_picker.PickCompaction(
585           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
586 
587   ASSERT_FALSE(compaction);
588 }
589 
TEST_F(CompactionPickerTest,UniversalPeriodicCompaction4)590 TEST_F(CompactionPickerTest, UniversalPeriodicCompaction4) {
591   // The case where universal periodic compaction couldn't form
592   // a compaction that inlcudes any file marked for periodic compaction.
593   // Right now we form the compaction anyway if it is more than one
594   // sorted run. Just put the case here to validate that it doesn't
595   // crash.
596   const uint64_t kFileSize = 100000;
597 
598   mutable_cf_options_.periodic_compaction_seconds = 1000;
599   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
600 
601   NewVersionStorage(5, kCompactionStyleUniversal);
602 
603   Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
604   Add(2, 2U, "010", "080", kFileSize, 0, 200, 251);
605   Add(3, 5U, "010", "080", kFileSize, 0, 200, 251);
606   Add(4, 3U, "301", "350", kFileSize, 0, 101, 150);
607   Add(4, 6U, "501", "750", kFileSize, 0, 101, 150);
608 
609   file_map_[2].first->being_compacted = true;
610   UpdateVersionStorageInfo();
611   vstorage_->TEST_AddFileMarkedForPeriodicCompaction(0, file_map_[2].first);
612 
613   std::unique_ptr<Compaction> compaction(
614       universal_compaction_picker.PickCompaction(
615           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
616   ASSERT_TRUE(!compaction ||
617               compaction->start_level() != compaction->output_level());
618 }
619 
TEST_F(CompactionPickerTest,UniversalPeriodicCompaction5)620 TEST_F(CompactionPickerTest, UniversalPeriodicCompaction5) {
621   // Test single L0 file periodic compaction triggering.
622   const uint64_t kFileSize = 100000;
623 
624   mutable_cf_options_.periodic_compaction_seconds = 1000;
625   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
626 
627   NewVersionStorage(5, kCompactionStyleUniversal);
628 
629   Add(0, 6U, "150", "200", kFileSize, 0, 500, 550);
630   UpdateVersionStorageInfo();
631   vstorage_->TEST_AddFileMarkedForPeriodicCompaction(0, file_map_[6].first);
632 
633   std::unique_ptr<Compaction> compaction(
634       universal_compaction_picker.PickCompaction(
635           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
636   ASSERT_TRUE(compaction);
637   ASSERT_EQ(0, compaction->start_level());
638   ASSERT_EQ(1U, compaction->num_input_files(0));
639   ASSERT_EQ(6U, compaction->input(0, 0)->fd.GetNumber());
640   ASSERT_EQ(4, compaction->output_level());
641 }
642 
TEST_F(CompactionPickerTest,UniversalPeriodicCompaction6)643 TEST_F(CompactionPickerTest, UniversalPeriodicCompaction6) {
644   // Test single sorted run non-L0 periodic compaction
645   const uint64_t kFileSize = 100000;
646 
647   mutable_cf_options_.periodic_compaction_seconds = 1000;
648   UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
649 
650   NewVersionStorage(5, kCompactionStyleUniversal);
651 
652   Add(4, 5U, "150", "200", kFileSize, 0, 500, 550);
653   Add(4, 6U, "350", "400", kFileSize, 0, 500, 550);
654   UpdateVersionStorageInfo();
655   vstorage_->TEST_AddFileMarkedForPeriodicCompaction(4, file_map_[6].first);
656 
657   std::unique_ptr<Compaction> compaction(
658       universal_compaction_picker.PickCompaction(
659           cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
660   ASSERT_TRUE(compaction);
661   ASSERT_EQ(4, compaction->start_level());
662   ASSERT_EQ(2U, compaction->num_input_files(0));
663   ASSERT_EQ(5U, compaction->input(0, 0)->fd.GetNumber());
664   ASSERT_EQ(6U, compaction->input(0, 1)->fd.GetNumber());
665   ASSERT_EQ(4, compaction->output_level());
666 }
667 
TEST_F(CompactionPickerTest,NeedsCompactionFIFO)668 TEST_F(CompactionPickerTest, NeedsCompactionFIFO) {
669   NewVersionStorage(1, kCompactionStyleFIFO);
670   const int kFileCount =
671       mutable_cf_options_.level0_file_num_compaction_trigger * 3;
672   const uint64_t kFileSize = 100000;
673   const uint64_t kMaxSize = kFileSize * kFileCount / 2;
674 
675   fifo_options_.max_table_files_size = kMaxSize;
676   mutable_cf_options_.compaction_options_fifo = fifo_options_;
677   FIFOCompactionPicker fifo_compaction_picker(ioptions_, &icmp_);
678   UpdateVersionStorageInfo();
679   // must return false when there's no files.
680   ASSERT_EQ(fifo_compaction_picker.NeedsCompaction(vstorage_.get()), false);
681 
682   // verify whether compaction is needed based on the current
683   // size of L0 files.
684   uint64_t current_size = 0;
685   for (int i = 1; i <= kFileCount; ++i) {
686     NewVersionStorage(1, kCompactionStyleFIFO);
687     Add(0, i, ToString((i + 100) * 1000).c_str(),
688         ToString((i + 100) * 1000 + 999).c_str(),
689         kFileSize, 0, i * 100, i * 100 + 99);
690     current_size += kFileSize;
691     UpdateVersionStorageInfo();
692     ASSERT_EQ(fifo_compaction_picker.NeedsCompaction(vstorage_.get()),
693               vstorage_->CompactionScore(0) >= 1);
694   }
695 }
696 #endif  // ROCKSDB_LITE
697 
TEST_F(CompactionPickerTest,CompactionPriMinOverlapping1)698 TEST_F(CompactionPickerTest, CompactionPriMinOverlapping1) {
699   NewVersionStorage(6, kCompactionStyleLevel);
700   ioptions_.compaction_pri = kMinOverlappingRatio;
701   mutable_cf_options_.target_file_size_base = 100000000000;
702   mutable_cf_options_.target_file_size_multiplier = 10;
703   mutable_cf_options_.max_bytes_for_level_base = 10 * 1024 * 1024;
704   mutable_cf_options_.RefreshDerivedOptions(ioptions_);
705 
706   Add(2, 6U, "150", "179", 50000000U);
707   Add(2, 7U, "180", "220", 50000000U);
708   Add(2, 8U, "321", "400", 50000000U);  // File not overlapping
709   Add(2, 9U, "721", "800", 50000000U);
710 
711   Add(3, 26U, "150", "170", 260000000U);
712   Add(3, 27U, "171", "179", 260000000U);
713   Add(3, 28U, "191", "220", 260000000U);
714   Add(3, 29U, "221", "300", 260000000U);
715   Add(3, 30U, "750", "900", 260000000U);
716   UpdateVersionStorageInfo();
717 
718   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
719       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
720   ASSERT_TRUE(compaction.get() != nullptr);
721   ASSERT_EQ(1U, compaction->num_input_files(0));
722   // Pick file 8 because it overlaps with 0 files on level 3.
723   ASSERT_EQ(8U, compaction->input(0, 0)->fd.GetNumber());
724   // Compaction input size * 1.1
725   ASSERT_GE(uint64_t{55000000}, compaction->OutputFilePreallocationSize());
726 }
727 
TEST_F(CompactionPickerTest,CompactionPriMinOverlapping2)728 TEST_F(CompactionPickerTest, CompactionPriMinOverlapping2) {
729   NewVersionStorage(6, kCompactionStyleLevel);
730   ioptions_.compaction_pri = kMinOverlappingRatio;
731   mutable_cf_options_.target_file_size_base = 10000000;
732   mutable_cf_options_.target_file_size_multiplier = 10;
733   mutable_cf_options_.max_bytes_for_level_base = 10 * 1024 * 1024;
734 
735   Add(2, 6U, "150", "175",
736       60000000U);  // Overlaps with file 26, 27, total size 521M
737   Add(2, 7U, "176", "200", 60000000U);  // Overlaps with file 27, 28, total size
738                                         // 520M, the smalelst overlapping
739   Add(2, 8U, "201", "300",
740       60000000U);  // Overlaps with file 28, 29, total size 521M
741 
742   Add(3, 26U, "100", "110", 261000000U);
743   Add(3, 26U, "150", "170", 261000000U);
744   Add(3, 27U, "171", "179", 260000000U);
745   Add(3, 28U, "191", "220", 260000000U);
746   Add(3, 29U, "221", "300", 261000000U);
747   Add(3, 30U, "321", "400", 261000000U);
748   UpdateVersionStorageInfo();
749 
750   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
751       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
752   ASSERT_TRUE(compaction.get() != nullptr);
753   ASSERT_EQ(1U, compaction->num_input_files(0));
754   // Picking file 7 because overlapping ratio is the biggest.
755   ASSERT_EQ(7U, compaction->input(0, 0)->fd.GetNumber());
756 }
757 
TEST_F(CompactionPickerTest,CompactionPriMinOverlapping3)758 TEST_F(CompactionPickerTest, CompactionPriMinOverlapping3) {
759   NewVersionStorage(6, kCompactionStyleLevel);
760   ioptions_.compaction_pri = kMinOverlappingRatio;
761   mutable_cf_options_.max_bytes_for_level_base = 10000000;
762   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
763 
764   // file 7 and 8 over lap with the same file, but file 8 is smaller so
765   // it will be picked.
766   Add(2, 6U, "150", "167", 60000000U);  // Overlaps with file 26, 27
767   Add(2, 7U, "168", "169", 60000000U);  // Overlaps with file 27
768   Add(2, 8U, "201", "300", 61000000U);  // Overlaps with file 28, but the file
769                                         // itself is larger. Should be picked.
770 
771   Add(3, 26U, "160", "165", 260000000U);
772   Add(3, 27U, "166", "170", 260000000U);
773   Add(3, 28U, "180", "400", 260000000U);
774   Add(3, 29U, "401", "500", 260000000U);
775   UpdateVersionStorageInfo();
776 
777   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
778       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
779   ASSERT_TRUE(compaction.get() != nullptr);
780   ASSERT_EQ(1U, compaction->num_input_files(0));
781   // Picking file 8 because overlapping ratio is the biggest.
782   ASSERT_EQ(8U, compaction->input(0, 0)->fd.GetNumber());
783 }
784 
TEST_F(CompactionPickerTest,CompactionPriMinOverlapping4)785 TEST_F(CompactionPickerTest, CompactionPriMinOverlapping4) {
786   NewVersionStorage(6, kCompactionStyleLevel);
787   ioptions_.compaction_pri = kMinOverlappingRatio;
788   mutable_cf_options_.max_bytes_for_level_base = 10000000;
789   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
790 
791   // file 7 and 8 over lap with the same file, but file 8 is smaller so
792   // it will be picked.
793   // Overlaps with file 26, 27. And the file is compensated so will be
794   // picked up.
795   Add(2, 6U, "150", "167", 60000000U, 0, 100, 100, 180000000U);
796   Add(2, 7U, "168", "169", 60000000U);  // Overlaps with file 27
797   Add(2, 8U, "201", "300", 61000000U);  // Overlaps with file 28
798 
799   Add(3, 26U, "160", "165", 60000000U);
800   // Boosted file size in output level is not considered.
801   Add(3, 27U, "166", "170", 60000000U, 0, 100, 100, 260000000U);
802   Add(3, 28U, "180", "400", 60000000U);
803   Add(3, 29U, "401", "500", 60000000U);
804   UpdateVersionStorageInfo();
805 
806   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
807       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
808   ASSERT_TRUE(compaction.get() != nullptr);
809   ASSERT_EQ(1U, compaction->num_input_files(0));
810   // Picking file 8 because overlapping ratio is the biggest.
811   ASSERT_EQ(6U, compaction->input(0, 0)->fd.GetNumber());
812 }
813 
814 // This test exhibits the bug where we don't properly reset parent_index in
815 // PickCompaction()
TEST_F(CompactionPickerTest,ParentIndexResetBug)816 TEST_F(CompactionPickerTest, ParentIndexResetBug) {
817   int num_levels = ioptions_.num_levels;
818   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
819   mutable_cf_options_.max_bytes_for_level_base = 200;
820   NewVersionStorage(num_levels, kCompactionStyleLevel);
821   Add(0, 1U, "150", "200");       // <- marked for compaction
822   Add(1, 3U, "400", "500", 600);  // <- this one needs compacting
823   Add(2, 4U, "150", "200");
824   Add(2, 5U, "201", "210");
825   Add(2, 6U, "300", "310");
826   Add(2, 7U, "400", "500");  // <- being compacted
827 
828   vstorage_->LevelFiles(2)[3]->being_compacted = true;
829   vstorage_->LevelFiles(0)[0]->marked_for_compaction = true;
830 
831   UpdateVersionStorageInfo();
832 
833   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
834       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
835 }
836 
837 // This test checks ExpandWhileOverlapping() by having overlapping user keys
838 // ranges (with different sequence numbers) in the input files.
TEST_F(CompactionPickerTest,OverlappingUserKeys)839 TEST_F(CompactionPickerTest, OverlappingUserKeys) {
840   NewVersionStorage(6, kCompactionStyleLevel);
841   ioptions_.compaction_pri = kByCompensatedSize;
842 
843   Add(1, 1U, "100", "150", 1U);
844   // Overlapping user keys
845   Add(1, 2U, "200", "400", 1U);
846   Add(1, 3U, "400", "500", 1000000000U, 0, 0);
847   Add(2, 4U, "600", "700", 1U);
848   UpdateVersionStorageInfo();
849 
850   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
851               cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
852   ASSERT_TRUE(compaction.get() != nullptr);
853   ASSERT_EQ(1U, compaction->num_input_levels());
854   ASSERT_EQ(2U, compaction->num_input_files(0));
855   ASSERT_EQ(2U, compaction->input(0, 0)->fd.GetNumber());
856   ASSERT_EQ(3U, compaction->input(0, 1)->fd.GetNumber());
857 }
858 
TEST_F(CompactionPickerTest,OverlappingUserKeys2)859 TEST_F(CompactionPickerTest, OverlappingUserKeys2) {
860   NewVersionStorage(6, kCompactionStyleLevel);
861   // Overlapping user keys on same level and output level
862   Add(1, 1U, "200", "400", 1000000000U);
863   Add(1, 2U, "400", "500", 1U, 0, 0);
864   Add(2, 3U, "000", "100", 1U);
865   Add(2, 4U, "100", "600", 1U, 0, 0);
866   Add(2, 5U, "600", "700", 1U, 0, 0);
867   UpdateVersionStorageInfo();
868 
869   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
870               cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
871   ASSERT_TRUE(compaction.get() != nullptr);
872   ASSERT_EQ(2U, compaction->num_input_levels());
873   ASSERT_EQ(2U, compaction->num_input_files(0));
874   ASSERT_EQ(3U, compaction->num_input_files(1));
875   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
876   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
877   ASSERT_EQ(3U, compaction->input(1, 0)->fd.GetNumber());
878   ASSERT_EQ(4U, compaction->input(1, 1)->fd.GetNumber());
879   ASSERT_EQ(5U, compaction->input(1, 2)->fd.GetNumber());
880 }
881 
TEST_F(CompactionPickerTest,OverlappingUserKeys3)882 TEST_F(CompactionPickerTest, OverlappingUserKeys3) {
883   NewVersionStorage(6, kCompactionStyleLevel);
884   // Chain of overlapping user key ranges (forces ExpandWhileOverlapping() to
885   // expand multiple times)
886   Add(1, 1U, "100", "150", 1U);
887   Add(1, 2U, "150", "200", 1U, 0, 0);
888   Add(1, 3U, "200", "250", 1000000000U, 0, 0);
889   Add(1, 4U, "250", "300", 1U, 0, 0);
890   Add(1, 5U, "300", "350", 1U, 0, 0);
891   // Output level overlaps with the beginning and the end of the chain
892   Add(2, 6U, "050", "100", 1U);
893   Add(2, 7U, "350", "400", 1U);
894   UpdateVersionStorageInfo();
895 
896   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
897               cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
898   ASSERT_TRUE(compaction.get() != nullptr);
899   ASSERT_EQ(2U, compaction->num_input_levels());
900   ASSERT_EQ(5U, compaction->num_input_files(0));
901   ASSERT_EQ(2U, compaction->num_input_files(1));
902   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
903   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
904   ASSERT_EQ(3U, compaction->input(0, 2)->fd.GetNumber());
905   ASSERT_EQ(4U, compaction->input(0, 3)->fd.GetNumber());
906   ASSERT_EQ(5U, compaction->input(0, 4)->fd.GetNumber());
907   ASSERT_EQ(6U, compaction->input(1, 0)->fd.GetNumber());
908   ASSERT_EQ(7U, compaction->input(1, 1)->fd.GetNumber());
909 }
910 
TEST_F(CompactionPickerTest,OverlappingUserKeys4)911 TEST_F(CompactionPickerTest, OverlappingUserKeys4) {
912   NewVersionStorage(6, kCompactionStyleLevel);
913   mutable_cf_options_.max_bytes_for_level_base = 1000000;
914 
915   Add(1, 1U, "100", "150", 1U);
916   Add(1, 2U, "150", "199", 1U, 0, 0);
917   Add(1, 3U, "200", "250", 1100000U, 0, 0);
918   Add(1, 4U, "251", "300", 1U, 0, 0);
919   Add(1, 5U, "300", "350", 1U, 0, 0);
920 
921   Add(2, 6U, "100", "115", 1U);
922   Add(2, 7U, "125", "325", 1U);
923   Add(2, 8U, "350", "400", 1U);
924   UpdateVersionStorageInfo();
925 
926   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
927       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
928   ASSERT_TRUE(compaction.get() != nullptr);
929   ASSERT_EQ(2U, compaction->num_input_levels());
930   ASSERT_EQ(1U, compaction->num_input_files(0));
931   ASSERT_EQ(1U, compaction->num_input_files(1));
932   ASSERT_EQ(3U, compaction->input(0, 0)->fd.GetNumber());
933   ASSERT_EQ(7U, compaction->input(1, 0)->fd.GetNumber());
934 }
935 
TEST_F(CompactionPickerTest,OverlappingUserKeys5)936 TEST_F(CompactionPickerTest, OverlappingUserKeys5) {
937   NewVersionStorage(6, kCompactionStyleLevel);
938   // Overlapping user keys on same level and output level
939   Add(1, 1U, "200", "400", 1000000000U);
940   Add(1, 2U, "400", "500", 1U, 0, 0);
941   Add(2, 3U, "000", "100", 1U);
942   Add(2, 4U, "100", "600", 1U, 0, 0);
943   Add(2, 5U, "600", "700", 1U, 0, 0);
944 
945   vstorage_->LevelFiles(2)[2]->being_compacted = true;
946 
947   UpdateVersionStorageInfo();
948 
949   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
950       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
951   ASSERT_TRUE(compaction.get() == nullptr);
952 }
953 
TEST_F(CompactionPickerTest,OverlappingUserKeys6)954 TEST_F(CompactionPickerTest, OverlappingUserKeys6) {
955   NewVersionStorage(6, kCompactionStyleLevel);
956   // Overlapping user keys on same level and output level
957   Add(1, 1U, "200", "400", 1U, 0, 0);
958   Add(1, 2U, "401", "500", 1U, 0, 0);
959   Add(2, 3U, "000", "100", 1U);
960   Add(2, 4U, "100", "300", 1U, 0, 0);
961   Add(2, 5U, "305", "450", 1U, 0, 0);
962   Add(2, 6U, "460", "600", 1U, 0, 0);
963   Add(2, 7U, "600", "700", 1U, 0, 0);
964 
965   vstorage_->LevelFiles(1)[0]->marked_for_compaction = true;
966   vstorage_->LevelFiles(1)[1]->marked_for_compaction = true;
967 
968   UpdateVersionStorageInfo();
969 
970   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
971       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
972   ASSERT_TRUE(compaction.get() != nullptr);
973   ASSERT_EQ(2U, compaction->num_input_levels());
974   ASSERT_EQ(1U, compaction->num_input_files(0));
975   ASSERT_EQ(3U, compaction->num_input_files(1));
976 }
977 
TEST_F(CompactionPickerTest,OverlappingUserKeys7)978 TEST_F(CompactionPickerTest, OverlappingUserKeys7) {
979   NewVersionStorage(6, kCompactionStyleLevel);
980   mutable_cf_options_.max_compaction_bytes = 100000000000u;
981   // Overlapping user keys on same level and output level
982   Add(1, 1U, "200", "400", 1U, 0, 0);
983   Add(1, 2U, "401", "500", 1000000000U, 0, 0);
984   Add(2, 3U, "100", "250", 1U);
985   Add(2, 4U, "300", "600", 1U, 0, 0);
986   Add(2, 5U, "600", "800", 1U, 0, 0);
987 
988   UpdateVersionStorageInfo();
989 
990   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
991       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
992   ASSERT_TRUE(compaction.get() != nullptr);
993   ASSERT_EQ(2U, compaction->num_input_levels());
994   ASSERT_GE(1U, compaction->num_input_files(0));
995   ASSERT_GE(2U, compaction->num_input_files(1));
996   // File 5 has to be included in the compaction
997   ASSERT_EQ(5U, compaction->inputs(1)->back()->fd.GetNumber());
998 }
999 
TEST_F(CompactionPickerTest,OverlappingUserKeys8)1000 TEST_F(CompactionPickerTest, OverlappingUserKeys8) {
1001   NewVersionStorage(6, kCompactionStyleLevel);
1002   mutable_cf_options_.max_compaction_bytes = 100000000000u;
1003   // grow the number of inputs in "level" without
1004   // changing the number of "level+1" files we pick up
1005   // Expand input level as much as possible
1006   // no overlapping case
1007   Add(1, 1U, "101", "150", 1U);
1008   Add(1, 2U, "151", "200", 1U);
1009   Add(1, 3U, "201", "300", 1000000000U);
1010   Add(1, 4U, "301", "400", 1U);
1011   Add(1, 5U, "401", "500", 1U);
1012   Add(2, 6U, "150", "200", 1U);
1013   Add(2, 7U, "200", "450", 1U, 0, 0);
1014   Add(2, 8U, "500", "600", 1U);
1015 
1016   UpdateVersionStorageInfo();
1017 
1018   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1019       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1020   ASSERT_TRUE(compaction.get() != nullptr);
1021   ASSERT_EQ(2U, compaction->num_input_levels());
1022   ASSERT_EQ(3U, compaction->num_input_files(0));
1023   ASSERT_EQ(2U, compaction->num_input_files(1));
1024   ASSERT_EQ(2U, compaction->input(0, 0)->fd.GetNumber());
1025   ASSERT_EQ(3U, compaction->input(0, 1)->fd.GetNumber());
1026   ASSERT_EQ(4U, compaction->input(0, 2)->fd.GetNumber());
1027   ASSERT_EQ(6U, compaction->input(1, 0)->fd.GetNumber());
1028   ASSERT_EQ(7U, compaction->input(1, 1)->fd.GetNumber());
1029 }
1030 
TEST_F(CompactionPickerTest,OverlappingUserKeys9)1031 TEST_F(CompactionPickerTest, OverlappingUserKeys9) {
1032   NewVersionStorage(6, kCompactionStyleLevel);
1033   mutable_cf_options_.max_compaction_bytes = 100000000000u;
1034   // grow the number of inputs in "level" without
1035   // changing the number of "level+1" files we pick up
1036   // Expand input level as much as possible
1037   // overlapping case
1038   Add(1, 1U, "121", "150", 1U);
1039   Add(1, 2U, "151", "200", 1U);
1040   Add(1, 3U, "201", "300", 1000000000U);
1041   Add(1, 4U, "301", "400", 1U);
1042   Add(1, 5U, "401", "500", 1U);
1043   Add(2, 6U, "100", "120", 1U);
1044   Add(2, 7U, "150", "200", 1U);
1045   Add(2, 8U, "200", "450", 1U, 0, 0);
1046   Add(2, 9U, "501", "600", 1U);
1047 
1048   UpdateVersionStorageInfo();
1049 
1050   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1051       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1052   ASSERT_TRUE(compaction.get() != nullptr);
1053   ASSERT_EQ(2U, compaction->num_input_levels());
1054   ASSERT_EQ(5U, compaction->num_input_files(0));
1055   ASSERT_EQ(2U, compaction->num_input_files(1));
1056   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
1057   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
1058   ASSERT_EQ(3U, compaction->input(0, 2)->fd.GetNumber());
1059   ASSERT_EQ(4U, compaction->input(0, 3)->fd.GetNumber());
1060   ASSERT_EQ(7U, compaction->input(1, 0)->fd.GetNumber());
1061   ASSERT_EQ(8U, compaction->input(1, 1)->fd.GetNumber());
1062 }
1063 
TEST_F(CompactionPickerTest,OverlappingUserKeys10)1064 TEST_F(CompactionPickerTest, OverlappingUserKeys10) {
1065   // Locked file encountered when pulling in extra input-level files with same
1066   // user keys. Verify we pick the next-best file from the same input level.
1067   NewVersionStorage(6, kCompactionStyleLevel);
1068   mutable_cf_options_.max_compaction_bytes = 100000000000u;
1069 
1070   // file_number 2U is largest and thus first choice. But it overlaps with
1071   // file_number 1U which is being compacted. So instead we pick the next-
1072   // biggest file, 3U, which is eligible for compaction.
1073   Add(1 /* level */, 1U /* file_number */, "100" /* smallest */,
1074       "150" /* largest */, 1U /* file_size */);
1075   file_map_[1U].first->being_compacted = true;
1076   Add(1 /* level */, 2U /* file_number */, "150" /* smallest */,
1077       "200" /* largest */, 1000000000U /* file_size */, 0 /* smallest_seq */,
1078       0 /* largest_seq */);
1079   Add(1 /* level */, 3U /* file_number */, "201" /* smallest */,
1080       "250" /* largest */, 900000000U /* file_size */);
1081   Add(2 /* level */, 4U /* file_number */, "100" /* smallest */,
1082       "150" /* largest */, 1U /* file_size */);
1083   Add(2 /* level */, 5U /* file_number */, "151" /* smallest */,
1084       "200" /* largest */, 1U /* file_size */);
1085   Add(2 /* level */, 6U /* file_number */, "201" /* smallest */,
1086       "250" /* largest */, 1U /* file_size */);
1087 
1088   UpdateVersionStorageInfo();
1089 
1090   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1091       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1092   ASSERT_TRUE(compaction.get() != nullptr);
1093   ASSERT_EQ(2U, compaction->num_input_levels());
1094   ASSERT_EQ(1U, compaction->num_input_files(0));
1095   ASSERT_EQ(1U, compaction->num_input_files(1));
1096   ASSERT_EQ(3U, compaction->input(0, 0)->fd.GetNumber());
1097   ASSERT_EQ(6U, compaction->input(1, 0)->fd.GetNumber());
1098 }
1099 
TEST_F(CompactionPickerTest,OverlappingUserKeys11)1100 TEST_F(CompactionPickerTest, OverlappingUserKeys11) {
1101   // Locked file encountered when pulling in extra output-level files with same
1102   // user keys. Expected to skip that compaction and pick the next-best choice.
1103   NewVersionStorage(6, kCompactionStyleLevel);
1104   mutable_cf_options_.max_compaction_bytes = 100000000000u;
1105 
1106   // score(L1) = 3.7
1107   // score(L2) = 1.85
1108   // There is no eligible file in L1 to compact since both candidates pull in
1109   // file_number 5U, which overlaps with a file pending compaction (6U). The
1110   // first eligible compaction is from L2->L3.
1111   Add(1 /* level */, 2U /* file_number */, "151" /* smallest */,
1112       "200" /* largest */, 1000000000U /* file_size */);
1113   Add(1 /* level */, 3U /* file_number */, "201" /* smallest */,
1114       "250" /* largest */, 1U /* file_size */);
1115   Add(2 /* level */, 4U /* file_number */, "100" /* smallest */,
1116       "149" /* largest */, 5000000000U /* file_size */);
1117   Add(2 /* level */, 5U /* file_number */, "150" /* smallest */,
1118       "201" /* largest */, 1U /* file_size */);
1119   Add(2 /* level */, 6U /* file_number */, "201" /* smallest */,
1120       "249" /* largest */, 1U /* file_size */, 0 /* smallest_seq */,
1121       0 /* largest_seq */);
1122   file_map_[6U].first->being_compacted = true;
1123   Add(3 /* level */, 7U /* file_number */, "100" /* smallest */,
1124       "149" /* largest */, 1U /* file_size */);
1125 
1126   UpdateVersionStorageInfo();
1127 
1128   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1129       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1130   ASSERT_TRUE(compaction.get() != nullptr);
1131   ASSERT_EQ(2U, compaction->num_input_levels());
1132   ASSERT_EQ(1U, compaction->num_input_files(0));
1133   ASSERT_EQ(1U, compaction->num_input_files(1));
1134   ASSERT_EQ(4U, compaction->input(0, 0)->fd.GetNumber());
1135   ASSERT_EQ(7U, compaction->input(1, 0)->fd.GetNumber());
1136 }
1137 
TEST_F(CompactionPickerTest,NotScheduleL1IfL0WithHigherPri1)1138 TEST_F(CompactionPickerTest, NotScheduleL1IfL0WithHigherPri1) {
1139   NewVersionStorage(6, kCompactionStyleLevel);
1140   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
1141   mutable_cf_options_.max_bytes_for_level_base = 900000000U;
1142 
1143   // 6 L0 files, score 3.
1144   Add(0, 1U, "000", "400", 1U);
1145   Add(0, 2U, "001", "400", 1U, 0, 0);
1146   Add(0, 3U, "001", "400", 1000000000U, 0, 0);
1147   Add(0, 31U, "001", "400", 1000000000U, 0, 0);
1148   Add(0, 32U, "001", "400", 1000000000U, 0, 0);
1149   Add(0, 33U, "001", "400", 1000000000U, 0, 0);
1150 
1151   // L1 total size 2GB, score 2.2. If one file being comapcted, score 1.1.
1152   Add(1, 4U, "050", "300", 1000000000U, 0, 0);
1153   file_map_[4u].first->being_compacted = true;
1154   Add(1, 5U, "301", "350", 1000000000U, 0, 0);
1155 
1156   // Output level overlaps with the beginning and the end of the chain
1157   Add(2, 6U, "050", "100", 1U);
1158   Add(2, 7U, "300", "400", 1U);
1159 
1160   // No compaction should be scheduled, if L0 has higher priority than L1
1161   // but L0->L1 compaction is blocked by a file in L1 being compacted.
1162   UpdateVersionStorageInfo();
1163   ASSERT_EQ(0, vstorage_->CompactionScoreLevel(0));
1164   ASSERT_EQ(1, vstorage_->CompactionScoreLevel(1));
1165   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1166       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1167   ASSERT_TRUE(compaction.get() == nullptr);
1168 }
1169 
TEST_F(CompactionPickerTest,NotScheduleL1IfL0WithHigherPri2)1170 TEST_F(CompactionPickerTest, NotScheduleL1IfL0WithHigherPri2) {
1171   NewVersionStorage(6, kCompactionStyleLevel);
1172   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
1173   mutable_cf_options_.max_bytes_for_level_base = 900000000U;
1174 
1175   // 6 L0 files, score 3.
1176   Add(0, 1U, "000", "400", 1U);
1177   Add(0, 2U, "001", "400", 1U, 0, 0);
1178   Add(0, 3U, "001", "400", 1000000000U, 0, 0);
1179   Add(0, 31U, "001", "400", 1000000000U, 0, 0);
1180   Add(0, 32U, "001", "400", 1000000000U, 0, 0);
1181   Add(0, 33U, "001", "400", 1000000000U, 0, 0);
1182 
1183   // L1 total size 2GB, score 2.2. If one file being comapcted, score 1.1.
1184   Add(1, 4U, "050", "300", 1000000000U, 0, 0);
1185   Add(1, 5U, "301", "350", 1000000000U, 0, 0);
1186 
1187   // Output level overlaps with the beginning and the end of the chain
1188   Add(2, 6U, "050", "100", 1U);
1189   Add(2, 7U, "300", "400", 1U);
1190 
1191   // If no file in L1 being compacted, L0->L1 compaction will be scheduled.
1192   UpdateVersionStorageInfo();  // being_compacted flag is cleared here.
1193   ASSERT_EQ(0, vstorage_->CompactionScoreLevel(0));
1194   ASSERT_EQ(1, vstorage_->CompactionScoreLevel(1));
1195   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1196       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1197   ASSERT_TRUE(compaction.get() != nullptr);
1198 }
1199 
TEST_F(CompactionPickerTest,NotScheduleL1IfL0WithHigherPri3)1200 TEST_F(CompactionPickerTest, NotScheduleL1IfL0WithHigherPri3) {
1201   NewVersionStorage(6, kCompactionStyleLevel);
1202   mutable_cf_options_.level0_file_num_compaction_trigger = 2;
1203   mutable_cf_options_.max_bytes_for_level_base = 900000000U;
1204 
1205   // 6 L0 files, score 3.
1206   Add(0, 1U, "000", "400", 1U);
1207   Add(0, 2U, "001", "400", 1U, 0, 0);
1208   Add(0, 3U, "001", "400", 1000000000U, 0, 0);
1209   Add(0, 31U, "001", "400", 1000000000U, 0, 0);
1210   Add(0, 32U, "001", "400", 1000000000U, 0, 0);
1211   Add(0, 33U, "001", "400", 1000000000U, 0, 0);
1212 
1213   // L1 score more than 6.
1214   Add(1, 4U, "050", "300", 1000000000U, 0, 0);
1215   file_map_[4u].first->being_compacted = true;
1216   Add(1, 5U, "301", "350", 1000000000U, 0, 0);
1217   Add(1, 51U, "351", "400", 6000000000U, 0, 0);
1218 
1219   // Output level overlaps with the beginning and the end of the chain
1220   Add(2, 6U, "050", "100", 1U);
1221   Add(2, 7U, "300", "400", 1U);
1222 
1223   // If score in L1 is larger than L0, L1 compaction goes through despite
1224   // there is pending L0 compaction.
1225   UpdateVersionStorageInfo();
1226   ASSERT_EQ(1, vstorage_->CompactionScoreLevel(0));
1227   ASSERT_EQ(0, vstorage_->CompactionScoreLevel(1));
1228   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1229       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1230   ASSERT_TRUE(compaction.get() != nullptr);
1231 }
1232 
TEST_F(CompactionPickerTest,EstimateCompactionBytesNeeded1)1233 TEST_F(CompactionPickerTest, EstimateCompactionBytesNeeded1) {
1234   int num_levels = ioptions_.num_levels;
1235   ioptions_.level_compaction_dynamic_level_bytes = false;
1236   mutable_cf_options_.level0_file_num_compaction_trigger = 4;
1237   mutable_cf_options_.max_bytes_for_level_base = 1000;
1238   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1239   NewVersionStorage(num_levels, kCompactionStyleLevel);
1240   Add(0, 1U, "150", "200", 200);
1241   Add(0, 2U, "150", "200", 200);
1242   Add(0, 3U, "150", "200", 200);
1243   // Level 1 is over target by 200
1244   Add(1, 4U, "400", "500", 600);
1245   Add(1, 5U, "600", "700", 600);
1246   // Level 2 is less than target 10000 even added size of level 1
1247   // Size ratio of L2/L1 is 9600 / 1200 = 8
1248   Add(2, 6U, "150", "200", 2500);
1249   Add(2, 7U, "201", "210", 2000);
1250   Add(2, 8U, "300", "310", 2600);
1251   Add(2, 9U, "400", "500", 2500);
1252   // Level 3 exceeds target 100,000 of 1000
1253   Add(3, 10U, "400", "500", 101000);
1254   // Level 4 exceeds target 1,000,000 by 900 after adding size from level 3
1255   // Size ratio L4/L3 is 9.9
1256   // After merge from L3, L4 size is 1000900
1257   Add(4, 11U, "400", "500", 999900);
1258   Add(5, 11U, "400", "500", 8007200);
1259 
1260   UpdateVersionStorageInfo();
1261 
1262   ASSERT_EQ(200u * 9u + 10900u + 900u * 9,
1263             vstorage_->estimated_compaction_needed_bytes());
1264 }
1265 
TEST_F(CompactionPickerTest,EstimateCompactionBytesNeeded2)1266 TEST_F(CompactionPickerTest, EstimateCompactionBytesNeeded2) {
1267   int num_levels = ioptions_.num_levels;
1268   ioptions_.level_compaction_dynamic_level_bytes = false;
1269   mutable_cf_options_.level0_file_num_compaction_trigger = 3;
1270   mutable_cf_options_.max_bytes_for_level_base = 1000;
1271   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1272   NewVersionStorage(num_levels, kCompactionStyleLevel);
1273   Add(0, 1U, "150", "200", 200);
1274   Add(0, 2U, "150", "200", 200);
1275   Add(0, 4U, "150", "200", 200);
1276   Add(0, 5U, "150", "200", 200);
1277   Add(0, 6U, "150", "200", 200);
1278   // Level 1 size will be 1400 after merging with L0
1279   Add(1, 7U, "400", "500", 200);
1280   Add(1, 8U, "600", "700", 200);
1281   // Level 2 is less than target 10000 even added size of level 1
1282   Add(2, 9U, "150", "200", 9100);
1283   // Level 3 over the target, but since level 4 is empty, we assume it will be
1284   // a trivial move.
1285   Add(3, 10U, "400", "500", 101000);
1286 
1287   UpdateVersionStorageInfo();
1288 
1289   // estimated L1->L2 merge: 400 * (9100.0 / 1400.0 + 1.0)
1290   ASSERT_EQ(1400u + 3000u, vstorage_->estimated_compaction_needed_bytes());
1291 }
1292 
TEST_F(CompactionPickerTest,EstimateCompactionBytesNeeded3)1293 TEST_F(CompactionPickerTest, EstimateCompactionBytesNeeded3) {
1294   int num_levels = ioptions_.num_levels;
1295   ioptions_.level_compaction_dynamic_level_bytes = false;
1296   mutable_cf_options_.level0_file_num_compaction_trigger = 3;
1297   mutable_cf_options_.max_bytes_for_level_base = 1000;
1298   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1299   NewVersionStorage(num_levels, kCompactionStyleLevel);
1300   Add(0, 1U, "150", "200", 2000);
1301   Add(0, 2U, "150", "200", 2000);
1302   Add(0, 4U, "150", "200", 2000);
1303   Add(0, 5U, "150", "200", 2000);
1304   Add(0, 6U, "150", "200", 1000);
1305   // Level 1 size will be 10000 after merging with L0
1306   Add(1, 7U, "400", "500", 500);
1307   Add(1, 8U, "600", "700", 500);
1308 
1309   Add(2, 9U, "150", "200", 10000);
1310 
1311   UpdateVersionStorageInfo();
1312 
1313   ASSERT_EQ(10000u + 18000u, vstorage_->estimated_compaction_needed_bytes());
1314 }
1315 
TEST_F(CompactionPickerTest,EstimateCompactionBytesNeededDynamicLevel)1316 TEST_F(CompactionPickerTest, EstimateCompactionBytesNeededDynamicLevel) {
1317   int num_levels = ioptions_.num_levels;
1318   ioptions_.level_compaction_dynamic_level_bytes = true;
1319   mutable_cf_options_.level0_file_num_compaction_trigger = 3;
1320   mutable_cf_options_.max_bytes_for_level_base = 1000;
1321   mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1322   NewVersionStorage(num_levels, kCompactionStyleLevel);
1323 
1324   // Set Last level size 50000
1325   // num_levels - 1 target 5000
1326   // num_levels - 2 is base level with target 1000 (rounded up to
1327   // max_bytes_for_level_base).
1328   Add(num_levels - 1, 10U, "400", "500", 50000);
1329 
1330   Add(0, 1U, "150", "200", 200);
1331   Add(0, 2U, "150", "200", 200);
1332   Add(0, 4U, "150", "200", 200);
1333   Add(0, 5U, "150", "200", 200);
1334   Add(0, 6U, "150", "200", 200);
1335   // num_levels - 3 is over target by 100 + 1000
1336   Add(num_levels - 3, 7U, "400", "500", 550);
1337   Add(num_levels - 3, 8U, "600", "700", 550);
1338   // num_levels - 2 is over target by 1100 + 200
1339   Add(num_levels - 2, 9U, "150", "200", 5200);
1340 
1341   UpdateVersionStorageInfo();
1342 
1343   // Merging to the second last level: (5200 / 2100 + 1) * 1100
1344   // Merging to the last level: (50000 / 6300 + 1) * 1300
1345   ASSERT_EQ(2100u + 3823u + 11617u,
1346             vstorage_->estimated_compaction_needed_bytes());
1347 }
1348 
TEST_F(CompactionPickerTest,IsBottommostLevelTest)1349 TEST_F(CompactionPickerTest, IsBottommostLevelTest) {
1350   // case 1: Higher levels are empty
1351   NewVersionStorage(6, kCompactionStyleLevel);
1352   Add(0, 1U, "a", "m");
1353   Add(0, 2U, "c", "z");
1354   Add(1, 3U, "d", "e");
1355   Add(1, 4U, "l", "p");
1356   Add(2, 5U, "g", "i");
1357   Add(2, 6U, "x", "z");
1358   UpdateVersionStorageInfo();
1359   SetCompactionInputFilesLevels(2, 1);
1360   AddToCompactionFiles(3U);
1361   AddToCompactionFiles(5U);
1362   bool result =
1363       Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1364   ASSERT_TRUE(result);
1365 
1366   // case 2: Higher levels have no overlap
1367   NewVersionStorage(6, kCompactionStyleLevel);
1368   Add(0, 1U, "a", "m");
1369   Add(0, 2U, "c", "z");
1370   Add(1, 3U, "d", "e");
1371   Add(1, 4U, "l", "p");
1372   Add(2, 5U, "g", "i");
1373   Add(2, 6U, "x", "z");
1374   Add(3, 7U, "k", "p");
1375   Add(3, 8U, "t", "w");
1376   Add(4, 9U, "a", "b");
1377   Add(5, 10U, "c", "cc");
1378   UpdateVersionStorageInfo();
1379   SetCompactionInputFilesLevels(2, 1);
1380   AddToCompactionFiles(3U);
1381   AddToCompactionFiles(5U);
1382   result = Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1383   ASSERT_TRUE(result);
1384 
1385   // case 3.1: Higher levels (level 3) have overlap
1386   NewVersionStorage(6, kCompactionStyleLevel);
1387   Add(0, 1U, "a", "m");
1388   Add(0, 2U, "c", "z");
1389   Add(1, 3U, "d", "e");
1390   Add(1, 4U, "l", "p");
1391   Add(2, 5U, "g", "i");
1392   Add(2, 6U, "x", "z");
1393   Add(3, 7U, "e", "g");
1394   Add(3, 8U, "h", "k");
1395   Add(4, 9U, "a", "b");
1396   Add(5, 10U, "c", "cc");
1397   UpdateVersionStorageInfo();
1398   SetCompactionInputFilesLevels(2, 1);
1399   AddToCompactionFiles(3U);
1400   AddToCompactionFiles(5U);
1401   result = Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1402   ASSERT_FALSE(result);
1403 
1404   // case 3.2: Higher levels (level 5) have overlap
1405   DeleteVersionStorage();
1406   NewVersionStorage(6, kCompactionStyleLevel);
1407   Add(0, 1U, "a", "m");
1408   Add(0, 2U, "c", "z");
1409   Add(1, 3U, "d", "e");
1410   Add(1, 4U, "l", "p");
1411   Add(2, 5U, "g", "i");
1412   Add(2, 6U, "x", "z");
1413   Add(3, 7U, "j", "k");
1414   Add(3, 8U, "l", "m");
1415   Add(4, 9U, "a", "b");
1416   Add(5, 10U, "c", "cc");
1417   Add(5, 11U, "h", "k");
1418   Add(5, 12U, "y", "yy");
1419   Add(5, 13U, "z", "zz");
1420   UpdateVersionStorageInfo();
1421   SetCompactionInputFilesLevels(2, 1);
1422   AddToCompactionFiles(3U);
1423   AddToCompactionFiles(5U);
1424   result = Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1425   ASSERT_FALSE(result);
1426 
1427   // case 3.3: Higher levels (level 5) have overlap, but it's only overlapping
1428   // one key ("d")
1429   NewVersionStorage(6, kCompactionStyleLevel);
1430   Add(0, 1U, "a", "m");
1431   Add(0, 2U, "c", "z");
1432   Add(1, 3U, "d", "e");
1433   Add(1, 4U, "l", "p");
1434   Add(2, 5U, "g", "i");
1435   Add(2, 6U, "x", "z");
1436   Add(3, 7U, "j", "k");
1437   Add(3, 8U, "l", "m");
1438   Add(4, 9U, "a", "b");
1439   Add(5, 10U, "c", "cc");
1440   Add(5, 11U, "ccc", "d");
1441   Add(5, 12U, "y", "yy");
1442   Add(5, 13U, "z", "zz");
1443   UpdateVersionStorageInfo();
1444   SetCompactionInputFilesLevels(2, 1);
1445   AddToCompactionFiles(3U);
1446   AddToCompactionFiles(5U);
1447   result = Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1448   ASSERT_FALSE(result);
1449 
1450   // Level 0 files overlap
1451   NewVersionStorage(6, kCompactionStyleLevel);
1452   Add(0, 1U, "s", "t");
1453   Add(0, 2U, "a", "m");
1454   Add(0, 3U, "b", "z");
1455   Add(0, 4U, "e", "f");
1456   Add(5, 10U, "y", "z");
1457   UpdateVersionStorageInfo();
1458   SetCompactionInputFilesLevels(1, 0);
1459   AddToCompactionFiles(1U);
1460   AddToCompactionFiles(2U);
1461   AddToCompactionFiles(3U);
1462   AddToCompactionFiles(4U);
1463   result = Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1464   ASSERT_FALSE(result);
1465 
1466   // Level 0 files don't overlap
1467   NewVersionStorage(6, kCompactionStyleLevel);
1468   Add(0, 1U, "s", "t");
1469   Add(0, 2U, "a", "m");
1470   Add(0, 3U, "b", "k");
1471   Add(0, 4U, "e", "f");
1472   Add(5, 10U, "y", "z");
1473   UpdateVersionStorageInfo();
1474   SetCompactionInputFilesLevels(1, 0);
1475   AddToCompactionFiles(1U);
1476   AddToCompactionFiles(2U);
1477   AddToCompactionFiles(3U);
1478   AddToCompactionFiles(4U);
1479   result = Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1480   ASSERT_TRUE(result);
1481 
1482   // Level 1 files overlap
1483   NewVersionStorage(6, kCompactionStyleLevel);
1484   Add(0, 1U, "s", "t");
1485   Add(0, 2U, "a", "m");
1486   Add(0, 3U, "b", "k");
1487   Add(0, 4U, "e", "f");
1488   Add(1, 5U, "a", "m");
1489   Add(1, 6U, "n", "o");
1490   Add(1, 7U, "w", "y");
1491   Add(5, 10U, "y", "z");
1492   UpdateVersionStorageInfo();
1493   SetCompactionInputFilesLevels(2, 0);
1494   AddToCompactionFiles(1U);
1495   AddToCompactionFiles(2U);
1496   AddToCompactionFiles(3U);
1497   AddToCompactionFiles(4U);
1498   AddToCompactionFiles(5U);
1499   AddToCompactionFiles(6U);
1500   AddToCompactionFiles(7U);
1501   result = Compaction::TEST_IsBottommostLevel(2, vstorage_.get(), input_files_);
1502   ASSERT_FALSE(result);
1503 
1504   DeleteVersionStorage();
1505 }
1506 
TEST_F(CompactionPickerTest,MaxCompactionBytesHit)1507 TEST_F(CompactionPickerTest, MaxCompactionBytesHit) {
1508   mutable_cf_options_.max_bytes_for_level_base = 1000000u;
1509   mutable_cf_options_.max_compaction_bytes = 800000u;
1510   ioptions_.level_compaction_dynamic_level_bytes = false;
1511   NewVersionStorage(6, kCompactionStyleLevel);
1512   // A compaction should be triggered and pick file 2 and 5.
1513   // It can expand because adding file 1 and 3, the compaction size will
1514   // exceed mutable_cf_options_.max_bytes_for_level_base.
1515   Add(1, 1U, "100", "150", 300000U);
1516   Add(1, 2U, "151", "200", 300001U, 0, 0);
1517   Add(1, 3U, "201", "250", 300000U, 0, 0);
1518   Add(1, 4U, "251", "300", 300000U, 0, 0);
1519   Add(2, 5U, "100", "256", 1U);
1520   UpdateVersionStorageInfo();
1521 
1522   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1523       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1524   ASSERT_TRUE(compaction.get() != nullptr);
1525   ASSERT_EQ(2U, compaction->num_input_levels());
1526   ASSERT_EQ(1U, compaction->num_input_files(0));
1527   ASSERT_EQ(1U, compaction->num_input_files(1));
1528   ASSERT_EQ(2U, compaction->input(0, 0)->fd.GetNumber());
1529   ASSERT_EQ(5U, compaction->input(1, 0)->fd.GetNumber());
1530 }
1531 
TEST_F(CompactionPickerTest,MaxCompactionBytesNotHit)1532 TEST_F(CompactionPickerTest, MaxCompactionBytesNotHit) {
1533   mutable_cf_options_.max_bytes_for_level_base = 800000u;
1534   mutable_cf_options_.max_compaction_bytes = 1000000u;
1535   ioptions_.level_compaction_dynamic_level_bytes = false;
1536   NewVersionStorage(6, kCompactionStyleLevel);
1537   // A compaction should be triggered and pick file 2 and 5.
1538   // and it expands to file 1 and 3 too.
1539   Add(1, 1U, "100", "150", 300000U);
1540   Add(1, 2U, "151", "200", 300001U, 0, 0);
1541   Add(1, 3U, "201", "250", 300000U, 0, 0);
1542   Add(1, 4U, "251", "300", 300000U, 0, 0);
1543   Add(2, 5U, "000", "251", 1U);
1544   UpdateVersionStorageInfo();
1545 
1546   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1547       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1548   ASSERT_TRUE(compaction.get() != nullptr);
1549   ASSERT_EQ(2U, compaction->num_input_levels());
1550   ASSERT_EQ(3U, compaction->num_input_files(0));
1551   ASSERT_EQ(1U, compaction->num_input_files(1));
1552   ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
1553   ASSERT_EQ(2U, compaction->input(0, 1)->fd.GetNumber());
1554   ASSERT_EQ(3U, compaction->input(0, 2)->fd.GetNumber());
1555   ASSERT_EQ(5U, compaction->input(1, 0)->fd.GetNumber());
1556 }
1557 
TEST_F(CompactionPickerTest,IsTrivialMoveOn)1558 TEST_F(CompactionPickerTest, IsTrivialMoveOn) {
1559   mutable_cf_options_.max_bytes_for_level_base = 10000u;
1560   mutable_cf_options_.max_compaction_bytes = 10001u;
1561   ioptions_.level_compaction_dynamic_level_bytes = false;
1562   NewVersionStorage(6, kCompactionStyleLevel);
1563   // A compaction should be triggered and pick file 2
1564   Add(1, 1U, "100", "150", 3000U);
1565   Add(1, 2U, "151", "200", 3001U);
1566   Add(1, 3U, "201", "250", 3000U);
1567   Add(1, 4U, "251", "300", 3000U);
1568 
1569   Add(3, 5U, "120", "130", 7000U);
1570   Add(3, 6U, "170", "180", 7000U);
1571   Add(3, 5U, "220", "230", 7000U);
1572   Add(3, 5U, "270", "280", 7000U);
1573   UpdateVersionStorageInfo();
1574 
1575   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1576     cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1577   ASSERT_TRUE(compaction.get() != nullptr);
1578   ASSERT_TRUE(compaction->IsTrivialMove());
1579 }
1580 
TEST_F(CompactionPickerTest,IsTrivialMoveOff)1581 TEST_F(CompactionPickerTest, IsTrivialMoveOff) {
1582   mutable_cf_options_.max_bytes_for_level_base = 1000000u;
1583   mutable_cf_options_.max_compaction_bytes = 10000u;
1584   ioptions_.level_compaction_dynamic_level_bytes = false;
1585   NewVersionStorage(6, kCompactionStyleLevel);
1586   // A compaction should be triggered and pick all files from level 1
1587   Add(1, 1U, "100", "150", 300000U, 0, 0);
1588   Add(1, 2U, "150", "200", 300000U, 0, 0);
1589   Add(1, 3U, "200", "250", 300000U, 0, 0);
1590   Add(1, 4U, "250", "300", 300000U, 0, 0);
1591 
1592   Add(3, 5U, "120", "130", 6000U);
1593   Add(3, 6U, "140", "150", 6000U);
1594   UpdateVersionStorageInfo();
1595 
1596   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1597     cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1598   ASSERT_TRUE(compaction.get() != nullptr);
1599   ASSERT_FALSE(compaction->IsTrivialMove());
1600 }
1601 
TEST_F(CompactionPickerTest,CacheNextCompactionIndex)1602 TEST_F(CompactionPickerTest, CacheNextCompactionIndex) {
1603   NewVersionStorage(6, kCompactionStyleLevel);
1604   mutable_cf_options_.max_compaction_bytes = 100000000000u;
1605 
1606   Add(1 /* level */, 1U /* file_number */, "100" /* smallest */,
1607       "149" /* largest */, 1000000000U /* file_size */);
1608   file_map_[1U].first->being_compacted = true;
1609   Add(1 /* level */, 2U /* file_number */, "150" /* smallest */,
1610       "199" /* largest */, 900000000U /* file_size */);
1611   Add(1 /* level */, 3U /* file_number */, "200" /* smallest */,
1612       "249" /* largest */, 800000000U /* file_size */);
1613   Add(1 /* level */, 4U /* file_number */, "250" /* smallest */,
1614       "299" /* largest */, 700000000U /* file_size */);
1615   Add(2 /* level */, 5U /* file_number */, "150" /* smallest */,
1616       "199" /* largest */, 1U /* file_size */);
1617   file_map_[5U].first->being_compacted = true;
1618 
1619   UpdateVersionStorageInfo();
1620 
1621   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1622       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1623   ASSERT_TRUE(compaction.get() != nullptr);
1624   ASSERT_EQ(1U, compaction->num_input_levels());
1625   ASSERT_EQ(1U, compaction->num_input_files(0));
1626   ASSERT_EQ(0U, compaction->num_input_files(1));
1627   ASSERT_EQ(3U, compaction->input(0, 0)->fd.GetNumber());
1628   ASSERT_EQ(2, vstorage_->NextCompactionIndex(1 /* level */));
1629 
1630   compaction.reset(level_compaction_picker.PickCompaction(
1631       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1632   ASSERT_TRUE(compaction.get() != nullptr);
1633   ASSERT_EQ(1U, compaction->num_input_levels());
1634   ASSERT_EQ(1U, compaction->num_input_files(0));
1635   ASSERT_EQ(0U, compaction->num_input_files(1));
1636   ASSERT_EQ(4U, compaction->input(0, 0)->fd.GetNumber());
1637   ASSERT_EQ(3, vstorage_->NextCompactionIndex(1 /* level */));
1638 
1639   compaction.reset(level_compaction_picker.PickCompaction(
1640       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1641   ASSERT_TRUE(compaction.get() == nullptr);
1642   ASSERT_EQ(4, vstorage_->NextCompactionIndex(1 /* level */));
1643 }
1644 
TEST_F(CompactionPickerTest,IntraL0MaxCompactionBytesNotHit)1645 TEST_F(CompactionPickerTest, IntraL0MaxCompactionBytesNotHit) {
1646   // Intra L0 compaction triggers only if there are at least
1647   // level0_file_num_compaction_trigger + 2 L0 files.
1648   mutable_cf_options_.level0_file_num_compaction_trigger = 3;
1649   mutable_cf_options_.max_compaction_bytes = 1000000u;
1650   NewVersionStorage(6, kCompactionStyleLevel);
1651 
1652   // All 5 L0 files will be picked for intra L0 compaction. The one L1 file
1653   // spans entire L0 key range and is marked as being compacted to avoid
1654   // L0->L1 compaction.
1655   Add(0, 1U, "100", "150", 200000U, 0, 100, 101);
1656   Add(0, 2U, "151", "200", 200000U, 0, 102, 103);
1657   Add(0, 3U, "201", "250", 200000U, 0, 104, 105);
1658   Add(0, 4U, "251", "300", 200000U, 0, 106, 107);
1659   Add(0, 5U, "301", "350", 200000U, 0, 108, 109);
1660   Add(1, 6U, "100", "350", 200000U, 0, 110, 111);
1661   vstorage_->LevelFiles(1)[0]->being_compacted = true;
1662   UpdateVersionStorageInfo();
1663 
1664   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1665       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1666   ASSERT_TRUE(compaction.get() != nullptr);
1667   ASSERT_EQ(1U, compaction->num_input_levels());
1668   ASSERT_EQ(5U, compaction->num_input_files(0));
1669   ASSERT_EQ(CompactionReason::kLevelL0FilesNum,
1670             compaction->compaction_reason());
1671   ASSERT_EQ(0, compaction->output_level());
1672 }
1673 
TEST_F(CompactionPickerTest,IntraL0MaxCompactionBytesHit)1674 TEST_F(CompactionPickerTest, IntraL0MaxCompactionBytesHit) {
1675   // Intra L0 compaction triggers only if there are at least
1676   // level0_file_num_compaction_trigger + 2 L0 files.
1677   mutable_cf_options_.level0_file_num_compaction_trigger = 3;
1678   mutable_cf_options_.max_compaction_bytes = 999999u;
1679   NewVersionStorage(6, kCompactionStyleLevel);
1680 
1681   // 4 out of 5 L0 files will be picked for intra L0 compaction due to
1682   // max_compaction_bytes limit (the minimum number of files for triggering
1683   // intra L0 compaction is 4). The one L1 file spans entire L0 key range and
1684   // is marked as being compacted to avoid L0->L1 compaction.
1685   Add(0, 1U, "100", "150", 200000U, 0, 100, 101);
1686   Add(0, 2U, "151", "200", 200000U, 0, 102, 103);
1687   Add(0, 3U, "201", "250", 200000U, 0, 104, 105);
1688   Add(0, 4U, "251", "300", 200000U, 0, 106, 107);
1689   Add(0, 5U, "301", "350", 200000U, 0, 108, 109);
1690   Add(1, 6U, "100", "350", 200000U, 0, 109, 110);
1691   vstorage_->LevelFiles(1)[0]->being_compacted = true;
1692   UpdateVersionStorageInfo();
1693 
1694   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1695       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
1696   ASSERT_TRUE(compaction.get() != nullptr);
1697   ASSERT_EQ(1U, compaction->num_input_levels());
1698   ASSERT_EQ(4U, compaction->num_input_files(0));
1699   ASSERT_EQ(CompactionReason::kLevelL0FilesNum,
1700             compaction->compaction_reason());
1701   ASSERT_EQ(0, compaction->output_level());
1702 }
1703 
TEST_F(CompactionPickerTest,IntraL0ForEarliestSeqno)1704 TEST_F(CompactionPickerTest, IntraL0ForEarliestSeqno) {
1705   // Intra L0 compaction triggers only if there are at least
1706   // level0_file_num_compaction_trigger + 2 L0 files.
1707   mutable_cf_options_.level0_file_num_compaction_trigger = 3;
1708   mutable_cf_options_.max_compaction_bytes = 999999u;
1709   NewVersionStorage(6, kCompactionStyleLevel);
1710 
1711   // 4 out of 6 L0 files will be picked for intra L0 compaction due to
1712   // being_compact limit. And the latest one L0 will be skipped due to earliest
1713   // seqno. The one L1 file spans entire L0 key range and is marked as being
1714   // compacted to avoid L0->L1 compaction.
1715   Add(1, 1U, "100", "350", 200000U, 0, 110, 111);
1716   Add(0, 2U, "301", "350", 1U, 0, 108, 109);
1717   Add(0, 3U, "251", "300", 1U, 0, 106, 107);
1718   Add(0, 4U, "201", "250", 1U, 0, 104, 105);
1719   Add(0, 5U, "151", "200", 1U, 0, 102, 103);
1720   Add(0, 6U, "100", "150", 1U, 0, 100, 101);
1721   Add(0, 7U, "100", "100", 1U, 0, 99, 100);
1722   vstorage_->LevelFiles(0)[5]->being_compacted = true;
1723   vstorage_->LevelFiles(1)[0]->being_compacted = true;
1724   UpdateVersionStorageInfo();
1725 
1726   std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
1727       cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_, 107));
1728   ASSERT_TRUE(compaction.get() != nullptr);
1729   ASSERT_EQ(1U, compaction->num_input_levels());
1730   ASSERT_EQ(4U, compaction->num_input_files(0));
1731   ASSERT_EQ(CompactionReason::kLevelL0FilesNum,
1732             compaction->compaction_reason());
1733   ASSERT_EQ(0, compaction->output_level());
1734 }
1735 
1736 }  // namespace ROCKSDB_NAMESPACE
1737 
main(int argc,char ** argv)1738 int main(int argc, char** argv) {
1739   ::testing::InitGoogleTest(&argc, argv);
1740   return RUN_ALL_TESTS();
1741 }
1742