#include "utilities/table_properties_collectors/compact_on_deletion_collector.h"
#include <memory>
+#include <sstream>
#include "rocksdb/utilities/table_properties_collectors.h"
namespace ROCKSDB_NAMESPACE {
CompactOnDeletionCollector::CompactOnDeletionCollector(
- size_t sliding_window_size, size_t deletion_trigger)
+ size_t sliding_window_size, size_t deletion_trigger, double deletion_ratio)
: bucket_size_((sliding_window_size + kNumBuckets - 1) / kNumBuckets),
current_bucket_(0),
num_keys_in_current_bucket_(0),
num_deletions_in_observation_window_(0),
deletion_trigger_(deletion_trigger),
+ deletion_ratio_(deletion_ratio),
+ deletion_ratio_enabled_(deletion_ratio > 0 && deletion_ratio <= 1),
need_compaction_(false),
finished_(false) {
memset(num_deletions_in_buckets_, 0, sizeof(size_t) * kNumBuckets);
SequenceNumber /*seq*/,
uint64_t /*file_size*/) {
assert(!finished_);
- if (bucket_size_ == 0) {
+ if (!bucket_size_ && !deletion_ratio_enabled_) {
// This collector is effectively disabled
return Status::OK();
}
return Status::OK();
}
- if (num_keys_in_current_bucket_ == bucket_size_) {
- // When the current bucket is full, advance the cursor of the
- // ring buffer to the next bucket.
- current_bucket_ = (current_bucket_ + 1) % kNumBuckets;
-
- // Update the current count of observed deletion keys by excluding
- // the number of deletion keys in the oldest bucket in the
- // observation window.
- assert(num_deletions_in_observation_window_ >=
- num_deletions_in_buckets_[current_bucket_]);
- num_deletions_in_observation_window_ -=
- num_deletions_in_buckets_[current_bucket_];
- num_deletions_in_buckets_[current_bucket_] = 0;
- num_keys_in_current_bucket_ = 0;
+ if (deletion_ratio_enabled_) {
+ total_entries_++;
+ if (type == kEntryDelete) {
+ deletion_entries_++;
+ }
}
- num_keys_in_current_bucket_++;
- if (type == kEntryDelete) {
- num_deletions_in_observation_window_++;
- num_deletions_in_buckets_[current_bucket_]++;
- if (num_deletions_in_observation_window_ >= deletion_trigger_) {
- need_compaction_ = true;
+ if (bucket_size_) {
+ if (num_keys_in_current_bucket_ == bucket_size_) {
+ // When the current bucket is full, advance the cursor of the
+ // ring buffer to the next bucket.
+ current_bucket_ = (current_bucket_ + 1) % kNumBuckets;
+
+ // Update the current count of observed deletion keys by excluding
+ // the number of deletion keys in the oldest bucket in the
+ // observation window.
+ assert(num_deletions_in_observation_window_ >=
+ num_deletions_in_buckets_[current_bucket_]);
+ num_deletions_in_observation_window_ -=
+ num_deletions_in_buckets_[current_bucket_];
+ num_deletions_in_buckets_[current_bucket_] = 0;
+ num_keys_in_current_bucket_ = 0;
}
+
+ num_keys_in_current_bucket_++;
+ if (type == kEntryDelete) {
+ num_deletions_in_observation_window_++;
+ num_deletions_in_buckets_[current_bucket_]++;
+ if (num_deletions_in_observation_window_ >= deletion_trigger_) {
+ need_compaction_ = true;
+ }
+ }
+ }
+
+ return Status::OK();
+}
+
+Status CompactOnDeletionCollector::Finish(
+ UserCollectedProperties* /*properties*/) {
+ if (!need_compaction_ && deletion_ratio_enabled_ && total_entries_ > 0) {
+ double ratio = static_cast<double>(deletion_entries_) / total_entries_;
+ need_compaction_ = ratio >= deletion_ratio_;
}
+ finished_ = true;
return Status::OK();
}
TablePropertiesCollector*
CompactOnDeletionCollectorFactory::CreateTablePropertiesCollector(
TablePropertiesCollectorFactory::Context /*context*/) {
- return new CompactOnDeletionCollector(
- sliding_window_size_.load(), deletion_trigger_.load());
+ return new CompactOnDeletionCollector(sliding_window_size_.load(),
+ deletion_trigger_.load(),
+ deletion_ratio_.load());
+}
+
+std::string CompactOnDeletionCollectorFactory::ToString() const {
+ std::ostringstream cfg;
+ cfg << Name() << " (Sliding window size = " << sliding_window_size_.load()
+ << " Deletion trigger = " << deletion_trigger_.load()
+ << " Deletion ratio = " << deletion_ratio_.load() << ')';
+ return cfg.str();
}
std::shared_ptr<CompactOnDeletionCollectorFactory>
- NewCompactOnDeletionCollectorFactory(
- size_t sliding_window_size,
- size_t deletion_trigger) {
+NewCompactOnDeletionCollectorFactory(size_t sliding_window_size,
+ size_t deletion_trigger,
+ double deletion_ratio) {
return std::shared_ptr<CompactOnDeletionCollectorFactory>(
- new CompactOnDeletionCollectorFactory(
- sliding_window_size, deletion_trigger));
+ new CompactOnDeletionCollectorFactory(sliding_window_size,
+ deletion_trigger, deletion_ratio));
}
} // namespace ROCKSDB_NAMESPACE
#endif // !ROCKSDB_LITE