Coverage Report

Created: 2026-06-09 06:30

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