diff --git a/db/compaction.cc b/db/compaction.cc index 9ea332da3..706eb3be0 100644 --- a/db/compaction.cc +++ b/db/compaction.cc @@ -284,32 +284,32 @@ bool Compaction::KeyNotExistsBeyondOutputLevel( assert(input_version_ != nullptr); assert(level_ptrs != nullptr); assert(level_ptrs->size() == static_cast(number_levels_)); - assert(cfd_->ioptions()->compaction_style != kCompactionStyleFIFO); - if (cfd_->ioptions()->compaction_style == kCompactionStyleUniversal) { - return bottommost_level_; - } - if (cfd_->ioptions()->compaction_style == kCompactionStyleLevel && - output_level_ == 0) { - return false; - } - // Maybe use binary search to find right entry instead of linear search? - const Comparator* user_cmp = cfd_->user_comparator(); - for (int lvl = output_level_ + 1; lvl < number_levels_; lvl++) { - const std::vector& files = input_vstorage_->LevelFiles(lvl); - for (; level_ptrs->at(lvl) < files.size(); level_ptrs->at(lvl)++) { - auto* f = files[level_ptrs->at(lvl)]; - if (user_cmp->Compare(user_key, f->largest.user_key()) <= 0) { - // We've advanced far enough - if (user_cmp->Compare(user_key, f->smallest.user_key()) >= 0) { - // Key falls in this file's range, so definitely - // exists beyond output level - return false; + if (cfd_->ioptions()->compaction_style == kCompactionStyleLevel) { + if (output_level_ == 0) { + return false; + } + // Maybe use binary search to find right entry instead of linear search? + const Comparator* user_cmp = cfd_->user_comparator(); + for (int lvl = output_level_ + 1; lvl < number_levels_; lvl++) { + const std::vector& files = + input_vstorage_->LevelFiles(lvl); + for (; level_ptrs->at(lvl) < files.size(); level_ptrs->at(lvl)++) { + auto* f = files[level_ptrs->at(lvl)]; + if (user_cmp->Compare(user_key, f->largest.user_key()) <= 0) { + // We've advanced far enough + if (user_cmp->Compare(user_key, f->smallest.user_key()) >= 0) { + // Key falls in this file's range, so definitely + // exists beyond output level + return false; + } + break; } - break; } } + return true; + } else { + return bottommost_level_; } - return true; } // Mark (or clear) each file that is being compacted diff --git a/db/db_test.cc b/db/db_test.cc index 675c403e5..fddb7aea6 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -2811,6 +2811,46 @@ TEST_F(DBTest, FIFOCompactionTestWithCompaction) { options.compaction_options_fifo.max_table_files_size); } +TEST_F(DBTest, FIFOCompactionStyleWithCompactionAndDelete) { + Options options; + options.compaction_style = kCompactionStyleFIFO; + options.write_buffer_size = 20 << 10; // 20K + options.arena_block_size = 4096; + options.compaction_options_fifo.max_table_files_size = 1500 << 10; // 1MB + options.compaction_options_fifo.allow_compaction = true; + options.level0_file_num_compaction_trigger = 3; + options.compression = kNoCompression; + options.create_if_missing = true; + options = CurrentOptions(options); + DestroyAndReopen(options); + + Random rnd(301); + for (int i = 0; i < 3; i++) { + // Each file contains a different key which will be dropped later. + ASSERT_OK(Put("a" + ToString(i), RandomString(&rnd, 500))); + ASSERT_OK(Put("key" + ToString(i), "")); + ASSERT_OK(Put("z" + ToString(i), RandomString(&rnd, 500))); + Flush(); + ASSERT_OK(dbfull()->TEST_WaitForCompact()); + } + ASSERT_EQ(NumTableFilesAtLevel(0), 1); + for (int i = 0; i < 3; i++) { + ASSERT_EQ("", Get("key" + ToString(i))); + } + for (int i = 0; i < 3; i++) { + // Each file contains a different key which will be dropped later. + ASSERT_OK(Put("a" + ToString(i), RandomString(&rnd, 500))); + ASSERT_OK(Delete("key" + ToString(i))); + ASSERT_OK(Put("z" + ToString(i), RandomString(&rnd, 500))); + Flush(); + ASSERT_OK(dbfull()->TEST_WaitForCompact()); + } + ASSERT_EQ(NumTableFilesAtLevel(0), 2); + for (int i = 0; i < 3; i++) { + ASSERT_EQ("NOT_FOUND", Get("key" + ToString(i))); + } +} + // Check that FIFO-with-TTL is not supported with max_open_files != -1. TEST_F(DBTest, FIFOCompactionWithTTLAndMaxOpenFilesTest) { Options options;