Fix bug of reading from empty DB.

Summary: I found that db_stress sometimes segfault on my machine. Fix the bug.

Test Plan: make all check. Run db_stress

Reviewers: ljin, yhchiang, rven, igor

Reviewed By: igor

Subscribers: leveldb, dhruba

Differential Revision: https://reviews.facebook.net/D28803
main
sdong 10 years ago
parent 31b02dc21d
commit fa50abb726
  1. 11
      db/version_set.cc
  2. 1
      db/version_set.h

@ -678,6 +678,11 @@ void Version::AddIterators(const ReadOptions& read_options,
MergeIteratorBuilder* merge_iter_builder) { MergeIteratorBuilder* merge_iter_builder) {
assert(storage_info_.finalized_); assert(storage_info_.finalized_);
if (storage_info_.num_non_empty_levels() == 0) {
// No file in the Version.
return;
}
// 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 < storage_info_.LevelFilesBrief(0).num_files; i++) { for (size_t i = 0; i < storage_info_.LevelFilesBrief(0).num_files; i++) {
const auto& file = storage_info_.LevelFilesBrief(0).files[i]; const auto& file = storage_info_.LevelFilesBrief(0).files[i];
@ -689,8 +694,8 @@ void Version::AddIterators(const ReadOptions& read_options,
// For levels > 0, we can use a concatenating iterator that sequentially // For levels > 0, we can use a concatenating iterator that sequentially
// 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 < storage_info_.num_levels(); level++) { for (int level = 1; level < storage_info_.num_non_empty_levels(); level++) {
if (storage_info_.level_files_brief_[level].num_files != 0) { if (storage_info_.LevelFilesBrief(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,
@ -711,7 +716,7 @@ VersionStorageInfo::VersionStorageInfo(
user_comparator_(user_comparator), user_comparator_(user_comparator),
// cfd is nullptr if Version is dummy // cfd is nullptr if Version is dummy
num_levels_(levels), num_levels_(levels),
num_non_empty_levels_(num_levels_), num_non_empty_levels_(0),
file_indexer_(user_comparator), file_indexer_(user_comparator),
compaction_style_(compaction_style), compaction_style_(compaction_style),
files_(new std::vector<FileMetaData*>[num_levels_]), files_(new std::vector<FileMetaData*>[num_levels_]),

@ -206,6 +206,7 @@ class VersionStorageInfo {
} }
const rocksdb::LevelFilesBrief& LevelFilesBrief(int level) const { const rocksdb::LevelFilesBrief& LevelFilesBrief(int level) const {
assert(level < static_cast<int>(level_files_brief_.size()));
return level_files_brief_[level]; return level_files_brief_[level];
} }

Loading…
Cancel
Save