From 82e8e9e26bb16d1af07a26741bcf63d8342e4336 Mon Sep 17 00:00:00 2001 From: JiYou Date: Fri, 14 Sep 2018 19:40:37 -0700 Subject: [PATCH] VersionBuilder: optmize SaveTo() to linear time. (#4366) Summary: Because `base_files` and `added_files` both are sorted, using a merge operation to these two sorted arrays is more effective. The complexity is reduced to linear time. - optmize the merge complexity. - move the `NDEBUG` of sorted `added_files` out of merge process. Signed-off-by: JiYou Pull Request resolved: https://github.com/facebook/rocksdb/pull/4366 Differential Revision: D9833592 Pulled By: ajkr fbshipit-source-id: dd32b67ebdca4c20e5e9546ab8082cecefe99fd0 --- db/version_builder.cc | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/db/version_builder.cc b/db/version_builder.cc index b1f558f6f..5d0d6d927 100644 --- a/db/version_builder.cc +++ b/db/version_builder.cc @@ -324,8 +324,6 @@ class VersionBuilder::Rep { // Merge the set of added files with the set of pre-existing files. // Drop any deleted files. Store the result in *v. const auto& base_files = base_vstorage_->LevelFiles(level); - auto base_iter = base_files.begin(); - auto base_end = base_files.end(); const auto& unordered_added_files = levels_[level].added_files; vstorage->Reserve(level, base_files.size() + unordered_added_files.size()); @@ -339,30 +337,27 @@ class VersionBuilder::Rep { std::sort(added_files.begin(), added_files.end(), cmp); #ifndef NDEBUG - FileMetaData* prev_file = nullptr; -#endif - + FileMetaData* prev_added_file = nullptr; for (const auto& added : added_files) { -#ifndef NDEBUG - if (level > 0 && prev_file != nullptr) { + if (level > 0 && prev_added_file != nullptr) { assert(base_vstorage_->InternalComparator()->Compare( - prev_file->smallest, added->smallest) <= 0); + prev_added_file->smallest, added->smallest) <= 0); } - prev_file = added; + prev_added_file = added; + } #endif - // Add all smaller files listed in base_ - for (auto bpos = std::upper_bound(base_iter, base_end, added, cmp); - base_iter != bpos; ++base_iter) { - MaybeAddFile(vstorage, level, *base_iter); + auto base_iter = base_files.begin(); + auto base_end = base_files.end(); + auto added_iter = added_files.begin(); + auto added_end = added_files.end(); + while (added_iter != added_end || base_iter != base_end) { + if (base_iter == base_end || + (added_iter != added_end && cmp(*added_iter, *base_iter))) { + MaybeAddFile(vstorage, level, *added_iter++); + } else { + MaybeAddFile(vstorage, level, *base_iter++); } - - MaybeAddFile(vstorage, level, added); - } - - // Add remaining base files - for (; base_iter != base_end; ++base_iter) { - MaybeAddFile(vstorage, level, *base_iter); } }