env.cc 10.5 KB
Newer Older
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
S
Siying Dong 已提交
2 3 4
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
5
//
J
jorlow@chromium.org 已提交
6 7 8 9
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

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 18
#include "util/arena.h"
#include "util/autovector.h"
J
jorlow@chromium.org 已提交
19

20
namespace rocksdb {
J
jorlow@chromium.org 已提交
21 22 23 24

Env::~Env() {
}

25 26 27 28 29
uint64_t Env::GetThreadID() const {
  std::hash<std::thread::id> hasher;
  return hasher(std::this_thread::get_id());
}

S
Sage Weil 已提交
30 31 32 33 34 35 36 37 38 39 40
Status Env::ReuseWritableFile(const std::string& fname,
                              const std::string& old_fname,
                              unique_ptr<WritableFile>* result,
                              const EnvOptions& options) {
  Status s = RenameFile(old_fname, fname);
  if (!s.ok()) {
    return s;
  }
  return NewWritableFile(fname, result, options);
}

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Status Env::GetChildrenFileAttributes(const std::string& dir,
                                      std::vector<FileAttributes>* result) {
  assert(result != nullptr);
  std::vector<std::string> child_fnames;
  Status s = GetChildren(dir, &child_fnames);
  if (!s.ok()) {
    return s;
  }
  result->resize(child_fnames.size());
  size_t result_size = 0;
  for (size_t i = 0; i < child_fnames.size(); ++i) {
    const std::string path = dir + "/" + child_fnames[i];
    if (!(s = GetFileSize(path, &(*result)[result_size].size_bytes)).ok()) {
      if (FileExists(path).IsNotFound()) {
        // The file may have been deleted since we listed the directory
        continue;
      }
      return s;
    }
    (*result)[result_size].name = std::move(child_fnames[i]);
    result_size++;
  }
  result->resize(result_size);
  return Status::OK();
}

J
jorlow@chromium.org 已提交
67 68 69 70 71 72 73 74 75
SequentialFile::~SequentialFile() {
}

RandomAccessFile::~RandomAccessFile() {
}

WritableFile::~WritableFile() {
}

76
Logger::~Logger() { }
77 78 79 80 81

Status Logger::Close() {
  if (!closed_) {
    closed_ = true;
    return CloseImpl();
82 83
  } else {
    return Status::OK();
84
  }
85 86
}

87
Status Logger::CloseImpl() { return Status::NotSupported(); }
88

J
jorlow@chromium.org 已提交
89 90 91
FileLock::~FileLock() {
}

I
Igor Canadi 已提交
92 93 94 95 96 97
void LogFlush(Logger *info_log) {
  if (info_log) {
    info_log->Flush();
  }
}

98
void Log(Logger* info_log, const char* format, ...) {
99
  if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
100 101
    va_list ap;
    va_start(ap, format);
102
    info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
103 104 105 106
    va_end(ap);
  }
}

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
void Logger::Logv(const InfoLogLevel log_level, const char* format, va_list ap) {
  static const char* kInfoLogLevelNames[5] = { "DEBUG", "INFO", "WARN",
    "ERROR", "FATAL" };
  if (log_level < log_level_) {
    return;
  }

  if (log_level == InfoLogLevel::INFO_LEVEL) {
    // Doesn't print log level if it is INFO level.
    // This is to avoid unexpected performance regression after we add
    // the feature of log level. All the logs before we add the feature
    // are INFO level. We don't want to add extra costs to those existing
    // logging.
    Logv(format, ap);
  } else {
    char new_format[500];
    snprintf(new_format, sizeof(new_format) - 1, "[%s] %s",
      kInfoLogLevelNames[log_level], format);
    Logv(new_format, ap);
  }
}


130 131
void Log(const InfoLogLevel log_level, Logger* info_log, const char* format,
         ...) {
132
  if (info_log && info_log->GetInfoLogLevel() <= log_level) {
133 134
    va_list ap;
    va_start(ap, format);
135 136 137 138 139 140 141

    if (log_level == InfoLogLevel::HEADER_LEVEL) {
      info_log->LogHeader(format, ap);
    } else {
      info_log->Logv(log_level, format, ap);
    }

142 143 144 145
    va_end(ap);
  }
}

