]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
2 | // This source code is licensed under both the GPLv2 (found in the |
3 | // COPYING file in the root directory) and Apache 2.0 License | |
4 | // (found in the LICENSE.Apache file in the root directory). | |
7c673cae FG |
5 | |
6 | #ifndef ROCKSDB_LITE | |
7 | #include "utilities/table_properties_collectors/compact_on_deletion_collector.h" | |
8 | ||
9 | #include <memory> | |
10 | #include "rocksdb/utilities/table_properties_collectors.h" | |
11 | ||
f67539c2 | 12 | namespace ROCKSDB_NAMESPACE { |
7c673cae FG |
13 | |
14 | CompactOnDeletionCollector::CompactOnDeletionCollector( | |
11fdf7f2 TL |
15 | size_t sliding_window_size, size_t deletion_trigger) |
16 | : bucket_size_((sliding_window_size + kNumBuckets - 1) / kNumBuckets), | |
17 | current_bucket_(0), | |
18 | num_keys_in_current_bucket_(0), | |
19 | num_deletions_in_observation_window_(0), | |
20 | deletion_trigger_(deletion_trigger), | |
21 | need_compaction_(false), | |
22 | finished_(false) { | |
23 | memset(num_deletions_in_buckets_, 0, sizeof(size_t) * kNumBuckets); | |
7c673cae FG |
24 | } |
25 | ||
26 | // AddUserKey() will be called when a new key/value pair is inserted into the | |
27 | // table. | |
28 | // @params key the user key that is inserted into the table. | |
29 | // @params value the value that is inserted into the table. | |
30 | // @params file_size file size up to now | |
11fdf7f2 TL |
31 | Status CompactOnDeletionCollector::AddUserKey(const Slice& /*key*/, |
32 | const Slice& /*value*/, | |
33 | EntryType type, | |
34 | SequenceNumber /*seq*/, | |
35 | uint64_t /*file_size*/) { | |
36 | assert(!finished_); | |
37 | if (bucket_size_ == 0) { | |
38 | // This collector is effectively disabled | |
39 | return Status::OK(); | |
40 | } | |
41 | ||
7c673cae FG |
42 | if (need_compaction_) { |
43 | // If the output file already needs to be compacted, skip the check. | |
44 | return Status::OK(); | |
45 | } | |
46 | ||
47 | if (num_keys_in_current_bucket_ == bucket_size_) { | |
48 | // When the current bucket is full, advance the cursor of the | |
49 | // ring buffer to the next bucket. | |
50 | current_bucket_ = (current_bucket_ + 1) % kNumBuckets; | |
51 | ||
52 | // Update the current count of observed deletion keys by excluding | |
53 | // the number of deletion keys in the oldest bucket in the | |
54 | // observation window. | |
55 | assert(num_deletions_in_observation_window_ >= | |
56 | num_deletions_in_buckets_[current_bucket_]); | |
57 | num_deletions_in_observation_window_ -= | |
58 | num_deletions_in_buckets_[current_bucket_]; | |
59 | num_deletions_in_buckets_[current_bucket_] = 0; | |
60 | num_keys_in_current_bucket_ = 0; | |
61 | } | |
62 | ||
63 | num_keys_in_current_bucket_++; | |
64 | if (type == kEntryDelete) { | |
65 | num_deletions_in_observation_window_++; | |
66 | num_deletions_in_buckets_[current_bucket_]++; | |
67 | if (num_deletions_in_observation_window_ >= deletion_trigger_) { | |
68 | need_compaction_ = true; | |
69 | } | |
70 | } | |
71 | return Status::OK(); | |
72 | } | |
73 | ||
74 | TablePropertiesCollector* | |
75 | CompactOnDeletionCollectorFactory::CreateTablePropertiesCollector( | |
11fdf7f2 | 76 | TablePropertiesCollectorFactory::Context /*context*/) { |
7c673cae | 77 | return new CompactOnDeletionCollector( |
11fdf7f2 | 78 | sliding_window_size_.load(), deletion_trigger_.load()); |
7c673cae FG |
79 | } |
80 | ||
11fdf7f2 | 81 | std::shared_ptr<CompactOnDeletionCollectorFactory> |
7c673cae FG |
82 | NewCompactOnDeletionCollectorFactory( |
83 | size_t sliding_window_size, | |
84 | size_t deletion_trigger) { | |
11fdf7f2 | 85 | return std::shared_ptr<CompactOnDeletionCollectorFactory>( |
7c673cae FG |
86 | new CompactOnDeletionCollectorFactory( |
87 | sliding_window_size, deletion_trigger)); | |
88 | } | |
f67539c2 | 89 | } // namespace ROCKSDB_NAMESPACE |
7c673cae | 90 | #endif // !ROCKSDB_LITE |