diff --git a/db/db_impl/db_impl_open.cc b/db/db_impl/db_impl_open.cc index 202ae777b..2397d8ca7 100644 --- a/db/db_impl/db_impl_open.cc +++ b/db/db_impl/db_impl_open.cc @@ -1553,6 +1553,27 @@ Status DBImpl::Open(const DBOptions& db_options, const std::string& dbname, if (s.ok() && sfm) { // Notify SstFileManager about all sst files that already exist in // db_paths[0] and cf_paths[0] when the DB is opened. + + // SstFileManagerImpl needs to know sizes of the files. For files whose size + // we already know (sst files that appear in manifest - typically that's the + // vast majority of all files), we'll pass the size to SstFileManager. + // For all other files SstFileManager will query the size from filesystem. + + std::vector metadata; + + impl->mutex_.Lock(); + impl->versions_->GetLiveFilesMetaData(&metadata); + impl->mutex_.Unlock(); + + std::unordered_map known_file_sizes; + for (const auto& md : metadata) { + std::string name = md.name; + if (!name.empty() && name[0] == '/') { + name = name.substr(1); + } + known_file_sizes[name] = md.size; + } + std::vector paths; paths.emplace_back(impl->immutable_db_options_.db_paths[0].path); for (auto& cf : column_families) { @@ -1572,7 +1593,14 @@ Status DBImpl::Open(const DBOptions& db_options, const std::string& dbname, std::string file_path = path + "/" + file_name; if (ParseFileName(file_name, &file_number, &file_type) && file_type == kTableFile) { - sfm->OnAddFile(file_path); + if (known_file_sizes.count(file_name)) { + // We're assuming that each sst file name exists in at most one of + // the paths. + sfm->OnAddFile(file_path, known_file_sizes.at(file_name), + /* compaction */ false); + } else { + sfm->OnAddFile(file_path); + } } } } diff --git a/file/sst_file_manager_impl.cc b/file/sst_file_manager_impl.cc index 959070041..c2d3d0e74 100644 --- a/file/sst_file_manager_impl.cc +++ b/file/sst_file_manager_impl.cc @@ -71,6 +71,14 @@ Status SstFileManagerImpl::OnAddFile(const std::string& file_path, return s; } +Status SstFileManagerImpl::OnAddFile(const std::string& file_path, + uint64_t file_size, bool compaction) { + MutexLock l(&mu_); + OnAddFileImpl(file_path, file_size, compaction); + TEST_SYNC_POINT("SstFileManagerImpl::OnAddFile"); + return Status::OK(); +} + Status SstFileManagerImpl::OnDeleteFile(const std::string& file_path) { { MutexLock l(&mu_); diff --git a/file/sst_file_manager_impl.h b/file/sst_file_manager_impl.h index 396dfb862..2a773f088 100644 --- a/file/sst_file_manager_impl.h +++ b/file/sst_file_manager_impl.h @@ -38,6 +38,11 @@ class SstFileManagerImpl : public SstFileManager { // DB will call OnAddFile whenever a new sst file is added. Status OnAddFile(const std::string& file_path, bool compaction = false); + // Overload where size of the file is provided by the caller rather than + // queried from the filesystem. This is an optimization. + Status OnAddFile(const std::string& file_path, uint64_t file_size, + bool compaction); + // DB will call OnDeleteFile whenever an sst file is deleted. Status OnDeleteFile(const std::string& file_path);