Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
flatfile.cpp
Go to the documentation of this file.
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
2
// Copyright (c) 2009-present The Bitcoin Core developers
3
// Distributed under the MIT software license, see the accompanying
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6
#include <
flatfile.h
>
7
8
#include <
tinyformat.h
>
9
#include <
util/fs_helpers.h
>
10
#include <
util/log.h
>
11
12
#include <stdexcept>
13
14
FlatFileSeq::FlatFileSeq
(fs::path dir,
const
char
*
prefix
,
size_t
chunk_size) :
15
m_dir
(
std
::move(dir)),
16
m_prefix
(
prefix
),
17
m_chunk_size
(chunk_size)
18
{
19
if
(chunk_size == 0) {
20
throw
std::invalid_argument(
"chunk_size must be positive"
);
21
}
22
}
23
24
std::string
FlatFilePos::ToString
()
const
25
{
26
return
strprintf
(
"FlatFilePos(nFile=%i, nPos=%i)"
,
nFile
,
nPos
);
27
}
28
29
fs::path
FlatFileSeq::FileName
(
const
FlatFilePos
& pos)
const
30
{
31
return
m_dir
/ fs::u8path(
strprintf
(
"%s%05u.dat"
,
m_prefix
, pos.
nFile
));
32
}
33
34
FILE*
FlatFileSeq::Open
(
const
FlatFilePos
& pos,
bool
read_only)
const
35
{
36
if
(pos.
IsNull
()) {
37
return
nullptr
;
38
}
39
fs::path path =
FileName
(pos);
40
fs::create_directories(path.parent_path());
41
FILE* file =
fsbridge::fopen
(path, read_only ?
"rb"
:
"rb+"
);
42
if
(!file && !read_only)
43
file =
fsbridge::fopen
(path,
"wb+"
);
44
if
(!file) {
45
LogError
(
"Unable to open file %s"
, fs::PathToString(path));
46
return
nullptr
;
47
}
48
if
(pos.
nPos
&& fseek(file, pos.
nPos
, SEEK_SET)) {
49
LogError
(
"Unable to seek to position %u of %s"
, pos.
nPos
, fs::PathToString(path));
50
if
(fclose(file) != 0) {
51
LogError
(
"Unable to close file %s"
, fs::PathToString(path));
52
}
53
return
nullptr
;
54
}
55
return
file;
56
}
57
58
size_t
FlatFileSeq::Allocate
(
const
FlatFilePos
& pos,
size_t
add_size,
bool
& out_of_space)
const
59
{
60
out_of_space =
false
;
61
62
unsigned
int
n_old_chunks = (pos.
nPos
+
m_chunk_size
- 1) /
m_chunk_size
;
63
unsigned
int
n_new_chunks = (pos.
nPos
+ add_size +
m_chunk_size
- 1) /
m_chunk_size
;
64
if
(n_new_chunks > n_old_chunks) {
65
size_t
old_size = pos.
nPos
;
66
size_t
new_size = n_new_chunks *
m_chunk_size
;
67
size_t
inc_size = new_size - old_size;
68
69
if
(
CheckDiskSpace
(
m_dir
, inc_size)) {
70
FILE *file =
Open
(pos);
71
if
(file) {
72
LogDebug
(
BCLog::VALIDATION
,
"Pre-allocating up to position 0x%x in %s%05u.dat\n"
, new_size,
m_prefix
, pos.
nFile
);
73
AllocateFileRange
(file, pos.
nPos
, inc_size);
74
if
(fclose(file) != 0) {
75
LogError
(
"Cannot close file %s%05u.dat after extending it with %u bytes"
,
m_prefix
, pos.
nFile
, new_size);
76
return
0;
77
}
78
return
inc_size;
79
}
80
}
else
{
81
out_of_space =
true
;
82
}
83
}
84
return
0;
85
}
86
87
bool
FlatFileSeq::Flush
(
const
FlatFilePos
& pos,
bool
finalize)
const
88
{
89
FILE* file =
Open
(
FlatFilePos
(pos.
nFile
, 0));
// Avoid fseek to nPos
90
if
(!file) {
91
LogError
(
"%s: failed to open file %d\n"
, __func__, pos.
nFile
);
92
return
false
;
93
}
94
if
(finalize && !
TruncateFile
(file, pos.
nPos
)) {
95
LogError
(
"%s: failed to truncate file %d\n"
, __func__, pos.
nFile
);
96
if
(fclose(file) != 0) {
97
LogError
(
"Failed to close file %d"
, pos.
nFile
);
98
}
99
return
false
;
100
}
101
if
(!
FileCommit
(file)) {
102
LogError
(
"%s: failed to commit file %d\n"
, __func__, pos.
nFile
);
103
if
(fclose(file) != 0) {
104
LogError
(
"Failed to close file %d"
, pos.
nFile
);
105
}
106
return
false
;
107
}
108
DirectoryCommit
(
m_dir
);
109
110
if
(fclose(file) != 0) {
111
LogError
(
"Failed to close file %d after flush"
, pos.
nFile
);
112
return
false
;
113
}
114
return
true
;
115
}
FlatFileSeq::Open
FILE * Open(const FlatFilePos &pos, bool read_only=false) const
Open a handle to the file at the given position.
Definition
flatfile.cpp:34
FlatFileSeq::FileName
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
Definition
flatfile.cpp:29
FlatFileSeq::Flush
bool Flush(const FlatFilePos &pos, bool finalize=false) const
Commit a file to disk, and optionally truncate off extra pre-allocated bytes if final.
Definition
flatfile.cpp:87
FlatFileSeq::m_dir
const fs::path m_dir
Definition
flatfile.h:44
FlatFileSeq::Allocate
size_t Allocate(const FlatFilePos &pos, size_t add_size, bool &out_of_space) const
Allocate additional space in a file after the given starting position.
Definition
flatfile.cpp:58
FlatFileSeq::m_chunk_size
const size_t m_chunk_size
Definition
flatfile.h:46
FlatFileSeq::m_prefix
const char *const m_prefix
Definition
flatfile.h:45
FlatFileSeq::FlatFileSeq
FlatFileSeq(fs::path dir, const char *prefix, size_t chunk_size)
Constructor.
Definition
flatfile.cpp:14
flatfile.h
DirectoryCommit
void DirectoryCommit(const fs::path &dirname)
Sync directory contents.
Definition
fs_helpers.cpp:133
AllocateFileRange
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length)
this function tries to make a particular range of a file allocated (corresponding to disk space) it i...
Definition
fs_helpers.cpp:181
CheckDiskSpace
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
Definition
fs_helpers.cpp:87
TruncateFile
bool TruncateFile(FILE *file, unsigned int length)
Definition
fs_helpers.cpp:144
FileCommit
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
Definition
fs_helpers.cpp:102
fs_helpers.h
log.h
LogError
#define LogError(...)
Definition
log.h:97
LogDebug
#define LogDebug(category,...)
Definition
log.h:115
BCLog::VALIDATION
@ VALIDATION
Definition
categories.h:37
fsbridge::fopen
FILE * fopen(const fs::path &p, const char *mode)
Definition
fs.cpp:25
std
Definition
common.h:29
prefix
const char * prefix
Definition
rest.cpp:1141
FlatFilePos
Definition
flatfile.h:15
FlatFilePos::nPos
uint32_t nPos
Definition
flatfile.h:17
FlatFilePos::ToString
std::string ToString() const
Definition
flatfile.cpp:24
FlatFilePos::IsNull
bool IsNull() const
Definition
flatfile.h:32
FlatFilePos::nFile
int32_t nFile
Definition
flatfile.h:16
tinyformat.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition
tinyformat.h:1172
Generated on
for Bitcoin Core by
1.17.0