leveldb
filename.cc
Go to the documentation of this file.
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 <ctype.h>
6 #include <stdio.h>
7 #include "db/filename.h"
8 #include "db/dbformat.h"
9 #include "leveldb/env.h"
10 #include "util/logging.h"
11 
12 namespace leveldb {
13 
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);
17 
18 static std::string MakeFileName(const std::string& name, uint64_t number,
19  const char* suffix) {
20  char buf[100];
21  snprintf(buf, sizeof(buf), "/%06llu.%s",
22  static_cast<unsigned long long>(number),
23  suffix);
24  return name + buf;
25 }
26 
27 std::string LogFileName(const std::string& name, uint64_t number) {
28  assert(number > 0);
29  return MakeFileName(name, number, "log");
30 }
31 
32 std::string TableFileName(const std::string& name, uint64_t number) {
33  assert(number > 0);
34  return MakeFileName(name, number, "ldb");
35 }
36 
37 std::string SSTTableFileName(const std::string& name, uint64_t number) {
38  assert(number > 0);
39  return MakeFileName(name, number, "sst");
40 }
41 
42 std::string DescriptorFileName(const std::string& dbname, uint64_t number) {
43  assert(number > 0);
44  char buf[100];
45  snprintf(buf, sizeof(buf), "/MANIFEST-%06llu",
46  static_cast<unsigned long long>(number));
47  return dbname + buf;
48 }
49 
50 std::string CurrentFileName(const std::string& dbname) {
51  return dbname + "/CURRENT";
52 }
53 
54 std::string LockFileName(const std::string& dbname) {
55  return dbname + "/LOCK";
56 }
57 
58 std::string TempFileName(const std::string& dbname, uint64_t number) {
59  assert(number > 0);
60  return MakeFileName(dbname, number, "dbtmp");
61 }
62 
63 std::string InfoLogFileName(const std::string& dbname) {
64  return dbname + "/LOG";
65 }
66 
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";
70 }
71 
72 
73 // Owned filenames have the form:
74 // dbname/CURRENT
75 // dbname/LOCK
76 // dbname/LOG
77 // dbname/LOG.old
78 // dbname/MANIFEST-[0-9]+
79 // dbname/[0-9]+.(log|sst|ldb)
80 bool ParseFileName(const std::string& fname,
81  uint64_t* number,
82  FileType* type) {
83  Slice rest(fname);
84  if (rest == "CURRENT") {
85  *number = 0;
86  *type = kCurrentFile;
87  } else if (rest == "LOCK") {
88  *number = 0;
89  *type = kDBLockFile;
90  } else if (rest == "LOG" || rest == "LOG.old") {
91  *number = 0;
92  *type = kInfoLogFile;
93  } else if (rest.starts_with("MANIFEST-")) {
94  rest.remove_prefix(strlen("MANIFEST-"));
95  uint64_t num;
96  if (!ConsumeDecimalNumber(&rest, &num)) {
97  return false;
98  }
99  if (!rest.empty()) {
100  return false;
101  }
102  *type = kDescriptorFile;
103  *number = num;
104  } else {
105  // Avoid strtoull() to keep filename format independent of the
106  // current locale
107  uint64_t num;
108  if (!ConsumeDecimalNumber(&rest, &num)) {
109  return false;
110  }
111  Slice suffix = rest;
112  if (suffix == Slice(".log")) {
113  *type = kLogFile;
114  } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) {
115  *type = kTableFile;
116  } else if (suffix == Slice(".dbtmp")) {
117  *type = kTempFile;
118  } else {
119  return false;
120  }
121  *number = num;
122  }
123  return true;
124 }
125 
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);
135  if (s.ok()) {
136  s = env->RenameFile(tmp, CurrentFileName(dbname));
137  }
138  if (!s.ok()) {
139  env->DeleteFile(tmp);
140  }
141  return s;
142 }
143 
144 } // namespace leveldb
Status WriteStringToFileSync(Env *env, const Slice &data, const std::string &fname)
Definition: env.cc:67
bool ParseFileName(const std::string &fname, uint64_t *number, FileType *type)
Definition: filename.cc:80
std::string OldInfoLogFileName(const std::string &dbname)
Definition: filename.cc:68
bool empty() const
Definition: slice.h:46
std::string TempFileName(const std::string &dbname, uint64_t number)
Definition: filename.cc:58
std::string InfoLogFileName(const std::string &dbname)
Definition: filename.cc:63
std::string ToString() const
Definition: slice.h:66
std::string TableFileName(const std::string &name, uint64_t number)
Definition: filename.cc:32
bool ConsumeDecimalNumber(Slice *in, uint64_t *val)
Definition: logging.cc:48
std::string DescriptorFileName(const std::string &dbname, uint64_t number)
Definition: filename.cc:42
static char dbname[200]
Definition: c_test.c:15
Status SetCurrentFile(Env *env, const std::string &dbname, uint64_t descriptor_number)
Definition: filename.cc:126
std::string CurrentFileName(const std::string &dbname)
Definition: filename.cc:50
static std::string MakeFileName(const std::string &name, uint64_t number, const char *suffix)
Definition: filename.cc:18
virtual Status RenameFile(const std::string &src, const std::string &target)=0
std::string SSTTableFileName(const std::string &name, uint64_t number)
Definition: filename.cc:37
void remove_prefix(size_t n)
Definition: slice.h:59
bool ok() const
Definition: status.h:52
std::string LogFileName(const std::string &name, uint64_t number)
Definition: filename.cc:27
bool starts_with(const Slice &x) const
Definition: slice.h:75
FileType
Definition: filename.h:20
virtual Status DeleteFile(const std::string &fname)=0
std::string LockFileName(const std::string &dbname)
Definition: filename.cc:54