]>
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 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | |
7 | // Use of this source code is governed by a BSD-style license that can be | |
8 | // found in the LICENSE file. See the AUTHORS file for names of contributors. | |
9 | ||
10 | #pragma once | |
11 | ||
12 | #include <string> | |
13 | #include <vector> | |
14 | ||
11fdf7f2 | 15 | #include "db/column_family.h" |
1e59de90 TL |
16 | #include "db/log_writer.h" |
17 | #include "db/version_set.h" | |
7c673cae | 18 | |
f67539c2 | 19 | namespace ROCKSDB_NAMESPACE { |
7c673cae FG |
20 | |
21 | class MemTable; | |
11fdf7f2 TL |
22 | struct SuperVersion; |
23 | ||
24 | struct SuperVersionContext { | |
25 | struct WriteStallNotification { | |
26 | WriteStallInfo write_stall_info; | |
1e59de90 | 27 | const ImmutableOptions* immutable_options; |
11fdf7f2 TL |
28 | }; |
29 | ||
30 | autovector<SuperVersion*> superversions_to_free; | |
31 | #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION | |
32 | autovector<WriteStallNotification> write_stall_notifications; | |
33 | #endif | |
494da23a TL |
34 | std::unique_ptr<SuperVersion> |
35 | new_superversion; // if nullptr no new superversion | |
11fdf7f2 TL |
36 | |
37 | explicit SuperVersionContext(bool create_superversion = false) | |
1e59de90 | 38 | : new_superversion(create_superversion ? new SuperVersion() : nullptr) {} |
11fdf7f2 | 39 | |
1e59de90 | 40 | explicit SuperVersionContext(SuperVersionContext&& other) noexcept |
11fdf7f2 TL |
41 | : superversions_to_free(std::move(other.superversions_to_free)), |
42 | #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION | |
43 | write_stall_notifications(std::move(other.write_stall_notifications)), | |
44 | #endif | |
45 | new_superversion(std::move(other.new_superversion)) { | |
46 | } | |
1e59de90 TL |
47 | // No copies |
48 | SuperVersionContext(const SuperVersionContext& other) = delete; | |
49 | void operator=(const SuperVersionContext& other) = delete; | |
11fdf7f2 TL |
50 | |
51 | void NewSuperVersion() { | |
494da23a | 52 | new_superversion = std::unique_ptr<SuperVersion>(new SuperVersion()); |
11fdf7f2 TL |
53 | } |
54 | ||
55 | inline bool HaveSomethingToDelete() const { | |
56 | #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION | |
1e59de90 | 57 | return !superversions_to_free.empty() || !write_stall_notifications.empty(); |
11fdf7f2 TL |
58 | #else |
59 | return !superversions_to_free.empty(); | |
60 | #endif | |
61 | } | |
62 | ||
1e59de90 TL |
63 | void PushWriteStallNotification(WriteStallCondition old_cond, |
64 | WriteStallCondition new_cond, | |
65 | const std::string& name, | |
66 | const ImmutableOptions* ioptions) { | |
11fdf7f2 TL |
67 | #if !defined(ROCKSDB_LITE) && !defined(ROCKSDB_DISABLE_STALL_NOTIFICATION) |
68 | WriteStallNotification notif; | |
69 | notif.write_stall_info.cf_name = name; | |
70 | notif.write_stall_info.condition.prev = old_cond; | |
71 | notif.write_stall_info.condition.cur = new_cond; | |
1e59de90 | 72 | notif.immutable_options = ioptions; |
11fdf7f2 TL |
73 | write_stall_notifications.push_back(notif); |
74 | #else | |
75 | (void)old_cond; | |
76 | (void)new_cond; | |
77 | (void)name; | |
78 | (void)ioptions; | |
1e59de90 TL |
79 | #endif // !defined(ROCKSDB_LITE) && |
80 | // !defined(ROCKSDB_DISABLE_STALL_NOTIFICATION) | |
11fdf7f2 TL |
81 | } |
82 | ||
83 | void Clean() { | |
84 | #if !defined(ROCKSDB_LITE) && !defined(ROCKSDB_DISABLE_STALL_NOTIFICATION) | |
85 | // notify listeners on changed write stall conditions | |
86 | for (auto& notif : write_stall_notifications) { | |
1e59de90 | 87 | for (auto& listener : notif.immutable_options->listeners) { |
11fdf7f2 TL |
88 | listener->OnStallConditionsChanged(notif.write_stall_info); |
89 | } | |
90 | } | |
91 | write_stall_notifications.clear(); | |
92 | #endif // !ROCKSDB_LITE | |
93 | // free superversions | |
94 | for (auto s : superversions_to_free) { | |
95 | delete s; | |
96 | } | |
97 | superversions_to_free.clear(); | |
98 | } | |
99 | ||
100 | ~SuperVersionContext() { | |
101 | #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION | |
102 | assert(write_stall_notifications.empty()); | |
103 | #endif | |
104 | assert(superversions_to_free.empty()); | |
105 | } | |
106 | }; | |
7c673cae FG |
107 | |
108 | struct JobContext { | |
109 | inline bool HaveSomethingToDelete() const { | |
20effc67 TL |
110 | return !(full_scan_candidate_files.empty() && sst_delete_files.empty() && |
111 | blob_delete_files.empty() && log_delete_files.empty() && | |
112 | manifest_delete_files.empty()); | |
11fdf7f2 TL |
113 | } |
114 | ||
115 | inline bool HaveSomethingToClean() const { | |
116 | bool sv_have_sth = false; | |
117 | for (const auto& sv_ctx : superversion_contexts) { | |
118 | if (sv_ctx.HaveSomethingToDelete()) { | |
119 | sv_have_sth = true; | |
120 | break; | |
121 | } | |
122 | } | |
123 | return memtables_to_free.size() > 0 || logs_to_free.size() > 0 || | |
1e59de90 TL |
124 | job_snapshot != nullptr || sv_have_sth; |
125 | } | |
126 | ||
127 | SequenceNumber GetJobSnapshotSequence() const { | |
128 | if (job_snapshot) { | |
129 | assert(job_snapshot->snapshot()); | |
130 | return job_snapshot->snapshot()->GetSequenceNumber(); | |
131 | } | |
132 | return kMaxSequenceNumber; | |
7c673cae FG |
133 | } |
134 | ||
135 | // Structure to store information for candidate files to delete. | |
136 | struct CandidateFileInfo { | |
137 | std::string file_name; | |
11fdf7f2 TL |
138 | std::string file_path; |
139 | CandidateFileInfo(std::string name, std::string path) | |
140 | : file_name(std::move(name)), file_path(std::move(path)) {} | |
7c673cae | 141 | bool operator==(const CandidateFileInfo& other) const { |
1e59de90 | 142 | return file_name == other.file_name && file_path == other.file_path; |
7c673cae FG |
143 | } |
144 | }; | |
145 | ||
146 | // Unique job id | |
147 | int job_id; | |
148 | ||
149 | // a list of all files that we'll consider deleting | |
150 | // (every once in a while this is filled up with all files | |
151 | // in the DB directory) | |
152 | // (filled only if we're doing full scan) | |
153 | std::vector<CandidateFileInfo> full_scan_candidate_files; | |
154 | ||
155 | // the list of all live sst files that cannot be deleted | |
20effc67 | 156 | std::vector<uint64_t> sst_live; |
7c673cae | 157 | |
20effc67 | 158 | // the list of sst files that we need to delete |
11fdf7f2 | 159 | std::vector<ObsoleteFileInfo> sst_delete_files; |
7c673cae | 160 | |
20effc67 TL |
161 | // the list of all live blob files that cannot be deleted |
162 | std::vector<uint64_t> blob_live; | |
163 | ||
164 | // the list of blob files that we need to delete | |
165 | std::vector<ObsoleteBlobFileInfo> blob_delete_files; | |
166 | ||
7c673cae FG |
167 | // a list of log files that we need to delete |
168 | std::vector<uint64_t> log_delete_files; | |
169 | ||
170 | // a list of log files that we need to preserve during full purge since they | |
171 | // will be reused later | |
172 | std::vector<uint64_t> log_recycle_files; | |
173 | ||
174 | // a list of manifest files that we need to delete | |
175 | std::vector<std::string> manifest_delete_files; | |
176 | ||
177 | // a list of memtables to be free | |
178 | autovector<MemTable*> memtables_to_free; | |
179 | ||
11fdf7f2 TL |
180 | // contexts for installing superversions for multiple column families |
181 | std::vector<SuperVersionContext> superversion_contexts; | |
7c673cae FG |
182 | |
183 | autovector<log::Writer*> logs_to_free; | |
184 | ||
7c673cae FG |
185 | // the current manifest_file_number, log_number and prev_log_number |
186 | // that corresponds to the set of files in 'live'. | |
187 | uint64_t manifest_file_number; | |
188 | uint64_t pending_manifest_file_number; | |
189 | uint64_t log_number; | |
190 | uint64_t prev_log_number; | |
191 | ||
192 | uint64_t min_pending_output = 0; | |
193 | uint64_t prev_total_log_size = 0; | |
194 | size_t num_alive_log_files = 0; | |
195 | uint64_t size_log_to_delete = 0; | |
196 | ||
494da23a TL |
197 | // Snapshot taken before flush/compaction job. |
198 | std::unique_ptr<ManagedSnapshot> job_snapshot; | |
199 | ||
7c673cae FG |
200 | explicit JobContext(int _job_id, bool create_superversion = false) { |
201 | job_id = _job_id; | |
202 | manifest_file_number = 0; | |
203 | pending_manifest_file_number = 0; | |
204 | log_number = 0; | |
205 | prev_log_number = 0; | |
11fdf7f2 TL |
206 | superversion_contexts.emplace_back( |
207 | SuperVersionContext(create_superversion)); | |
7c673cae FG |
208 | } |
209 | ||
210 | // For non-empty JobContext Clean() has to be called at least once before | |
211 | // before destruction (see asserts in ~JobContext()). Should be called with | |
212 | // unlocked DB mutex. Destructor doesn't call Clean() to avoid accidentally | |
213 | // doing potentially slow Clean() with locked DB mutex. | |
214 | void Clean() { | |
11fdf7f2 TL |
215 | // free superversions |
216 | for (auto& sv_context : superversion_contexts) { | |
217 | sv_context.Clean(); | |
218 | } | |
7c673cae FG |
219 | // free pending memtables |
220 | for (auto m : memtables_to_free) { | |
221 | delete m; | |
222 | } | |
7c673cae FG |
223 | for (auto l : logs_to_free) { |
224 | delete l; | |
225 | } | |
7c673cae FG |
226 | |
227 | memtables_to_free.clear(); | |
7c673cae | 228 | logs_to_free.clear(); |
494da23a | 229 | job_snapshot.reset(); |
7c673cae FG |
230 | } |
231 | ||
232 | ~JobContext() { | |
233 | assert(memtables_to_free.size() == 0); | |
7c673cae FG |
234 | assert(logs_to_free.size() == 0); |
235 | } | |
236 | }; | |
237 | ||
f67539c2 | 238 | } // namespace ROCKSDB_NAMESPACE |