13
13
namespace ROCKSDB_NAMESPACE {
14
14
15
15
CompactOnDeletionCollector::CompactOnDeletionCollector (
16
- size_t sliding_window_size, size_t deletion_trigger)
16
+ size_t sliding_window_size, size_t deletion_trigger, double deletion_ratio )
17
17
: bucket_size_((sliding_window_size + kNumBuckets - 1 ) / kNumBuckets ),
18
18
current_bucket_ (0 ),
19
19
num_keys_in_current_bucket_(0 ),
20
20
num_deletions_in_observation_window_(0 ),
21
21
deletion_trigger_(deletion_trigger),
22
+ deletion_ratio_(deletion_ratio),
23
+ deletion_ratio_enabled_(deletion_ratio > 0 && deletion_ratio <= 1 ),
22
24
need_compaction_(false ),
23
25
finished_(false ) {
24
26
memset (num_deletions_in_buckets_, 0 , sizeof (size_t ) * kNumBuckets );
@@ -35,7 +37,7 @@ Status CompactOnDeletionCollector::AddUserKey(const Slice& /*key*/,
35
37
SequenceNumber /* seq*/ ,
36
38
uint64_t /* file_size*/ ) {
37
39
assert (!finished_);
38
- if (bucket_size_ == 0 ) {
40
+ if (! bucket_size_ && !deletion_ratio_enabled_ ) {
39
41
// This collector is effectively disabled
40
42
return Status::OK ();
41
43
}
@@ -45,54 +47,76 @@ Status CompactOnDeletionCollector::AddUserKey(const Slice& /*key*/,
45
47
return Status::OK ();
46
48
}
47
49
48
- if (num_keys_in_current_bucket_ == bucket_size_) {
49
- // When the current bucket is full, advance the cursor of the
50
- // ring buffer to the next bucket.
51
- current_bucket_ = (current_bucket_ + 1 ) % kNumBuckets ;
52
-
53
- // Update the current count of observed deletion keys by excluding
54
- // the number of deletion keys in the oldest bucket in the
55
- // observation window.
56
- assert (num_deletions_in_observation_window_ >=
57
- num_deletions_in_buckets_[current_bucket_]);
58
- num_deletions_in_observation_window_ -=
59
- num_deletions_in_buckets_[current_bucket_];
60
- num_deletions_in_buckets_[current_bucket_] = 0 ;
61
- num_keys_in_current_bucket_ = 0 ;
50
+ if (deletion_ratio_enabled_) {
51
+ total_entries_++;
52
+ if (type == kEntryDelete ) {
53
+ deletion_entries_++;
54
+ }
62
55
}
63
56
64
- num_keys_in_current_bucket_++;
65
- if (type == kEntryDelete ) {
66
- num_deletions_in_observation_window_++;
67
- num_deletions_in_buckets_[current_bucket_]++;
68
- if (num_deletions_in_observation_window_ >= deletion_trigger_) {
69
- need_compaction_ = true ;
57
+ if (bucket_size_) {
58
+ if (num_keys_in_current_bucket_ == bucket_size_) {
59
+ // When the current bucket is full, advance the cursor of the
60
+ // ring buffer to the next bucket.
61
+ current_bucket_ = (current_bucket_ + 1 ) % kNumBuckets ;
62
+
63
+ // Update the current count of observed deletion keys by excluding
64
+ // the number of deletion keys in the oldest bucket in the
65
+ // observation window.
66
+ assert (num_deletions_in_observation_window_ >=
67
+ num_deletions_in_buckets_[current_bucket_]);
68
+ num_deletions_in_observation_window_ -=
69
+ num_deletions_in_buckets_[current_bucket_];
70
+ num_deletions_in_buckets_[current_bucket_] = 0 ;
71
+ num_keys_in_current_bucket_ = 0 ;
72
+ }
73
+
74
+ num_keys_in_current_bucket_++;
75
+ if (type == kEntryDelete ) {
76
+ num_deletions_in_observation_window_++;
77
+ num_deletions_in_buckets_[current_bucket_]++;
78
+ if (num_deletions_in_observation_window_ >= deletion_trigger_) {
79
+ need_compaction_ = true ;
80
+ }
70
81
}
71
82
}
83
+
84
+ return Status::OK ();
85
+ }
86
+
87
+ Status CompactOnDeletionCollector::Finish (
88
+ UserCollectedProperties* /* properties*/ ) {
89
+ if (!need_compaction_ && deletion_ratio_enabled_ && total_entries_ > 0 ) {
90
+ double ratio = static_cast <double >(deletion_entries_) / total_entries_;
91
+ need_compaction_ = ratio >= deletion_ratio_;
92
+ }
93
+ finished_ = true ;
72
94
return Status::OK ();
73
95
}
74
96
75
97
TablePropertiesCollector*
76
98
CompactOnDeletionCollectorFactory::CreateTablePropertiesCollector (
77
99
TablePropertiesCollectorFactory::Context /* context*/ ) {
78
- return new CompactOnDeletionCollector (
79
- sliding_window_size_.load (), deletion_trigger_.load ());
100
+ return new CompactOnDeletionCollector (sliding_window_size_.load (),
101
+ deletion_trigger_.load (),
102
+ deletion_ratio_.load ());
80
103
}
81
104
82
105
std::string CompactOnDeletionCollectorFactory::ToString () const {
83
106
std::ostringstream cfg;
84
107
cfg << Name () << " (Sliding window size = " << sliding_window_size_.load ()
85
- << " Deletion trigger = " << deletion_trigger_.load () << ' )' ;
108
+ << " Deletion trigger = " << deletion_trigger_.load ()
109
+ << " Deletion ratio = " << deletion_ratio_.load () << ' )' ;
86
110
return cfg.str ();
87
111
}
88
112
89
113
std::shared_ptr<CompactOnDeletionCollectorFactory>
90
- NewCompactOnDeletionCollectorFactory (
91
- size_t sliding_window_size ,
92
- size_t deletion_trigger ) {
114
+ NewCompactOnDeletionCollectorFactory (size_t sliding_window_size,
115
+ size_t deletion_trigger ,
116
+ double deletion_ratio ) {
93
117
return std::shared_ptr<CompactOnDeletionCollectorFactory>(
94
- new CompactOnDeletionCollectorFactory (
95
- sliding_window_size, deletion_trigger));
118
+ new CompactOnDeletionCollectorFactory (sliding_window_size,
119
+ deletion_trigger, deletion_ratio ));
96
120
}
97
121
} // namespace ROCKSDB_NAMESPACE
98
122
#endif // !ROCKSDB_LITE
0 commit comments