rename FileLevel to LevelFilesBrief / unfriend CompactedDBImpl

Summary:
We have several different types of data structures for file information.
FileLevel is kinda of confusing since it only contains file range and
fd. Rename it to LevelFilesBrief to make it clear.
Unfriend CompactedDBImpl as a by product

Test Plan:
make release / make all
will run full test with all stacked diffs

Reviewers: sdong, yhchiang, rven, igor

Reviewed By: igor

Subscribers: dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D27585
main
Lei Jin 10 years ago
parent a28b3c4388
commit 834c67d77f
  1. 3
      db/compaction.cc
  2. 6
      db/compaction.h
  3. 4
      db/version_edit.h
  4. 75
      db/version_set.cc
  5. 28
      db/version_set.h
  6. 22
      db/version_set_test.cc
  7. 19
      utilities/compacted_db/compacted_db_impl.cc
  8. 2
      utilities/compacted_db/compacted_db_impl.h

@ -86,7 +86,8 @@ Compaction::~Compaction() {
void Compaction::GenerateFileLevels() { void Compaction::GenerateFileLevels() {
input_levels_.resize(num_input_levels()); input_levels_.resize(num_input_levels());
for (int which = 0; which < num_input_levels(); which++) { for (int which = 0; which < num_input_levels(); which++) {
DoGenerateFileLevel(&input_levels_[which], inputs_[which].files, &arena_); DoGenerateLevelFilesBrief(
&input_levels_[which], inputs_[which].files, &arena_);
} }
} }

@ -89,8 +89,8 @@ class Compaction {
return &inputs_[compaction_input_level].files; return &inputs_[compaction_input_level].files;
} }
// Returns the FileLevel of the specified compaction input level. // Returns the LevelFilesBrief of the specified compaction input level.
FileLevel* input_levels(int compaction_input_level) { LevelFilesBrief* input_levels(int compaction_input_level) {
return &input_levels_[compaction_input_level]; return &input_levels_[compaction_input_level];
} }
@ -193,7 +193,7 @@ class Compaction {
autovector<CompactionInputFiles> inputs_; autovector<CompactionInputFiles> inputs_;
// A copy of inputs_, organized more closely in memory // A copy of inputs_, organized more closely in memory
autovector<FileLevel, 2> input_levels_; autovector<LevelFilesBrief, 2> input_levels_;
// State used to check for number of of overlapping grandparent files // State used to check for number of of overlapping grandparent files
// (grandparent == "output_level_ + 1") // (grandparent == "output_level_ + 1")

@ -120,10 +120,10 @@ struct FdWithKeyRange {
// Data structure to store an array of FdWithKeyRange in one level // Data structure to store an array of FdWithKeyRange in one level
// Actual data is guaranteed to be stored closely // Actual data is guaranteed to be stored closely
struct FileLevel { struct LevelFilesBrief {
size_t num_files; size_t num_files;
FdWithKeyRange* files; FdWithKeyRange* files;
FileLevel() { LevelFilesBrief() {
num_files = 0; num_files = 0;
files = nullptr; files = nullptr;
} }

@ -46,10 +46,10 @@ namespace rocksdb {
namespace { namespace {
// Find File in FileLevel data structure // Find File in LevelFilesBrief data structure
// Within an index range defined by left and right // Within an index range defined by left and right
int FindFileInRange(const InternalKeyComparator& icmp, int FindFileInRange(const InternalKeyComparator& icmp,
const FileLevel& file_level, const LevelFilesBrief& file_level,
const Slice& key, const Slice& key,
uint32_t left, uint32_t left,
uint32_t right) { uint32_t right) {
@ -102,7 +102,7 @@ class FilePicker {
std::vector<FileMetaData*>* files, std::vector<FileMetaData*>* files,
const Slice& user_key, const Slice& user_key,
const Slice& ikey, const Slice& ikey,
autovector<FileLevel>* file_levels, autovector<LevelFilesBrief>* file_levels,
unsigned int num_levels, unsigned int num_levels,
FileIndexer* file_indexer, FileIndexer* file_indexer,
const Comparator* user_comparator, const Comparator* user_comparator,
@ -114,7 +114,7 @@ class FilePicker {
#ifndef NDEBUG #ifndef NDEBUG
files_(files), files_(files),
#endif #endif
file_levels_(file_levels), level_files_brief_(file_levels),
user_key_(user_key), user_key_(user_key),
ikey_(ikey), ikey_(ikey),
file_indexer_(file_indexer), file_indexer_(file_indexer),
@ -124,8 +124,8 @@ class FilePicker {
search_ended_ = !PrepareNextLevel(); search_ended_ = !PrepareNextLevel();
if (!search_ended_) { if (!search_ended_) {
// Prefetch Level 0 table data to avoid cache miss if possible. // Prefetch Level 0 table data to avoid cache miss if possible.
for (unsigned int i = 0; i < (*file_levels_)[0].num_files; ++i) { for (unsigned int i = 0; i < (*level_files_brief_)[0].num_files; ++i) {
auto* r = (*file_levels_)[0].files[i].fd.table_reader; auto* r = (*level_files_brief_)[0].files[i].fd.table_reader;
if (r) { if (r) {
r->Prepare(ikey); r->Prepare(ikey);
} }
@ -225,9 +225,9 @@ class FilePicker {
#ifndef NDEBUG #ifndef NDEBUG
std::vector<FileMetaData*>* files_; std::vector<FileMetaData*>* files_;
#endif #endif
autovector<FileLevel>* file_levels_; autovector<LevelFilesBrief>* level_files_brief_;
bool search_ended_; bool search_ended_;
FileLevel* curr_file_level_; LevelFilesBrief* curr_file_level_;
unsigned int curr_index_in_curr_level_; unsigned int curr_index_in_curr_level_;
unsigned int start_index_in_curr_level_; unsigned int start_index_in_curr_level_;
Slice user_key_; Slice user_key_;
@ -244,7 +244,7 @@ class FilePicker {
bool PrepareNextLevel() { bool PrepareNextLevel() {
curr_level_++; curr_level_++;
while (curr_level_ < num_levels_) { while (curr_level_ < num_levels_) {
curr_file_level_ = &(*file_levels_)[curr_level_]; curr_file_level_ = &(*level_files_brief_)[curr_level_];
if (curr_file_level_->num_files == 0) { if (curr_file_level_->num_files == 0) {
// When current level is empty, the search bound generated from upper // When current level is empty, the search bound generated from upper
// level must be [0, -1] or [0, FileIndexer::kLevelMaxIndex] if it is // level must be [0, -1] or [0, FileIndexer::kLevelMaxIndex] if it is
@ -331,12 +331,12 @@ Version::~Version() {
} }
int FindFile(const InternalKeyComparator& icmp, int FindFile(const InternalKeyComparator& icmp,
const FileLevel& file_level, const LevelFilesBrief& file_level,
const Slice& key) { const Slice& key) {
return FindFileInRange(icmp, file_level, key, 0, file_level.num_files); return FindFileInRange(icmp, file_level, key, 0, file_level.num_files);
} }
void DoGenerateFileLevel(FileLevel* file_level, void DoGenerateLevelFilesBrief(LevelFilesBrief* file_level,
const std::vector<FileMetaData*>& files, const std::vector<FileMetaData*>& files,
Arena* arena) { Arena* arena) {
assert(file_level); assert(file_level);
@ -383,7 +383,7 @@ static bool BeforeFile(const Comparator* ucmp,
bool SomeFileOverlapsRange( bool SomeFileOverlapsRange(
const InternalKeyComparator& icmp, const InternalKeyComparator& icmp,
bool disjoint_sorted_files, bool disjoint_sorted_files,
const FileLevel& file_level, const LevelFilesBrief& file_level,
const Slice* smallest_user_key, const Slice* smallest_user_key,
const Slice* largest_user_key) { const Slice* largest_user_key) {
const Comparator* ucmp = icmp.user_comparator(); const Comparator* ucmp = icmp.user_comparator();
@ -425,7 +425,7 @@ bool SomeFileOverlapsRange(
class Version::LevelFileNumIterator : public Iterator { class Version::LevelFileNumIterator : public Iterator {
public: public:
LevelFileNumIterator(const InternalKeyComparator& icmp, LevelFileNumIterator(const InternalKeyComparator& icmp,
const FileLevel* flevel) const LevelFilesBrief* flevel)
: icmp_(icmp), : icmp_(icmp),
flevel_(flevel), flevel_(flevel),
index_(flevel->num_files), index_(flevel->num_files),
@ -468,7 +468,7 @@ class Version::LevelFileNumIterator : public Iterator {
virtual Status status() const { return Status::OK(); } virtual Status status() const { return Status::OK(); }
private: private:
const InternalKeyComparator icmp_; const InternalKeyComparator icmp_;
const FileLevel* flevel_; const LevelFilesBrief* flevel_;
uint32_t index_; uint32_t index_;
mutable FileDescriptor current_value_; mutable FileDescriptor current_value_;
}; };
@ -582,7 +582,7 @@ Status Version::GetPropertiesOfAllTables(TablePropertiesCollection* props) {
size_t Version::GetMemoryUsageByTableReaders() { size_t Version::GetMemoryUsageByTableReaders() {
size_t total_usage = 0; size_t total_usage = 0;
for (auto& file_level : file_levels_) { for (auto& file_level : level_files_brief_) {
for (size_t i = 0; i < file_level.num_files; i++) { for (size_t i = 0; i < file_level.num_files; i++) {
total_usage += cfd_->table_cache()->GetMemoryUsageByTableReader( total_usage += cfd_->table_cache()->GetMemoryUsageByTableReader(
vset_->env_options_, cfd_->internal_comparator(), vset_->env_options_, cfd_->internal_comparator(),
@ -618,8 +618,8 @@ void Version::AddIterators(const ReadOptions& read_options,
assert(finalized_); assert(finalized_);
// Merge all level zero files together since they may overlap // Merge all level zero files together since they may overlap
for (size_t i = 0; i < file_levels_[0].num_files; i++) { for (size_t i = 0; i < level_files_brief_[0].num_files; i++) {
const auto& file = file_levels_[0].files[i]; const auto& file = level_files_brief_[0].files[i];
merge_iter_builder->AddIterator(cfd_->table_cache()->NewIterator( merge_iter_builder->AddIterator(cfd_->table_cache()->NewIterator(
read_options, soptions, cfd_->internal_comparator(), file.fd, nullptr, read_options, soptions, cfd_->internal_comparator(), file.fd, nullptr,
false, merge_iter_builder->GetArena())); false, merge_iter_builder->GetArena()));
@ -629,14 +629,14 @@ void Version::AddIterators(const ReadOptions& read_options,
// walks through the non-overlapping files in the level, opening them // walks through the non-overlapping files in the level, opening them
// lazily. // lazily.
for (int level = 1; level < num_levels_; level++) { for (int level = 1; level < num_levels_; level++) {
if (file_levels_[level].num_files != 0) { if (level_files_brief_[level].num_files != 0) {
merge_iter_builder->AddIterator(NewTwoLevelIterator( merge_iter_builder->AddIterator(NewTwoLevelIterator(
new LevelFileIteratorState( new LevelFileIteratorState(
cfd_->table_cache(), read_options, soptions, cfd_->table_cache(), read_options, soptions,
cfd_->internal_comparator(), false /* for_compaction */, cfd_->internal_comparator(), false /* for_compaction */,
cfd_->ioptions()->prefix_extractor != nullptr), cfd_->ioptions()->prefix_extractor != nullptr),
new LevelFileNumIterator(cfd_->internal_comparator(), new LevelFileNumIterator(cfd_->internal_comparator(),
&file_levels_[level]), merge_iter_builder->GetArena())); &level_files_brief_[level]), merge_iter_builder->GetArena()));
} }
} }
} }
@ -706,8 +706,9 @@ void Version::Get(const ReadOptions& read_options,
db_statistics_, status->ok() ? GetContext::kNotFound : GetContext::kMerge, db_statistics_, status->ok() ? GetContext::kNotFound : GetContext::kMerge,
user_key, value, value_found, merge_context); user_key, value, value_found, merge_context);
FilePicker fp(files_, user_key, ikey, &file_levels_, num_non_empty_levels_, FilePicker fp(files_, user_key, ikey, &level_files_brief_,
&file_indexer_, user_comparator_, internal_comparator_); num_non_empty_levels_, &file_indexer_, user_comparator_,
internal_comparator_);
FdWithKeyRange* f = fp.GetNextFile(); FdWithKeyRange* f = fp.GetNextFile();
while (f != nullptr) { while (f != nullptr) {
*status = table_cache_->Get(read_options, *internal_comparator_, f->fd, *status = table_cache_->Get(read_options, *internal_comparator_, f->fd,
@ -758,10 +759,11 @@ void Version::Get(const ReadOptions& read_options,
} }
} }
void Version::GenerateFileLevels() { void Version::GenerateLevelFilesBrief() {
file_levels_.resize(num_non_empty_levels_); level_files_brief_.resize(num_non_empty_levels_);
for (int level = 0; level < num_non_empty_levels_; level++) { for (int level = 0; level < num_non_empty_levels_; level++) {
DoGenerateFileLevel(&file_levels_[level], files_[level], &arena_); DoGenerateLevelFilesBrief(
&level_files_brief_[level], files_[level], &arena_);
} }
} }
@ -772,7 +774,7 @@ void Version::PrepareApply(const MutableCFOptions& mutable_cf_options,
UpdateFilesBySize(); UpdateFilesBySize();
UpdateNumNonEmptyLevels(); UpdateNumNonEmptyLevels();
file_indexer_.UpdateIndex(&arena_, num_non_empty_levels_, files_); file_indexer_.UpdateIndex(&arena_, num_non_empty_levels_, files_);
GenerateFileLevels(); GenerateLevelFilesBrief();
} }
bool Version::MaybeInitializeFileMetaData(FileMetaData* file_meta) { bool Version::MaybeInitializeFileMetaData(FileMetaData* file_meta) {
@ -1046,7 +1048,7 @@ bool Version::OverlapInLevel(int level,
const Slice* smallest_user_key, const Slice* smallest_user_key,
const Slice* largest_user_key) { const Slice* largest_user_key) {
return SomeFileOverlapsRange(cfd_->internal_comparator(), (level > 0), return SomeFileOverlapsRange(cfd_->internal_comparator(), (level > 0),
file_levels_[level], smallest_user_key, level_files_brief_[level], smallest_user_key,
largest_user_key); largest_user_key);
} }
@ -1109,8 +1111,8 @@ void Version::GetOverlappingInputs(int level,
hint_index, file_index); hint_index, file_index);
return; return;
} }
for (size_t i = 0; i < file_levels_[level].num_files; ) { for (size_t i = 0; i < level_files_brief_[level].num_files; ) {
FdWithKeyRange* f = &(file_levels_[level].files[i++]); FdWithKeyRange* f = &(level_files_brief_[level].files[i++]);
const Slice file_start = ExtractUserKey(f->smallest_key); const Slice file_start = ExtractUserKey(f->smallest_key);
const Slice file_limit = ExtractUserKey(f->largest_key); const Slice file_limit = ExtractUserKey(f->largest_key);
if (begin != nullptr && user_cmp->Compare(file_limit, user_begin) < 0) { if (begin != nullptr && user_cmp->Compare(file_limit, user_begin) < 0) {
@ -1166,7 +1168,7 @@ void Version::GetOverlappingInputsBinarySearch(
while (!foundOverlap && min <= max) { while (!foundOverlap && min <= max) {
mid = (min + max)/2; mid = (min + max)/2;
FdWithKeyRange* f = &(file_levels_[level].files[mid]); FdWithKeyRange* f = &(level_files_brief_[level].files[mid]);
const Slice file_start = ExtractUserKey(f->smallest_key); const Slice file_start = ExtractUserKey(f->smallest_key);
const Slice file_limit = ExtractUserKey(f->largest_key); const Slice file_limit = ExtractUserKey(f->largest_key);
if (user_cmp->Compare(file_limit, user_begin) < 0) { if (user_cmp->Compare(file_limit, user_begin) < 0) {
@ -1194,7 +1196,7 @@ void Version::GetOverlappingInputsBinarySearch(
// The midIndex specifies the index of at least one file that // The midIndex specifies the index of at least one file that
// overlaps the specified range. From that file, iterate backward // overlaps the specified range. From that file, iterate backward
// and forward to find all overlapping files. // and forward to find all overlapping files.
// Use FileLevel in searching, make it faster // Use LevelFilesBrief in searching, make it faster
void Version::ExtendOverlappingInputs( void Version::ExtendOverlappingInputs(
int level, int level,
const Slice& user_begin, const Slice& user_begin,
@ -1203,11 +1205,11 @@ void Version::ExtendOverlappingInputs(
unsigned int midIndex) { unsigned int midIndex) {
const Comparator* user_cmp = cfd_->internal_comparator().user_comparator(); const Comparator* user_cmp = cfd_->internal_comparator().user_comparator();
const FdWithKeyRange* files = file_levels_[level].files; const FdWithKeyRange* files = level_files_brief_[level].files;
#ifndef NDEBUG #ifndef NDEBUG
{ {
// assert that the file at midIndex overlaps with the range // assert that the file at midIndex overlaps with the range
assert(midIndex < file_levels_[level].num_files); assert(midIndex < level_files_brief_[level].num_files);
const FdWithKeyRange* f = &files[midIndex]; const FdWithKeyRange* f = &files[midIndex];
const Slice fstart = ExtractUserKey(f->smallest_key); const Slice fstart = ExtractUserKey(f->smallest_key);
const Slice flimit = ExtractUserKey(f->largest_key); const Slice flimit = ExtractUserKey(f->largest_key);
@ -1234,7 +1236,8 @@ void Version::ExtendOverlappingInputs(
} }
} }
// check forward from 'mid+1' to higher indices // check forward from 'mid+1' to higher indices
for (unsigned int i = midIndex+1; i < file_levels_[level].num_files; i++) { for (unsigned int i = midIndex+1;
i < level_files_brief_[level].num_files; i++) {
const FdWithKeyRange* f = &files[i]; const FdWithKeyRange* f = &files[i];
const Slice file_start = ExtractUserKey(f->smallest_key); const Slice file_start = ExtractUserKey(f->smallest_key);
if (user_cmp->Compare(file_start, user_end) <= 0) { if (user_cmp->Compare(file_start, user_end) <= 0) {
@ -1268,8 +1271,8 @@ bool Version::HasOverlappingUserKey(
} }
const Comparator* user_cmp = cfd_->internal_comparator().user_comparator(); const Comparator* user_cmp = cfd_->internal_comparator().user_comparator();
const FileLevel& file_level = file_levels_[level]; const LevelFilesBrief& file_level = level_files_brief_[level];
const FdWithKeyRange* files = file_levels_[level].files; const FdWithKeyRange* files = level_files_brief_[level].files;
const size_t kNumFiles = file_level.num_files; const size_t kNumFiles = file_level.num_files;
// Check the last file in inputs against the file after it // Check the last file in inputs against the file after it
@ -2799,7 +2802,7 @@ Iterator* VersionSet::MakeInputIterator(Compaction* c) {
for (int which = 0; which < c->num_input_levels(); which++) { for (int which = 0; which < c->num_input_levels(); which++) {
if (c->input_levels(which)->num_files != 0) { if (c->input_levels(which)->num_files != 0) {
if (c->level(which) == 0) { if (c->level(which) == 0) {
const FileLevel* flevel = c->input_levels(which); const LevelFilesBrief* flevel = c->input_levels(which);
for (size_t i = 0; i < flevel->num_files; i++) { for (size_t i = 0; i < flevel->num_files; i++) {
list[num++] = cfd->table_cache()->NewIterator( list[num++] = cfd->table_cache()->NewIterator(
read_options, env_options_compactions_, read_options, env_options_compactions_,

@ -58,7 +58,7 @@ class MergeIteratorBuilder;
// REQUIRES: "file_level.files" contains a sorted list of // REQUIRES: "file_level.files" contains a sorted list of
// non-overlapping files. // non-overlapping files.
extern int FindFile(const InternalKeyComparator& icmp, extern int FindFile(const InternalKeyComparator& icmp,
const FileLevel& file_level, const LevelFilesBrief& file_level,
const Slice& key); const Slice& key);
// Returns true iff some file in "files" overlaps the user key range // Returns true iff some file in "files" overlaps the user key range
@ -70,14 +70,14 @@ extern int FindFile(const InternalKeyComparator& icmp,
extern bool SomeFileOverlapsRange( extern bool SomeFileOverlapsRange(
const InternalKeyComparator& icmp, const InternalKeyComparator& icmp,
bool disjoint_sorted_files, bool disjoint_sorted_files,
const FileLevel& file_level, const LevelFilesBrief& file_level,
const Slice* smallest_user_key, const Slice* smallest_user_key,
const Slice* largest_user_key); const Slice* largest_user_key);
// Generate FileLevel from vector<FdWithKeyRange*> // Generate LevelFilesBrief from vector<FdWithKeyRange*>
// Would copy smallest_key and largest_key data to sequential memory // Would copy smallest_key and largest_key data to sequential memory
// arena: Arena used to allocate the memory // arena: Arena used to allocate the memory
extern void DoGenerateFileLevel(FileLevel* file_level, extern void DoGenerateLevelFilesBrief(LevelFilesBrief* file_level,
const std::vector<FileMetaData*>& files, const std::vector<FileMetaData*>& files,
Arena* arena); Arena* arena);
@ -105,8 +105,8 @@ class Version {
const MutableCFOptions& mutable_cf_options, const MutableCFOptions& mutable_cf_options,
std::vector<uint64_t>& size_being_compacted); std::vector<uint64_t>& size_being_compacted);
// Generate file_levels_ from files_ // Generate level_files_brief_ from files_
void GenerateFileLevels(); void GenerateLevelFilesBrief();
// Update scores, pre-calculated variables. It needs to be called before // Update scores, pre-calculated variables. It needs to be called before
// applying the version to the version set. // applying the version to the version set.
@ -183,6 +183,12 @@ class Version {
int NumberLevels() const { return num_levels_; } int NumberLevels() const { return num_levels_; }
// REQUIRES: This version has been saved (see VersionSet::SaveTo)
int NumNonEmptyLevels() const {
assert(finalized_);
return num_non_empty_levels_;
}
// REQUIRES: This version has been saved (see VersionSet::SaveTo) // REQUIRES: This version has been saved (see VersionSet::SaveTo)
int NumLevelFiles(int level) const { int NumLevelFiles(int level) const {
assert(finalized_); assert(finalized_);
@ -263,6 +269,10 @@ class Version {
return files_by_size_[level]; return files_by_size_[level];
} }
const LevelFilesBrief& GetLevelFilesBrief(int level) const {
return level_files_brief_[level];
}
// REQUIRES: lock is held // REQUIRES: lock is held
// Set the index that is used to offset into files_by_size_ to find // Set the index that is used to offset into files_by_size_ to find
// the next compaction candidate file. // the next compaction candidate file.
@ -285,7 +295,6 @@ class Version {
private: private:
friend class VersionSet; friend class VersionSet;
friend class DBImpl; friend class DBImpl;
friend class CompactedDBImpl;
friend class ColumnFamilyData; friend class ColumnFamilyData;
friend class ForwardIterator; friend class ForwardIterator;
friend class InternalStats; friend class InternalStats;
@ -321,7 +330,8 @@ class Version {
TableCache* table_cache_; TableCache* table_cache_;
const MergeOperator* merge_operator_; const MergeOperator* merge_operator_;
autovector<FileLevel> file_levels_; // A copy of list of files per level // A short brief metadata of files per level
autovector<LevelFilesBrief> level_files_brief_;
Logger* info_log_; Logger* info_log_;
Statistics* db_statistics_; Statistics* db_statistics_;
int num_levels_; // Number of levels int num_levels_; // Number of levels
@ -329,7 +339,7 @@ class Version {
// is guaranteed to be empty. // is guaranteed to be empty.
FileIndexer file_indexer_; FileIndexer file_indexer_;
VersionSet* vset_; // VersionSet to which this Version belongs VersionSet* vset_; // VersionSet to which this Version belongs
Arena arena_; // Used to allocate space for file_levels_ Arena arena_; // Used to allocate space for level_files_brief_
Version* next_; // Next version in linked list Version* next_; // Next version in linked list
Version* prev_; // Previous version in linked list Version* prev_; // Previous version in linked list
int refs_; // Number of live refs to this version int refs_; // Number of live refs to this version

@ -14,15 +14,15 @@
namespace rocksdb { namespace rocksdb {
class GenerateFileLevelTest { class GenerateLevelFilesBriefTest {
public: public:
std::vector<FileMetaData*> files_; std::vector<FileMetaData*> files_;
FileLevel file_level_; LevelFilesBrief file_level_;
Arena arena_; Arena arena_;
GenerateFileLevelTest() { } GenerateLevelFilesBriefTest() { }
~GenerateFileLevelTest() { ~GenerateLevelFilesBriefTest() {
for (unsigned int i = 0; i < files_.size(); i++) { for (unsigned int i = 0; i < files_.size(); i++) {
delete files_[i]; delete files_[i];
} }
@ -49,33 +49,33 @@ class GenerateFileLevelTest {
} }
}; };
TEST(GenerateFileLevelTest, Empty) { TEST(GenerateLevelFilesBriefTest, Empty) {
DoGenerateFileLevel(&file_level_, files_, &arena_); DoGenerateLevelFilesBrief(&file_level_, files_, &arena_);
ASSERT_EQ(0u, file_level_.num_files); ASSERT_EQ(0u, file_level_.num_files);
ASSERT_EQ(0, Compare()); ASSERT_EQ(0, Compare());
} }
TEST(GenerateFileLevelTest, Single) { TEST(GenerateLevelFilesBriefTest, Single) {
Add("p", "q"); Add("p", "q");
DoGenerateFileLevel(&file_level_, files_, &arena_); DoGenerateLevelFilesBrief(&file_level_, files_, &arena_);
ASSERT_EQ(1u, file_level_.num_files); ASSERT_EQ(1u, file_level_.num_files);
ASSERT_EQ(0, Compare()); ASSERT_EQ(0, Compare());
} }
TEST(GenerateFileLevelTest, Multiple) { TEST(GenerateLevelFilesBriefTest, Multiple) {
Add("150", "200"); Add("150", "200");
Add("200", "250"); Add("200", "250");
Add("300", "350"); Add("300", "350");
Add("400", "450"); Add("400", "450");
DoGenerateFileLevel(&file_level_, files_, &arena_); DoGenerateLevelFilesBrief(&file_level_, files_, &arena_);
ASSERT_EQ(4u, file_level_.num_files); ASSERT_EQ(4u, file_level_.num_files);
ASSERT_EQ(0, Compare()); ASSERT_EQ(0, Compare());
} }
class FindLevelFileTest { class FindLevelFileTest {
public: public:
FileLevel file_level_; LevelFilesBrief file_level_;
bool disjoint_sorted_files_; bool disjoint_sorted_files_;
Arena arena_; Arena arena_;

@ -104,27 +104,28 @@ Status CompactedDBImpl::Init(const Options& options) {
} }
version_ = cfd_->GetSuperVersion()->current; version_ = cfd_->GetSuperVersion()->current;
user_comparator_ = cfd_->user_comparator(); user_comparator_ = cfd_->user_comparator();
const LevelFilesBrief& l0 = version_->GetLevelFilesBrief(0);
// L0 should not have files // L0 should not have files
if (version_->file_levels_[0].num_files > 1) { if (l0.num_files > 1) {
return Status::NotSupported("L0 contain more than 1 file"); return Status::NotSupported("L0 contain more than 1 file");
} }
if (version_->file_levels_[0].num_files == 1) { if (l0.num_files == 1) {
if (version_->num_non_empty_levels_ > 1) { if (version_->NumNonEmptyLevels() > 1) {
return Status::NotSupported("Both L0 and other level contain files"); return Status::NotSupported("Both L0 and other level contain files");
} }
files_ = version_->file_levels_[0]; files_ = l0;
return Status::OK(); return Status::OK();
} }
for (int i = 1; i < version_->num_non_empty_levels_ - 1; ++i) { for (int i = 1; i < version_->NumNonEmptyLevels() - 1; ++i) {
if (version_->file_levels_[i].num_files > 0) { if (version_->GetLevelFilesBrief(i).num_files > 0) {
return Status::NotSupported("Other levels also contain files"); return Status::NotSupported("Other levels also contain files");
} }
} }
int level = version_->num_non_empty_levels_ - 1; int level = version_->NumNonEmptyLevels() - 1;
if (version_->file_levels_[level].num_files > 0) { if (version_->GetLevelFilesBrief(level).num_files > 0) {
files_ = version_->file_levels_[version_->num_non_empty_levels_ - 1]; files_ = version_->GetLevelFilesBrief(level);
return Status::OK(); return Status::OK();
} }
return Status::NotSupported("no file exists"); return Status::NotSupported("no file exists");

@ -86,7 +86,7 @@ class CompactedDBImpl : public DBImpl {
ColumnFamilyData* cfd_; ColumnFamilyData* cfd_;
Version* version_; Version* version_;
const Comparator* user_comparator_; const Comparator* user_comparator_;
FileLevel files_; LevelFilesBrief files_;
// No copying allowed // No copying allowed
CompactedDBImpl(const CompactedDBImpl&); CompactedDBImpl(const CompactedDBImpl&);

Loading…
Cancel
Save