xref: /aosp_15_r20/external/leveldb/db/filename.cc (revision 9507f98c5f32dee4b5f9e4a38cd499f3ff5c4490)
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