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