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