Branch data Line data Source code
# 1 : : // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
# 2 : : // Use of this source code is governed by a BSD-style license that can be
# 3 : : // found in the LICENSE file. See the AUTHORS file for names of contributors.
# 4 : :
# 5 : : #include "db/filename.h"
# 6 : :
# 7 : : #include <ctype.h>
# 8 : : #include <stdio.h>
# 9 : :
# 10 : : #include "db/dbformat.h"
# 11 : : #include "leveldb/env.h"
# 12 : : #include "util/logging.h"
# 13 : :
# 14 : : namespace leveldb {
# 15 : :
# 16 : : // A utility routine: write "data" to the named file and Sync() it.
# 17 : : Status WriteStringToFileSync(Env* env, const Slice& data,
# 18 : : const std::string& fname);
# 19 : :
# 20 : : static std::string MakeFileName(const std::string& dbname, uint64_t number,
# 21 : 9578 : const char* suffix) {
# 22 : 9578 : char buf[100];
# 23 : 9578 : snprintf(buf, sizeof(buf), "/%06llu.%s",
# 24 : 9578 : static_cast<unsigned long long>(number), suffix);
# 25 : 9578 : return dbname + buf;
# 26 : 9578 : }
# 27 : :
# 28 : 3165 : std::string LogFileName(const std::string& dbname, uint64_t number) {
# 29 : 3165 : assert(number > 0);
# 30 : 0 : return MakeFileName(dbname, number, "log");
# 31 : 3165 : }
# 32 : :
# 33 : 3002 : std::string TableFileName(const std::string& dbname, uint64_t number) {
# 34 : 3002 : assert(number > 0);
# 35 : 0 : return MakeFileName(dbname, number, "ldb");
# 36 : 3002 : }
# 37 : :
# 38 : 0 : std::string SSTTableFileName(const std::string& dbname, uint64_t number) {
# 39 : 0 : assert(number > 0);
# 40 : 0 : return MakeFileName(dbname, number, "sst");
# 41 : 0 : }
# 42 : :
# 43 : 6822 : std::string DescriptorFileName(const std::string& dbname, uint64_t number) {
# 44 : 6822 : assert(number > 0);
# 45 : 0 : char buf[100];
# 46 : 6822 : snprintf(buf, sizeof(buf), "/MANIFEST-%06llu",
# 47 : 6822 : static_cast<unsigned long long>(number));
# 48 : 6822 : return dbname + buf;
# 49 : 6822 : }
# 50 : :
# 51 : 7797 : std::string CurrentFileName(const std::string& dbname) {
# 52 : 7797 : return dbname + "/CURRENT";
# 53 : 7797 : }
# 54 : :
# 55 : 2218 : std::string LockFileName(const std::string& dbname) { return dbname + "/LOCK"; }
# 56 : :
# 57 : 3411 : std::string TempFileName(const std::string& dbname, uint64_t number) {
# 58 : 3411 : assert(number > 0);
# 59 : 0 : return MakeFileName(dbname, number, "dbtmp");
# 60 : 3411 : }
# 61 : :
# 62 : 0 : std::string InfoLogFileName(const std::string& dbname) {
# 63 : 0 : return dbname + "/LOG";
# 64 : 0 : }
# 65 : :
# 66 : : // Return the name of the old info log file for "dbname".
# 67 : 0 : std::string OldInfoLogFileName(const std::string& dbname) {
# 68 : 0 : return dbname + "/LOG.old";
# 69 : 0 : }
# 70 : :
# 71 : : // Owned filenames have the form:
# 72 : : // dbname/CURRENT
# 73 : : // dbname/LOCK
# 74 : : // dbname/LOG
# 75 : : // dbname/LOG.old
# 76 : : // dbname/MANIFEST-[0-9]+
# 77 : : // dbname/[0-9]+.(log|sst|ldb)
# 78 : : bool ParseFileName(const std::string& filename, uint64_t* number,
# 79 : 28447 : FileType* type) {
# 80 : 28447 : Slice rest(filename);
# 81 [ + + ]: 28447 : if (rest == "CURRENT") {
# 82 : 4520 : *number = 0;
# 83 : 4520 : *type = kCurrentFile;
# 84 [ + + ]: 23927 : } else if (rest == "LOCK") {
# 85 : 3216 : *number = 0;
# 86 : 3216 : *type = kDBLockFile;
# 87 [ - + ][ - + ]: 20711 : } else if (rest == "LOG" || rest == "LOG.old") {
# [ - + ]
# 88 : 0 : *number = 0;
# 89 : 0 : *type = kInfoLogFile;
# 90 [ + + ]: 20711 : } else if (rest.starts_with("MANIFEST-")) {
# 91 : 6711 : rest.remove_prefix(strlen("MANIFEST-"));
# 92 : 6711 : uint64_t num;
# 93 [ - + ]: 6711 : if (!ConsumeDecimalNumber(&rest, &num)) {
# 94 : 0 : return false;
# 95 : 0 : }
# 96 [ - + ]: 6711 : if (!rest.empty()) {
# 97 : 0 : return false;
# 98 : 0 : }
# 99 : 6711 : *type = kDescriptorFile;
# 100 : 6711 : *number = num;
# 101 : 14000 : } else {
# 102 : : // Avoid strtoull() to keep filename format independent of the
# 103 : : // current locale
# 104 : 14000 : uint64_t num;
# 105 [ + + ]: 14000 : if (!ConsumeDecimalNumber(&rest, &num)) {
# 106 : 6432 : return false;
# 107 : 6432 : }
# 108 : 7568 : Slice suffix = rest;
# 109 [ + + ]: 7568 : if (suffix == Slice(".log")) {
# 110 : 4274 : *type = kLogFile;
# 111 [ - + ][ + + ]: 4274 : } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) {
# [ + + ]
# 112 : 3287 : *type = kTableFile;
# 113 [ - + ]: 3287 : } else if (suffix == Slice(".dbtmp")) {
# 114 : 0 : *type = kTempFile;
# 115 : 7 : } else {
# 116 : 7 : return false;
# 117 : 7 : }
# 118 : 7561 : *number = num;
# 119 : 7561 : }
# 120 : 22008 : return true;
# 121 : 28447 : }
# 122 : :
# 123 : : Status SetCurrentFile(Env* env, const std::string& dbname,
# 124 : 3411 : uint64_t descriptor_number) {
# 125 : : // Remove leading "dbname/" and add newline to manifest file name
# 126 : 3411 : std::string manifest = DescriptorFileName(dbname, descriptor_number);
# 127 : 3411 : Slice contents = manifest;
# 128 : 3411 : assert(contents.starts_with(dbname + "/"));
# 129 : 0 : contents.remove_prefix(dbname.size() + 1);
# 130 : 3411 : std::string tmp = TempFileName(dbname, descriptor_number);
# 131 : 3411 : Status s = WriteStringToFileSync(env, contents.ToString() + "\n", tmp);
# 132 [ + - ]: 3411 : if (s.ok()) {
# 133 : 3411 : s = env->RenameFile(tmp, CurrentFileName(dbname));
# 134 : 3411 : }
# 135 [ - + ]: 3411 : if (!s.ok()) {
# 136 : 0 : env->DeleteFile(tmp);
# 137 : 0 : }
# 138 : 3411 : return s;
# 139 : 3411 : }
# 140 : :
# 141 : : } // namespace leveldb
|