146 147 148 149 150 151 152 153 154
void Header(Logger* info_log, const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
    info_log->LogHeader(format, ap);
    va_end(ap);
  }
}

155
void Debug(Logger* info_log, const char* format, ...) {
156
  if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::DEBUG_LEVEL) {
157 158
    va_list ap;
    va_start(ap, format);
159
    info_log->Logv(InfoLogLevel::DEBUG_LEVEL, format, ap);
160 161 162 163 164
    va_end(ap);
  }
}

void Info(Logger* info_log, const char* format, ...) {
165
  if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
166 167
    va_list ap;
    va_start(ap, format);
168
    info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
169 170 171 172 173
    va_end(ap);
  }
}

void Warn(Logger* info_log, const char* format, ...) {
174
  if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::WARN_LEVEL) {
175 176
    va_list ap;
    va_start(ap, format);
177
    info_log->Logv(InfoLogLevel::WARN_LEVEL, format, ap);
178 179 180 181
    va_end(ap);
  }
}
void Error(Logger* info_log, const char* format, ...) {
182
  if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::ERROR_LEVEL) {
183 184
    va_list ap;
    va_start(ap, format);
185
    info_log->Logv(InfoLogLevel::ERROR_LEVEL, format, ap);
186 187 188 189
    va_end(ap);
  }
}
void Fatal(Logger* info_log, const char* format, ...) {
190
  if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::FATAL_LEVEL) {
191 192
    va_list ap;
    va_start(ap, format);
193
    info_log->Logv(InfoLogLevel::FATAL_LEVEL, format, ap);
194 195 196 197
    va_end(ap);
  }
}

I
Igor Canadi 已提交
198 199 200 201 202 203
void LogFlush(const shared_ptr<Logger>& info_log) {
  if (info_log) {
    info_log->Flush();
  }
}

204 205 206 207 208 209 210 211 212 213
void Log(const InfoLogLevel log_level, const shared_ptr<Logger>& info_log,
         const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
    info_log->Logv(log_level, format, ap);
    va_end(ap);
  }
}

214 215 216 217 218 219 220 221 222
void Header(const shared_ptr<Logger>& info_log, const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
    info_log->LogHeader(format, ap);
    va_end(ap);
  }
}

223 224 225 226
void Debug(const shared_ptr<Logger>& info_log, const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
227
    info_log->Logv(InfoLogLevel::DEBUG_LEVEL, format, ap);
228 229 230 231 232 233 234 235
    va_end(ap);
  }
}

void Info(const shared_ptr<Logger>& info_log, const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
236
    info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
237 238 239 240 241 242 243 244
    va_end(ap);
  }
}

void Warn(const shared_ptr<Logger>& info_log, const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
245
    info_log->Logv(InfoLogLevel::WARN_LEVEL, format, ap);
246 247 248 249 250 251 252 253
    va_end(ap);
  }
}

void Error(const shared_ptr<Logger>& info_log, const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
254
    info_log->Logv(InfoLogLevel::ERROR_LEVEL, format, ap);
255 256 257 258 259 260 261 262
    va_end(ap);
  }
}

void Fatal(const shared_ptr<Logger>& info_log, const char* format, ...) {
  if (info_log) {
    va_list ap;
    va_start(ap, format);
263
    info_log->Logv(InfoLogLevel::FATAL_LEVEL, format, ap);
264 265 266 267
    va_end(ap);
  }
}

268 269
void Log(const shared_ptr<Logger>& info_log, const char* format, ...) {
  if (info_log) {
270 271
    va_list ap;
    va_start(ap, format);
272
    info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
273 274
    va_end(ap);
  }
J
jorlow@chromium.org 已提交
275 276
}

I
Igor Canadi 已提交
277 278
Status WriteStringToFile(Env* env, const Slice& data, const std::string& fname,
                         bool should_sync) {
279
  unique_ptr<WritableFile> file;
H
Haobo Xu 已提交
280
  EnvOptions soptions;
281
  Status s = env->NewWritableFile(fname, &file, soptions);
J
jorlow@chromium.org 已提交
282 283 284 285
  if (!s.ok()) {
    return s;
  }
  s = file->Append(data);
286 287 288
  if (s.ok() && should_sync) {
    s = file->Sync();
  }
J
jorlow@chromium.org 已提交
289 290 291 292 293 294 295
  if (!s.ok()) {
    env->DeleteFile(fname);
  }
  return s;
}

