/src/rocksdb/db/compaction/subcompaction_state.cc
Line | Count | Source |
1 | | // Copyright (c) Meta Platforms, Inc. and affiliates. |
2 | | // |
3 | | // This source code is licensed under both the GPLv2 (found in the |
4 | | // COPYING file in the root directory) and Apache 2.0 License |
5 | | // (found in the LICENSE.Apache file in the root directory). |
6 | | // |
7 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
8 | | // Use of this source code is governed by a BSD-style license that can be |
9 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
10 | | |
11 | | #include "db/compaction/subcompaction_state.h" |
12 | | |
13 | | #include "rocksdb/sst_partitioner.h" |
14 | | |
15 | | namespace ROCKSDB_NAMESPACE { |
16 | | void SubcompactionState::AggregateCompactionOutputStats( |
17 | 3.42k | InternalStats::CompactionStatsFull& internal_stats) const { |
18 | | // Outputs should be closed. By extension, any files created just for |
19 | | // range deletes have already been written also. |
20 | 3.42k | assert(compaction_outputs_.HasBuilder() == false); |
21 | 3.42k | assert(proximal_level_outputs_.HasBuilder() == false); |
22 | | |
23 | | // FIXME: These stats currently include abandonned output files |
24 | | // assert(compaction_outputs_.stats_.num_output_files == |
25 | | // compaction_outputs_.outputs_.size()); |
26 | | // assert(proximal_level_outputs_.stats_.num_output_files == |
27 | | // proximal_level_outputs_.outputs_.size()); |
28 | | |
29 | 3.42k | internal_stats.output_level_stats.Add(compaction_outputs_.stats_); |
30 | 3.42k | if (proximal_level_outputs_.HasOutput()) { |
31 | 0 | internal_stats.has_proximal_level_output = true; |
32 | 0 | internal_stats.proximal_level_stats.Add(proximal_level_outputs_.stats_); |
33 | 0 | } |
34 | 3.42k | } |
35 | | |
36 | 7.63k | OutputIterator SubcompactionState::GetOutputs() const { |
37 | 7.63k | return OutputIterator(proximal_level_outputs_.outputs_, |
38 | 7.63k | compaction_outputs_.outputs_); |
39 | 7.63k | } |
40 | | |
41 | 3.42k | void SubcompactionState::Cleanup(Cache* cache, const Status& overall_status) { |
42 | 3.42k | proximal_level_outputs_.Cleanup(); |
43 | 3.42k | compaction_outputs_.Cleanup(); |
44 | | |
45 | 3.42k | if (!status.ok() || !overall_status.ok()) { |
46 | 1.32k | for (const auto& out : GetOutputs()) { |
47 | | // If this file was inserted into the table cache then remove it here |
48 | | // because this compaction was not committed. This is not strictly |
49 | | // required because of a backstop TableCache::Evict() in |
50 | | // PurgeObsoleteFiles() but is our opportunity to apply |
51 | | // uncache_aggressiveness. TODO: instead, put these files into the |
52 | | // VersionSet::obsolete_files_ pipeline so that they don't have to |
53 | | // be picked up by scanning the DB directory. |
54 | 0 | TableCache::ReleaseObsolete( |
55 | 0 | cache, out.meta.fd.GetNumber(), nullptr /*handle*/, |
56 | 0 | compaction->mutable_cf_options().uncache_aggressiveness); |
57 | 0 | } |
58 | 1.32k | } |
59 | | // TODO: sub_compact.io_status is not checked like status. Not sure if thats |
60 | | // intentional. So ignoring the io_status as of now. |
61 | 3.42k | io_status.PermitUncheckedError(); |
62 | 3.42k | } |
63 | | |
64 | 1.27k | Slice SubcompactionState::SmallestUserKey() const { |
65 | 1.27k | if (proximal_level_outputs_.HasOutput()) { |
66 | 0 | Slice a = compaction_outputs_.SmallestUserKey(); |
67 | 0 | Slice b = proximal_level_outputs_.SmallestUserKey(); |
68 | 0 | if (a.empty()) { |
69 | 0 | return b; |
70 | 0 | } |
71 | 0 | if (b.empty()) { |
72 | 0 | return a; |
73 | 0 | } |
74 | 0 | const Comparator* user_cmp = |
75 | 0 | compaction->column_family_data()->user_comparator(); |
76 | 0 | if (user_cmp->Compare(a, b) > 0) { |
77 | 0 | return b; |
78 | 0 | } else { |
79 | 0 | return a; |
80 | 0 | } |
81 | 1.27k | } else { |
82 | 1.27k | return compaction_outputs_.SmallestUserKey(); |
83 | 1.27k | } |
84 | 1.27k | } |
85 | | |
86 | 1.27k | Slice SubcompactionState::LargestUserKey() const { |
87 | 1.27k | if (proximal_level_outputs_.HasOutput()) { |
88 | 0 | Slice a = compaction_outputs_.LargestUserKey(); |
89 | 0 | Slice b = proximal_level_outputs_.LargestUserKey(); |
90 | 0 | if (a.empty()) { |
91 | 0 | return b; |
92 | 0 | } |
93 | 0 | if (b.empty()) { |
94 | 0 | return a; |
95 | 0 | } |
96 | 0 | const Comparator* user_cmp = |
97 | 0 | compaction->column_family_data()->user_comparator(); |
98 | 0 | if (user_cmp->Compare(a, b) < 0) { |
99 | 0 | return b; |
100 | 0 | } else { |
101 | 0 | return a; |
102 | 0 | } |
103 | 1.27k | } else { |
104 | 1.27k | return compaction_outputs_.LargestUserKey(); |
105 | 1.27k | } |
106 | 1.27k | } |
107 | | |
108 | | Status SubcompactionState::AddToOutput( |
109 | | const CompactionIterator& iter, bool use_proximal_output, |
110 | | const CompactionFileOpenFunc& open_file_func, |
111 | | const CompactionFileCloseFunc& close_file_func, |
112 | 2.17k | const ParsedInternalKey& prev_iter_output_internal_key) { |
113 | | // update target output |
114 | 2.17k | current_outputs_ = |
115 | 2.17k | use_proximal_output ? &proximal_level_outputs_ : &compaction_outputs_; |
116 | 2.17k | return current_outputs_->AddToOutput(iter, open_file_func, close_file_func, |
117 | 2.17k | prev_iter_output_internal_key); |
118 | 2.17k | } |
119 | | |
120 | | } // namespace ROCKSDB_NAMESPACE |