compaction_picker_test.cc 69 KB

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