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