Coverage Report

Created: 2025-11-11 06:56

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