]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/env/env.cc
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / env / env.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
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).
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 #include "rocksdb/env.h"
11
12 #include <thread>
13 #include "options/db_options.h"
14 #include "port/port.h"
15 #include "port/sys_time.h"
16 #include "rocksdb/options.h"
17 #include "util/arena.h"
18 #include "util/autovector.h"
19
20 namespace rocksdb {
21
22 Env::~Env() {
23 }
24
25 std::string Env::PriorityToString(Env::Priority priority) {
26 switch (priority) {
27 case Env::Priority::BOTTOM:
28 return "Bottom";
29 case Env::Priority::LOW:
30 return "Low";
31 case Env::Priority::HIGH:
32 return "High";
33 case Env::Priority::USER:
34 return "User";
35 case Env::Priority::TOTAL:
36 assert(false);
37 }
38 return "Invalid";
39 }
40
41 uint64_t Env::GetThreadID() const {
42 std::hash<std::thread::id> hasher;
43 return hasher(std::this_thread::get_id());
44 }
45
46 Status Env::ReuseWritableFile(const std::string& fname,
47 const std::string& old_fname,
48 std::unique_ptr<WritableFile>* result,
49 const EnvOptions& options) {
50 Status s = RenameFile(old_fname, fname);
51 if (!s.ok()) {
52 return s;
53 }
54 return NewWritableFile(fname, result, options);
55 }
56
57 Status Env::GetChildrenFileAttributes(const std::string& dir,
58 std::vector<FileAttributes>* result) {
59 assert(result != nullptr);
60 std::vector<std::string> child_fnames;
61 Status s = GetChildren(dir, &child_fnames);
62 if (!s.ok()) {
63 return s;
64 }
65 result->resize(child_fnames.size());
66 size_t result_size = 0;
67 for (size_t i = 0; i < child_fnames.size(); ++i) {
68 const std::string path = dir + "/" + child_fnames[i];
69 if (!(s = GetFileSize(path, &(*result)[result_size].size_bytes)).ok()) {
70 if (FileExists(path).IsNotFound()) {
71 // The file may have been deleted since we listed the directory
72 continue;
73 }
74 return s;
75 }
76 (*result)[result_size].name = std::move(child_fnames[i]);
77 result_size++;
78 }
79 result->resize(result_size);
80 return Status::OK();
81 }
82
83 SequentialFile::~SequentialFile() {
84 }
85
86 RandomAccessFile::~RandomAccessFile() {
87 }
88
89 WritableFile::~WritableFile() {
90 }
91
92 MemoryMappedFileBuffer::~MemoryMappedFileBuffer() {}
93
94 Logger::~Logger() {}
95
96 Status Logger::Close() {
97 if (!closed_) {
98 closed_ = true;
99 return CloseImpl();
100 } else {
101 return Status::OK();
102 }
103 }
104
105 Status Logger::CloseImpl() { return Status::NotSupported(); }
106
107 FileLock::~FileLock() {
108 }
109
110 void LogFlush(Logger *info_log) {
111 if (info_log) {
112 info_log->Flush();
113 }
114 }
115
116 static void Logv(Logger *info_log, const char* format, va_list ap) {
117 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
118 info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
119 }
120 }
121
122 void Log(Logger* info_log, const char* format, ...) {
123 va_list ap;
124 va_start(ap, format);
125 Logv(info_log, format, ap);
126 va_end(ap);
127 }
128
129 void Logger::Logv(const InfoLogLevel log_level, const char* format, va_list ap) {
130 static const char* kInfoLogLevelNames[5] = { "DEBUG", "INFO", "WARN",
131 "ERROR", "FATAL" };
132 if (log_level < log_level_) {
133 return;
134 }
135
136 if (log_level == InfoLogLevel::INFO_LEVEL) {
137 // Doesn't print log level if it is INFO level.
138 // This is to avoid unexpected performance regression after we add
139 // the feature of log level. All the logs before we add the feature
140 // are INFO level. We don't want to add extra costs to those existing
141 // logging.
142 Logv(format, ap);
143 } else if (log_level == InfoLogLevel::HEADER_LEVEL) {
144 LogHeader(format, ap);
145 } else {
146 char new_format[500];
147 snprintf(new_format, sizeof(new_format) - 1, "[%s] %s",
148 kInfoLogLevelNames[log_level], format);
149 Logv(new_format, ap);
150 }
151 }
152
153 static void Logv(const InfoLogLevel log_level, Logger *info_log, const char *format, va_list ap) {
154 if (info_log && info_log->GetInfoLogLevel() <= log_level) {
155 if (log_level == InfoLogLevel::HEADER_LEVEL) {
156 info_log->LogHeader(format, ap);
157 } else {
158 info_log->Logv(log_level, format, ap);
159 }
160 }
161 }
162
163 void Log(const InfoLogLevel log_level, Logger* info_log, const char* format,
164 ...) {
165 va_list ap;
166 va_start(ap, format);
167 Logv(log_level, info_log, format, ap);
168 va_end(ap);
169 }
170
171 static void Headerv(Logger *info_log, const char *format, va_list ap) {
172 if (info_log) {
173 info_log->LogHeader(format, ap);
174 }
175 }
176
177 void Header(Logger* info_log, const char* format, ...) {
178 va_list ap;
179 va_start(ap, format);
180 Headerv(info_log, format, ap);
181 va_end(ap);
182 }
183
184 static void Debugv(Logger* info_log, const char* format, va_list ap) {
185 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::DEBUG_LEVEL) {
186 info_log->Logv(InfoLogLevel::DEBUG_LEVEL, format, ap);
187 }
188 }
189
190 void Debug(Logger* info_log, const char* format, ...) {
191 va_list ap;
192 va_start(ap, format);
193 Debugv(info_log, format, ap);
194 va_end(ap);
195 }
196
197 static void Infov(Logger* info_log, const char* format, va_list ap) {
198 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
199 info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
200 }
201 }
202
203 void Info(Logger* info_log, const char* format, ...) {
204 va_list ap;
205 va_start(ap, format);
206 Infov(info_log, format, ap);
207 va_end(ap);
208 }
209
210 static void Warnv(Logger* info_log, const char* format, va_list ap) {
211 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::WARN_LEVEL) {
212 info_log->Logv(InfoLogLevel::WARN_LEVEL, format, ap);
213 }
214 }
215
216 void Warn(Logger* info_log, const char* format, ...) {
217 va_list ap;
218 va_start(ap, format);
219 Warnv(info_log, format, ap);
220 va_end(ap);
221 }
222
223 static void Errorv(Logger* info_log, const char* format, va_list ap) {
224 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::ERROR_LEVEL) {
225 info_log->Logv(InfoLogLevel::ERROR_LEVEL, format, ap);
226 }
227 }
228
229 void Error(Logger* info_log, const char* format, ...) {
230 va_list ap;
231 va_start(ap, format);
232 Errorv(info_log, format, ap);
233 va_end(ap);
234 }
235
236 static void Fatalv(Logger* info_log, const char* format, va_list ap) {
237 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::FATAL_LEVEL) {
238 info_log->Logv(InfoLogLevel::FATAL_LEVEL, format, ap);
239 }
240 }
241
242 void Fatal(Logger* info_log, const char* format, ...) {
243 va_list ap;
244 va_start(ap, format);
245 Fatalv(info_log, format, ap);
246 va_end(ap);
247 }
248
249 void LogFlush(const std::shared_ptr<Logger>& info_log) {
250 LogFlush(info_log.get());
251 }
252
253 void Log(const InfoLogLevel log_level, const std::shared_ptr<Logger>& info_log,
254 const char* format, ...) {
255 va_list ap;
256 va_start(ap, format);
257 Logv(log_level, info_log.get(), format, ap);
258 va_end(ap);
259 }
260
261 void Header(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
262 va_list ap;
263 va_start(ap, format);
264 Headerv(info_log.get(), format, ap);
265 va_end(ap);
266 }
267
268 void Debug(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
269 va_list ap;
270 va_start(ap, format);
271 Debugv(info_log.get(), format, ap);
272 va_end(ap);
273 }
274
275 void Info(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
276 va_list ap;
277 va_start(ap, format);
278 Infov(info_log.get(), format, ap);
279 va_end(ap);
280 }
281
282 void Warn(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
283 va_list ap;
284 va_start(ap, format);
285 Warnv(info_log.get(), format, ap);
286 va_end(ap);
287 }
288
289 void Error(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
290 va_list ap;
291 va_start(ap, format);
292 Errorv(info_log.get(), format, ap);
293 va_end(ap);
294 }
295
296 void Fatal(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
297 va_list ap;
298 va_start(ap, format);
299 Fatalv(info_log.get(), format, ap);
300 va_end(ap);
301 }
302
303 void Log(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
304 va_list ap;
305 va_start(ap, format);
306 Logv(info_log.get(), format, ap);
307 va_end(ap);
308 }
309
310 Status WriteStringToFile(Env* env, const Slice& data, const std::string& fname,
311 bool should_sync) {
312 std::unique_ptr<WritableFile> file;
313 EnvOptions soptions;
314 Status s = env->NewWritableFile(fname, &file, soptions);
315 if (!s.ok()) {
316 return s;
317 }
318 s = file->Append(data);
319 if (s.ok() && should_sync) {
320 s = file->Sync();
321 }
322 if (!s.ok()) {
323 env->DeleteFile(fname);
324 }
325 return s;
326 }
327
328 Status ReadFileToString(Env* env, const std::string& fname, std::string* data) {
329 EnvOptions soptions;
330 data->clear();
331 std::unique_ptr<SequentialFile> file;
332 Status s = env->NewSequentialFile(fname, &file, soptions);
333 if (!s.ok()) {
334 return s;
335 }
336 static const int kBufferSize = 8192;
337 char* space = new char[kBufferSize];
338 while (true) {
339 Slice fragment;
340 s = file->Read(kBufferSize, &fragment, space);
341 if (!s.ok()) {
342 break;
343 }
344 data->append(fragment.data(), fragment.size());
345 if (fragment.empty()) {
346 break;
347 }
348 }
349 delete[] space;
350 return s;
351 }
352
353 EnvWrapper::~EnvWrapper() {
354 }
355
356 namespace { // anonymous namespace
357
358 void AssignEnvOptions(EnvOptions* env_options, const DBOptions& options) {
359 env_options->use_mmap_reads = options.allow_mmap_reads;
360 env_options->use_mmap_writes = options.allow_mmap_writes;
361 env_options->use_direct_reads = options.use_direct_reads;
362 env_options->set_fd_cloexec = options.is_fd_close_on_exec;
363 env_options->bytes_per_sync = options.bytes_per_sync;
364 env_options->compaction_readahead_size = options.compaction_readahead_size;
365 env_options->random_access_max_buffer_size =
366 options.random_access_max_buffer_size;
367 env_options->rate_limiter = options.rate_limiter.get();
368 env_options->writable_file_max_buffer_size =
369 options.writable_file_max_buffer_size;
370 env_options->allow_fallocate = options.allow_fallocate;
371 }
372
373 }
374
375 EnvOptions Env::OptimizeForLogWrite(const EnvOptions& env_options,
376 const DBOptions& db_options) const {
377 EnvOptions optimized_env_options(env_options);
378 optimized_env_options.bytes_per_sync = db_options.wal_bytes_per_sync;
379 optimized_env_options.writable_file_max_buffer_size =
380 db_options.writable_file_max_buffer_size;
381 return optimized_env_options;
382 }
383
384 EnvOptions Env::OptimizeForManifestWrite(const EnvOptions& env_options) const {
385 return env_options;
386 }
387
388 EnvOptions Env::OptimizeForLogRead(const EnvOptions& env_options) const {
389 EnvOptions optimized_env_options(env_options);
390 optimized_env_options.use_direct_reads = false;
391 return optimized_env_options;
392 }
393
394 EnvOptions Env::OptimizeForManifestRead(const EnvOptions& env_options) const {
395 EnvOptions optimized_env_options(env_options);
396 optimized_env_options.use_direct_reads = false;
397 return optimized_env_options;
398 }
399
400 EnvOptions Env::OptimizeForCompactionTableWrite(
401 const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
402 EnvOptions optimized_env_options(env_options);
403 optimized_env_options.use_direct_writes =
404 db_options.use_direct_io_for_flush_and_compaction;
405 return optimized_env_options;
406 }
407
408 EnvOptions Env::OptimizeForCompactionTableRead(
409 const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
410 EnvOptions optimized_env_options(env_options);
411 optimized_env_options.use_direct_reads = db_options.use_direct_reads;
412 return optimized_env_options;
413 }
414
415 EnvOptions::EnvOptions(const DBOptions& options) {
416 AssignEnvOptions(this, options);
417 }
418
419 EnvOptions::EnvOptions() {
420 DBOptions options;
421 AssignEnvOptions(this, options);
422 }
423
424
425 } // namespace rocksdb