Coverage Report

Created: 2024-09-19 18:47

/root/bitcoin/src/leveldb/db/filename.cc
Line
Count
Source (jump to first uncovered line)
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