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