]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rocksdb/utilities/table_properties_collectors/compact_on_deletion_collector.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / rocksdb / utilities / table_properties_collectors / compact_on_deletion_collector.cc
index 89d666d4d6a817ecee6c876a9b4572923a758838..8e97118dfc2464c6634235fa7dcf8a32175f7586 100644 (file)
@@ -7,17 +7,20 @@
 #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);
@@ -34,7 +37,7 @@ Status CompactOnDeletionCollector::AddUserKey(const Slice& /*key*/,
                                               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();
   }
@@ -44,47 +47,76 @@ Status CompactOnDeletionCollector::AddUserKey(const Slice& /*key*/,
     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