diff --git a/db/range_del_aggregator.cc b/db/range_del_aggregator.cc index fdd847a7a..2e22dd861 100644 --- a/db/range_del_aggregator.cc +++ b/db/range_del_aggregator.cc @@ -536,4 +536,11 @@ bool RangeDelAggregator::IsEmpty() { return true; } +bool RangeDelAggregator::AddFile(uint64_t file_number) { + if (rep_ == nullptr) { + return true; + } + return rep_->added_files_.emplace(file_number).second; +} + } // namespace rocksdb diff --git a/db/range_del_aggregator.h b/db/range_del_aggregator.h index f050e8917..99ac62f65 100644 --- a/db/range_del_aggregator.h +++ b/db/range_del_aggregator.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include #include @@ -140,6 +141,7 @@ class RangeDelAggregator { CompactionIterationStats* range_del_out_stats = nullptr, bool bottommost_level = false); bool IsEmpty(); + bool AddFile(uint64_t file_number); private: // Maps tombstone user start key -> tombstone object @@ -166,6 +168,7 @@ class RangeDelAggregator { struct Rep { StripeMap stripe_map_; PinnedIteratorsManager pinned_iters_mgr_; + std::set added_files_; }; // Initializes rep_ lazily. This aggregator object is constructed for every // read, so expensive members should only be created when necessary, i.e., diff --git a/db/table_cache.cc b/db/table_cache.cc index 18246f4f8..852d048a3 100644 --- a/db/table_cache.cc +++ b/db/table_cache.cc @@ -247,13 +247,15 @@ InternalIterator* TableCache::NewIterator( } } if (s.ok() && range_del_agg != nullptr && !options.ignore_range_deletions) { - std::unique_ptr range_del_iter( - table_reader->NewRangeTombstoneIterator(options)); - if (range_del_iter != nullptr) { - s = range_del_iter->status(); - } - if (s.ok()) { - s = range_del_agg->AddTombstones(std::move(range_del_iter)); + if (range_del_agg->AddFile(fd.GetNumber())) { + std::unique_ptr range_del_iter( + table_reader->NewRangeTombstoneIterator(options)); + if (range_del_iter != nullptr) { + s = range_del_iter->status(); + } + if (s.ok()) { + s = range_del_agg->AddTombstones(std::move(range_del_iter)); + } } }