Status ReadFileToString(Env* env, const std::string& fname, std::string* data) {
H
Haobo Xu 已提交
296
  EnvOptions soptions;
J
jorlow@chromium.org 已提交
297
  data->clear();
298
  unique_ptr<SequentialFile> file;
299
  Status s = env->NewSequentialFile(fname, &file, soptions);
J
jorlow@chromium.org 已提交
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
  if (!s.ok()) {
    return s;
  }
  static const int kBufferSize = 8192;
  char* space = new char[kBufferSize];
  while (true) {
    Slice fragment;
    s = file->Read(kBufferSize, &fragment, space);
    if (!s.ok()) {
      break;
    }
    data->append(fragment.data(), fragment.size());
    if (fragment.empty()) {
      break;
    }
  }
  delete[] space;
  return s;
}

EnvWrapper::~EnvWrapper() {
}

H
Haobo Xu 已提交
323 324
namespace {  // anonymous namespace

I
Igor Canadi 已提交
325
void AssignEnvOptions(EnvOptions* env_options, const DBOptions& options) {
H
Haobo Xu 已提交
326 327
  env_options->use_mmap_reads = options.allow_mmap_reads;
  env_options->use_mmap_writes = options.allow_mmap_writes;
328
  env_options->use_direct_reads = options.use_direct_reads;
H
Haobo Xu 已提交
329
  env_options->set_fd_cloexec = options.is_fd_close_on_exec;
H
Haobo Xu 已提交
330
  env_options->bytes_per_sync = options.bytes_per_sync;
331
  env_options->compaction_readahead_size = options.compaction_readahead_size;
S
sdong 已提交
332 333
  env_options->random_access_max_buffer_size =
      options.random_access_max_buffer_size;
L
Lei Jin 已提交
334
  env_options->rate_limiter = options.rate_limiter.get();
I
Islam AbdelRahman 已提交
335 336
  env_options->writable_file_max_buffer_size =
      options.writable_file_max_buffer_size;
337
  env_options->allow_fallocate = options.allow_fallocate;
H
Haobo Xu 已提交
338 339 340 341
}

}

342 343 344 345
EnvOptions Env::OptimizeForLogWrite(const EnvOptions& env_options,
                                    const DBOptions& db_options) const {
  EnvOptions optimized_env_options(env_options);
  optimized_env_options.bytes_per_sync = db_options.wal_bytes_per_sync;
346 347
  optimized_env_options.writable_file_max_buffer_size =
      db_options.writable_file_max_buffer_size;
348
  return optimized_env_options;
I
Igor Canadi 已提交
349 350 351 352
}

EnvOptions Env::OptimizeForManifestWrite(const EnvOptions& env_options) const {
  return env_options;
I
Igor Canadi 已提交
353 354
}

355 356 357 358 359 360 361 362 363 364 365 366
EnvOptions Env::OptimizeForLogRead(const EnvOptions& env_options) const {
  EnvOptions optimized_env_options(env_options);
  optimized_env_options.use_direct_reads = false;
  return optimized_env_options;
}

EnvOptions Env::OptimizeForManifestRead(const EnvOptions& env_options) const {
  EnvOptions optimized_env_options(env_options);
  optimized_env_options.use_direct_reads = false;
  return optimized_env_options;
}

367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
EnvOptions Env::OptimizeForCompactionTableWrite(
    const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
  EnvOptions optimized_env_options(env_options);
  optimized_env_options.use_direct_writes =
      db_options.use_direct_io_for_flush_and_compaction;
  return optimized_env_options;
}

EnvOptions Env::OptimizeForCompactionTableRead(
    const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
  EnvOptions optimized_env_options(env_options);
  optimized_env_options.use_direct_reads =
      db_options.use_direct_io_for_flush_and_compaction;
  return optimized_env_options;
}

I
Igor Canadi 已提交
383
EnvOptions::EnvOptions(const DBOptions& options) {
H
Haobo Xu 已提交
384 385 386 387
  AssignEnvOptions(this, options);
}

EnvOptions::EnvOptions() {
I
Igor Canadi 已提交
388
  DBOptions options;
H
Haobo Xu 已提交
389 390 391 392
  AssignEnvOptions(this, options);
}


393
}  // namespace rocksdb