From fa50abb72615789647103f3d9220878c2125aaaa Mon Sep 17 00:00:00 2001 From: sdong Date: Wed, 12 Nov 2014 14:19:33 -0800 Subject: [PATCH] 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 --- db/version_set.cc | 11 ++++++++--- db/version_set.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/db/version_set.cc b/db/version_set.cc index a1954bddb..32dc900b3 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -678,6 +678,11 @@ void Version::AddIterators(const ReadOptions& read_options, MergeIteratorBuilder* merge_iter_builder) { 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 for (size_t i = 0; i < storage_info_.LevelFilesBrief(0).num_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 // walks through the non-overlapping files in the level, opening them // lazily. - for (int level = 1; level < storage_info_.num_levels(); level++) { - if (storage_info_.level_files_brief_[level].num_files != 0) { + for (int level = 1; level < storage_info_.num_non_empty_levels(); level++) { + if (storage_info_.LevelFilesBrief(level).num_files != 0) { merge_iter_builder->AddIterator(NewTwoLevelIterator( new LevelFileIteratorState( cfd_->table_cache(), read_options, soptions, @@ -711,7 +716,7 @@ VersionStorageInfo::VersionStorageInfo( user_comparator_(user_comparator), // cfd is nullptr if Version is dummy num_levels_(levels), - num_non_empty_levels_(num_levels_), + num_non_empty_levels_(0), file_indexer_(user_comparator), compaction_style_(compaction_style), files_(new std::vector[num_levels_]), diff --git a/db/version_set.h b/db/version_set.h index f23fcc693..d5a0cb28b 100644 --- a/db/version_set.h +++ b/db/version_set.h @@ -206,6 +206,7 @@ class VersionStorageInfo { } const rocksdb::LevelFilesBrief& LevelFilesBrief(int level) const { + assert(level < static_cast(level_files_brief_.size())); return level_files_brief_[level]; }