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");
32 std::string
TableFileName(const std::string
& name
, uint64_t number
) {
34 return MakeFileName(name
, number
, "ldb");
37 std::string
SSTTableFileName(const std::string
& name
, uint64_t number
) {
39 return MakeFileName(name
, number
, "sst");
42 std::string
DescriptorFileName(const std::string
& dbname
, uint64_t number
) {
45 snprintf(buf
, sizeof(buf
), "/MANIFEST-%06llu",
46 static_cast<unsigned long long>(number
));
50 std::string
CurrentFileName(const std::string
& dbname
) {
51 return dbname
+ "/CURRENT";
54 std::string
LockFileName(const std::string
& dbname
) {
55 return dbname
+ "/LOCK";
58 std::string
TempFileName(const std::string
& dbname
, uint64_t number
) {
60 return MakeFileName(dbname
, number
, "dbtmp");
63 std::string
InfoLogFileName(const std::string
& dbname
) {
64 return dbname
+ "/LOG";
67 // Return the name of the old info log file for "dbname".
68 std::string
OldInfoLogFileName(const std::string
& dbname
) {
69 return dbname
+ "/LOG.old";
73 // Owned filenames have the form:
78 // dbname/MANIFEST-[0-9]+
79 // dbname/[0-9]+.(log|sst|ldb)
80 bool ParseFileName(const std::string
& fname
,
84 if (rest
== "CURRENT") {
87 } else if (rest
== "LOCK") {
90 } else if (rest
== "LOG" || rest
== "LOG.old") {
93 } else if (rest
.starts_with("MANIFEST-")) {
94 rest
.remove_prefix(strlen("MANIFEST-"));
96 if (!ConsumeDecimalNumber(&rest
, &num
)) {
102 *type
= kDescriptorFile
;
105 // Avoid strtoull() to keep filename format independent of the
108 if (!ConsumeDecimalNumber(&rest
, &num
)) {
112 if (suffix
== Slice(".log")) {
114 } else if (suffix
== Slice(".sst") || suffix
== Slice(".ldb")) {
116 } else if (suffix
== Slice(".dbtmp")) {
126 Status
SetCurrentFile(Env
* env
, const std::string
& dbname
,
127 uint64_t descriptor_number
) {
128 // Remove leading "dbname/" and add newline to manifest file name
129 std::string manifest
= DescriptorFileName(dbname
, descriptor_number
);
130 Slice contents
= manifest
;
131 assert(contents
.starts_with(dbname
+ "/"));
132 contents
.remove_prefix(dbname
.size() + 1);
133 std::string tmp
= TempFileName(dbname
, descriptor_number
);
134 Status s
= WriteStringToFileSync(env
, contents
.ToString() + "\n", tmp
);
136 s
= env
->RenameFile(tmp
, CurrentFileName(dbname
));
139 env
->DeleteFile(tmp
);
144 } // namespace leveldb