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