Coverage Report

Created: 2023-06-07 06:28

/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 <cassert>
8
#include <cstdio>
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
1.08M
                                const char* suffix) {
22
1.08M
  char buf[100];
23
1.08M
  std::snprintf(buf, sizeof(buf), "/%06llu.%s",
24
1.08M
                static_cast<unsigned long long>(number), suffix);
25
1.08M
  return dbname + buf;
26
1.08M
}
27
28
282k
std::string LogFileName(const std::string& dbname, uint64_t number) {
29
282k
  assert(number > 0);
30
282k
  return MakeFileName(dbname, number, "log");
31
282k
}
32
33
668k
std::string TableFileName(const std::string& dbname, uint64_t number) {
34
668k
  assert(number > 0);
35
668k
  return MakeFileName(dbname, number, "ldb");
36
668k
}
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
272k
std::string DescriptorFileName(const std::string& dbname, uint64_t number) {
44
272k
  assert(number > 0);
45
272k
  char buf[100];
46
272k
  std::snprintf(buf, sizeof(buf), "/MANIFEST-%06llu",
47
272k
                static_cast<unsigned long long>(number));
48
272k
  return dbname + buf;
49
272k
}
50
51
397k
std::string CurrentFileName(const std::string& dbname) {
52
397k
  return dbname + "/CURRENT";
53
397k
}
54
55
130k
std::string LockFileName(const std::string& dbname) { return dbname + "/LOCK"; }
56
57
136k
std::string TempFileName(const std::string& dbname, uint64_t number) {
58
136k
  assert(number > 0);
59
136k
  return MakeFileName(dbname, number, "dbtmp");
60
136k
}
61
62
261k
std::string InfoLogFileName(const std::string& dbname) {
63
261k
  return dbname + "/LOG";
64
261k
}
65
66
// Return the name of the old info log file for "dbname".
67
130k
std::string OldInfoLogFileName(const std::string& dbname) {
68
130k
  return dbname + "/LOG.old";
69
130k
}
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
4.59M
                   FileType* type) {
80
4.59M
  Slice rest(filename);
81
4.59M
  if (rest == "CURRENT") {
82
310k
    *number = 0;
83
310k
    *type = kCurrentFile;
84
4.28M
  } else if (rest == "LOCK") {
85
310k
    *number = 0;
86
310k
    *type = kDBLockFile;
87
3.97M
  } else if (rest == "LOG" || rest == "LOG.old") {
88
607k
    *number = 0;
89
607k
    *type = kInfoLogFile;
90
3.36M
  } else if (rest.starts_with("MANIFEST-")) {
91
441k
    rest.remove_prefix(strlen("MANIFEST-"));
92
441k
    uint64_t num;
93
441k
    if (!ConsumeDecimalNumber(&rest, &num)) {
94
0
      return false;
95
0
    }
96
441k
    if (!rest.empty()) {
97
0
      return false;
98
0
    }
99
441k
    *type = kDescriptorFile;
100
441k
    *number = num;
101
2.92M
  } else {
102
    // Avoid strtoull() to keep filename format independent of the
103
    // current locale
104
2.92M
    uint64_t num;
105
2.92M
    if (!ConsumeDecimalNumber(&rest, &num)) {
106
621k
      return false;
107
621k
    }
108
2.30M
    Slice suffix = rest;
109
2.30M
    if (suffix == Slice(".log")) {
110
457k
      *type = kLogFile;
111
1.84M
    } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) {
112
1.84M
      *type = kTableFile;
113
1.84M
    } else if (suffix == Slice(".dbtmp")) {
114
0
      *type = kTempFile;
115
0
    } else {
116
0
      return false;
117
0
    }
118
2.30M
    *number = num;
119
2.30M
  }
120
3.97M
  return true;
121
4.59M
}
122
123
Status SetCurrentFile(Env* env, const std::string& dbname,
124
136k
                      uint64_t descriptor_number) {
125
  // Remove leading "dbname/" and add newline to manifest file name
126
136k
  std::string manifest = DescriptorFileName(dbname, descriptor_number);
127
136k
  Slice contents = manifest;
128
136k
  assert(contents.starts_with(dbname + "/"));
129
136k
  contents.remove_prefix(dbname.size() + 1);
130
136k
  std::string tmp = TempFileName(dbname, descriptor_number);
131
136k
  Status s = WriteStringToFileSync(env, contents.ToString() + "\n", tmp);
132
136k
  if (s.ok()) {
133
136k
    s = env->RenameFile(tmp, CurrentFileName(dbname));
134
136k
  }
135
136k
  if (!s.ok()) {
136
0
    env->RemoveFile(tmp);
137
0
  }
138
136k
  return s;
139
136k
}
140
141
}  // namespace leveldb