diff --git a/db/db_impl.cc b/db/db_impl.cc index 03b7c6b..058ef78 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -604,34 +604,6 @@ void DBImpl::TEST_CompactRange(int level, const Slice* begin, assert(level >= 0); assert(level < config::kNumLevels); - // if (level == config::kNumLevels - 1) { - // // TTL: TODO: update files in the last level - // mutex_.AssertHeld(); - - // Compaction* c; - // c = versions_->CompactRange(level, begin, end); - - // Iterator* files = versions_->MakeInputIterator(c); - - // while (files->Valid() && !shutting_down_.load(std::memory_order_acquire)) { - // std::string value = files->value().ToString(); - // uint64_t ddl; - // DecodeDeadLineValue(&value, ddl); - - // if (ddl != 0) { - // if (ddl <= std::time(nullptr)) { - // c->edit()->RemoveFile(c->level(), number); - // versions_->LogAndApply(c->edit(), &mutex_); - // } - // } - - - // files->Next(); - // } - - // return; - // } - InternalKey begin_storage, end_storage; ManualCompaction manual; @@ -947,8 +919,14 @@ Status DBImpl::InstallCompactionResults(CompactionState* compact) { const int level = compact->compaction->level(); for (size_t i = 0; i < compact->outputs.size(); i++) { const CompactionState::Output& out = compact->outputs[i]; - compact->compaction->edit()->AddFile(level + 1, out.number, out.file_size, - out.smallest, out.largest); + if (level < config::kNumLevels - 1) { + compact->compaction->edit()->AddFile(level + 1, out.number, out.file_size, + out.smallest, out.largest); + } else { + // TTL: outputs of last level compaction should be writen to last level itself + compact->compaction->edit()->AddFile(level, out.number, out.file_size, + out.smallest, out.largest); + } } return versions_->LogAndApply(compact->compaction->edit(), &mutex_); } @@ -1109,7 +1087,12 @@ Status DBImpl::DoCompactionWork(CompactionState* compact) { } mutex_.Lock(); - stats_[compact->compaction->level() + 1].Add(stats); + if (compact->compaction->level() + 1 < config::kNumLevels) { + stats_[compact->compaction->level() + 1].Add(stats); + } else { + // TTL: compaction for last level + stats_[compact->compaction->level()].Add(stats); + } if (status.ok()) { status = InstallCompactionResults(compact); diff --git a/db/dbformat.h b/db/dbformat.h index a1c30ed..6dc0ba8 100644 --- a/db/dbformat.h +++ b/db/dbformat.h @@ -22,7 +22,7 @@ namespace leveldb { // Grouping of constants. We may want to make some of these // parameters set via options. namespace config { -static const int kNumLevels = 7; +static const int kNumLevels = 3; // Level-0 compaction is started when we hit this many files. static const int kL0_CompactionTrigger = 4; diff --git a/db/version_set.cc b/db/version_set.cc index 4e37bf9..b147e08 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -1104,13 +1104,11 @@ int VersionSet::NumLevelFiles(int level) const { const char* VersionSet::LevelSummary(LevelSummaryStorage* scratch) const { // Update code if kNumLevels changes - static_assert(config::kNumLevels == 7, ""); + static_assert(config::kNumLevels == 3, ""); std::snprintf( - scratch->buffer, sizeof(scratch->buffer), "files[ %d %d %d %d %d %d %d ]", + scratch->buffer, sizeof(scratch->buffer), "files[ %d %d %d ]", int(current_->files_[0].size()), int(current_->files_[1].size()), - int(current_->files_[2].size()), int(current_->files_[3].size()), - int(current_->files_[4].size()), int(current_->files_[5].size()), - int(current_->files_[6].size())); + int(current_->files_[2].size())); return scratch->buffer; } @@ -1389,9 +1387,12 @@ void VersionSet::SetupOtherInputs(Compaction* c) { AddBoundaryInputs(icmp_, current_->files_[level], &c->inputs_[0]); GetRange(c->inputs_[0], &smallest, &largest); - current_->GetOverlappingInputs(level + 1, &smallest, &largest, - &c->inputs_[1]); - AddBoundaryInputs(icmp_, current_->files_[level + 1], &c->inputs_[1]); + // TTL: manual compaction for last level shouldn't have inputs[1] + if (level + 1 < config::kNumLevels) { + current_->GetOverlappingInputs(level + 1, &smallest, &largest, + &c->inputs_[1]); + AddBoundaryInputs(icmp_, current_->files_[level + 1], &c->inputs_[1]); + } // Get entire range covered by compaction InternalKey all_start, all_limit; diff --git a/test/ttl_test.cc b/test/ttl_test.cc index 06da85d..ea71c06 100644 --- a/test/ttl_test.cc +++ b/test/ttl_test.cc @@ -92,11 +92,9 @@ TEST(TestTTL, CompactionTTL) { uint64_t sizes[1]; db->GetApproximateSizes(ranges, 1, sizes); ASSERT_GT(sizes[0], 0); - Env::Default()->SleepForMicroseconds(ttl * 1000000); db->CompactRange(nullptr, nullptr); - leveldb::Range ranges1[1]; ranges1[0] = leveldb::Range("-", "A"); uint64_t sizes1[1]; @@ -106,6 +104,42 @@ TEST(TestTTL, CompactionTTL) { delete db; } +// Test handling last level with kNumLevels = 3 +TEST(TestTTL, LastLevelCompaction) { + DB *db; + + if(OpenDB("testdb", &db).ok() == false) { + std::cerr << "open db failed" << std::endl; + abort(); + } + + uint64_t ttl = 20; + InsertData(db, ttl); + + leveldb::Range ranges[1]; + ranges[0] = leveldb::Range("-", "A"); + uint64_t sizes[1]; + db->GetApproximateSizes(ranges, 1, sizes); + ASSERT_GT(sizes[0], 0); + + std::string last_level_file_num; + std::string last_level = "2"; + db->GetProperty("leveldb.num-files-at-level" + last_level, &last_level_file_num); + std::cout << "File nums in last level: " << last_level_file_num << std::endl; + ASSERT_GT(std::atoi(last_level_file_num.c_str()), 0); + + Env::Default()->SleepForMicroseconds(ttl * 1000000); + + db->CompactRange(nullptr, nullptr); + leveldb::Range ranges1[1]; + ranges1[0] = leveldb::Range("-", "A"); + uint64_t sizes1[1]; + db->GetApproximateSizes(ranges1, 1, sizes1); + ASSERT_EQ(sizes1[0], 0); + + delete db; +} + int main(int argc, char** argv) { // All tests currently run with the same read-only file limits.