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.
7 #include "db/filename.h"
8 #include "db/dbformat.h"
9 #include "leveldb/env.h"
10 #include "util/logging.h"
14 // A utility routine: write "data" to the named file and Sync() it.
15 extern Status WriteStringToFileSync(Env* env, const Slice& data,
16 const std::string& fname);
18 static std::string MakeFileName(const std::string& name, uint64_t number,
21 snprintf(buf, sizeof(buf), "/%06llu.%s",
22 static_cast<unsigned long long>(number),
27 std::string LogFileName(const std::string& name, uint64_t number) {
29 return MakeFileName(name, number, "log");
31 // TableFileName returns the filenames we usually write to, while
32 // SSTTableFileName returns the alternative filenames we also try to read from
33 // for backward compatibility. For now, swap them around.
34 // TODO: when compatibility is no longer necessary, swap them back
35 // (TableFileName to use "ldb" and SSTTableFileName to use "sst").
36 std::string TableFileName(const std::string& name, uint64_t number) {
38 return MakeFileName(name, number, "sst");
41 std::string SSTTableFileName(const std::string& name, uint64_t number) {
43 return MakeFileName(name, number, "ldb");
46 std::string DescriptorFileName(const std::string& dbname, uint64_t number) {
49 snprintf(buf, sizeof(buf), "/MANIFEST-%06llu",
50 static_cast<unsigned long long>(number));
54 std::string CurrentFileName(const std::string& dbname) {
55 return dbname + "/CURRENT";
58 std::string LockFileName(const std::string& dbname) {
59 return dbname + "/LOCK";
62 std::string TempFileName(const std::string& dbname, uint64_t number) {
64 return MakeFileName(dbname, number, "dbtmp");
67 std::string InfoLogFileName(const std::string& dbname) {
68 return dbname + "/LOG";
71 // Return the name of the old info log file for "dbname".
72 std::string OldInfoLogFileName(const std::string& dbname) {
73 return dbname + "/LOG.old";
77 // Owned filenames have the form:
82 // dbname/MANIFEST-[0-9]+
83 // dbname/[0-9]+.(log|sst|ldb)
84 bool ParseFileName(const std::string& fname,
88 if (rest == "CURRENT") {
91 } else if (rest == "LOCK") {
94 } else if (rest == "LOG" || rest == "LOG.old") {
97 } else if (rest.starts_with("MANIFEST-")) {
98 rest.remove_prefix(strlen("MANIFEST-"));
100 if (!ConsumeDecimalNumber(&rest, &num)) {
106 *type = kDescriptorFile;
109 // Avoid strtoull() to keep filename format independent of the
112 if (!ConsumeDecimalNumber(&rest, &num)) {
116 if (suffix == Slice(".log")) {
118 } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) {
120 } else if (suffix == Slice(".dbtmp")) {
130 Status SetCurrentFile(Env* env, const std::string& dbname,
131 uint64_t descriptor_number) {
132 // Remove leading "dbname/" and add newline to manifest file name
133 std::string manifest = DescriptorFileName(dbname, descriptor_number);
134 Slice contents = manifest;
135 assert(contents.starts_with(dbname + "/"));
136 contents.remove_prefix(dbname.size() + 1);
137 std::string tmp = TempFileName(dbname, descriptor_number);
138 Status s = WriteStringToFileSync(env, contents.ToString() + "\n", tmp);
140 s = env->RenameFile(tmp, CurrentFileName(dbname));
143 env->DeleteFile(tmp);
148 } // namespace leveldb