1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Use of this source code is governed by a BSD-style license that can be 3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// found in the LICENSE file. See the AUTHORS file for names of contributors. 4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 5179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <ctype.h> 6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <stdio.h> 7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/filename.h" 8179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/dbformat.h" 9fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/env.h" 10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/logging.h" 11179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 12179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace leveldb { 13179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 14e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com// A utility routine: write "data" to the named file and Sync() it. 15e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.comextern Status WriteStringToFileSync(Env* env, const Slice& data, 16e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com const std::string& fname); 17e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com 18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic std::string MakeFileName(const std::string& name, uint64_t number, 19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const char* suffix) { 20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org char buf[100]; 21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org snprintf(buf, sizeof(buf), "/%06llu.%s", 22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org static_cast<unsigned long long>(number), 23179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org suffix); 24179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return name + buf; 25179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 26179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 27179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string LogFileName(const std::string& name, uint64_t number) { 28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(number > 0); 29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return MakeFileName(name, number, "log"); 30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 31179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string TableFileName(const std::string& name, uint64_t number) { 33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(number > 0); 342d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org return MakeFileName(name, number, "ldb"); 352d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org} 362d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org 372d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.orgstd::string SSTTableFileName(const std::string& name, uint64_t number) { 382d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org assert(number > 0); 39179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return MakeFileName(name, number, "sst"); 40179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 41179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 42179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string DescriptorFileName(const std::string& dbname, uint64_t number) { 43179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(number > 0); 44179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org char buf[100]; 45179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org snprintf(buf, sizeof(buf), "/MANIFEST-%06llu", 46179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org static_cast<unsigned long long>(number)); 47179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return dbname + buf; 48179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 49179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 50179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string CurrentFileName(const std::string& dbname) { 51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return dbname + "/CURRENT"; 52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string LockFileName(const std::string& dbname) { 55179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return dbname + "/LOCK"; 56179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 57179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 58179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string TempFileName(const std::string& dbname, uint64_t number) { 59179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(number > 0); 60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return MakeFileName(dbname, number, "dbtmp"); 61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 63179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string InfoLogFileName(const std::string& dbname) { 64179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return dbname + "/LOG"; 65179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 66179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 67179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Return the name of the old info log file for "dbname". 68179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstd::string OldInfoLogFileName(const std::string& dbname) { 69179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return dbname + "/LOG.old"; 70179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 71179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 72179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 73179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Owned filenames have the form: 74179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// dbname/CURRENT 75179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// dbname/LOCK 76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// dbname/LOG 77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// dbname/LOG.old 78179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// dbname/MANIFEST-[0-9]+ 792d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org// dbname/[0-9]+.(log|sst|ldb) 80179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgbool ParseFileName(const std::string& fname, 81179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint64_t* number, 82179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org FileType* type) { 83179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Slice rest(fname); 84179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (rest == "CURRENT") { 85179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *number = 0; 86179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *type = kCurrentFile; 87179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else if (rest == "LOCK") { 88179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *number = 0; 89179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *type = kDBLockFile; 90179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else if (rest == "LOG" || rest == "LOG.old") { 91179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *number = 0; 92179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *type = kInfoLogFile; 93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else if (rest.starts_with("MANIFEST-")) { 94179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org rest.remove_prefix(strlen("MANIFEST-")); 95179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint64_t num; 96179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!ConsumeDecimalNumber(&rest, &num)) { 97179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return false; 98179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 99179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!rest.empty()) { 100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return false; 101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *type = kDescriptorFile; 103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *number = num; 104179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else { 105179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Avoid strtoull() to keep filename format independent of the 106179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // current locale 107179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint64_t num; 108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!ConsumeDecimalNumber(&rest, &num)) { 109179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return false; 110179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 111179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Slice suffix = rest; 112179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (suffix == Slice(".log")) { 113179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *type = kLogFile; 1142d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) { 115179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *type = kTableFile; 116179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else if (suffix == Slice(".dbtmp")) { 117179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *type = kTempFile; 118179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else { 119179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return false; 120179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 121179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *number = num; 122179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 123179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return true; 124179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 125179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 126179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgStatus SetCurrentFile(Env* env, const std::string& dbname, 127179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint64_t descriptor_number) { 128179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Remove leading "dbname/" and add newline to manifest file name 129179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string manifest = DescriptorFileName(dbname, descriptor_number); 130179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Slice contents = manifest; 131179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(contents.starts_with(dbname + "/")); 132179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org contents.remove_prefix(dbname.size() + 1); 133179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string tmp = TempFileName(dbname, descriptor_number); 134e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com Status s = WriteStringToFileSync(env, contents.ToString() + "\n", tmp); 135179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (s.ok()) { 136179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org s = env->RenameFile(tmp, CurrentFileName(dbname)); 137179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 138179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!s.ok()) { 139179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org env->DeleteFile(tmp); 140179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 141179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return s; 142179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 143179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 14445b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace leveldb 145