Skip to content

Commit e624a9b

Browse files
committed
streams: cache file position within AutoFile
1 parent 07c7c96 commit e624a9b

File tree

8 files changed

+48
-35
lines changed

8 files changed

+48
-35
lines changed

src/bench/streams_findbyte.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static void FindByte(benchmark::Bench& bench)
1919
uint8_t data[file_size] = {0};
2020
data[file_size-1] = 1;
2121
file << data;
22-
std::rewind(file.Get());
22+
file.seek(0, SEEK_SET);
2323
BufferedFile bf{file, /*nBufSize=*/file_size + 1, /*nRewindIn=*/file_size};
2424

2525
bench.run([&] {

src/index/txindex.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,7 @@ bool TxIndex::FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRe
8787
CBlockHeader header;
8888
try {
8989
file >> header;
90-
if (fseek(file.Get(), postx.nTxOffset, SEEK_CUR)) {
91-
LogError("%s: fseek(...) failed\n", __func__);
92-
return false;
93-
}
90+
file.seek(postx.nTxOffset, SEEK_CUR);
9491
file >> TX_WITH_WITNESS(tx);
9592
} catch (const std::exception& e) {
9693
LogError("%s: Deserialize or I/O error - %s\n", __func__, e.what());

src/node/blockstorage.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ bool BlockManager::UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos
683683
fileout << GetParams().MessageStart() << nSize;
684684

685685
// Write undo data
686-
long fileOutPos = ftell(fileout.Get());
686+
long fileOutPos = fileout.tell();
687687
if (fileOutPos < 0) {
688688
LogError("%s: ftell failed\n", __func__);
689689
return false;
@@ -981,7 +981,7 @@ bool BlockManager::WriteBlockToDisk(const CBlock& block, FlatFilePos& pos) const
981981
fileout << GetParams().MessageStart() << nSize;
982982

983983
// Write block
984-
long fileOutPos = ftell(fileout.Get());
984+
long fileOutPos = fileout.tell();
985985
if (fileOutPos < 0) {
986986
LogError("%s: ftell failed\n", __func__);
987987
return false;

src/node/utxo_snapshot.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir)
7373
}
7474
afile >> base_blockhash;
7575

76-
if (std::fgetc(afile.Get()) != EOF) {
76+
int64_t position = afile.tell();
77+
afile.seek(0, SEEK_END);
78+
if (position != afile.tell()) {
7779
LogPrintf("[snapshot] warning: unexpected trailing data in %s\n", read_from_str);
7880
} else if (std::ferror(afile.Get())) {
7981
LogPrintf("[snapshot] warning: i/o error reading %s\n", read_from_str);

src/streams.cpp

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,25 @@
77

88
#include <array>
99

10+
AutoFile::AutoFile(std::FILE* file, std::vector<std::byte> data_xor)
11+
: m_file{file}, m_xor{std::move(data_xor)}
12+
{
13+
if (!IsNull()) {
14+
auto pos{std::ftell(m_file)};
15+
if (pos >= 0) m_position = pos;
16+
}
17+
}
18+
1019
std::size_t AutoFile::detail_fread(Span<std::byte> dst)
1120
{
1221
if (!m_file) throw std::ios_base::failure("AutoFile::read: file handle is nullptr");
13-
if (m_xor.empty()) {
14-
return std::fread(dst.data(), 1, dst.size(), m_file);
15-
} else {
16-
const auto init_pos{std::ftell(m_file)};
17-
if (init_pos < 0) throw std::ios_base::failure("AutoFile::read: ftell failed");
18-
std::size_t ret{std::fread(dst.data(), 1, dst.size(), m_file)};
19-
util::Xor(dst.subspan(0, ret), m_xor, init_pos);
20-
return ret;
22+
size_t ret = std::fread(dst.data(), 1, dst.size(), m_file);
23+
if (!m_xor.empty()) {
24+
if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::read: position unknown");
25+
util::Xor(dst.subspan(0, ret), m_xor, *m_position);
2126
}
27+
if (m_position.has_value()) *m_position += ret;
28+
return ret;
2229
}
2330

2431
void AutoFile::seek(int64_t offset, int origin)
@@ -29,18 +36,23 @@ void AutoFile::seek(int64_t offset, int origin)
2936
if (std::fseek(m_file, offset, origin) != 0) {
3037
throw std::ios_base::failure(feof() ? "AutoFile::seek: end of file" : "AutoFile::seek: fseek failed");
3138
}
39+
if (origin == SEEK_SET) {
40+
m_position = offset;
41+
} else if (origin == SEEK_CUR && m_position.has_value()) {
42+
*m_position += offset;
43+
} else {
44+
int64_t r{std::ftell(m_file)};
45+
if (r < 0) {
46+
throw std::ios_base::failure("AutoFile::seek: ftell failed");
47+
}
48+
m_position = r;
49+
}
3250
}
3351

3452
int64_t AutoFile::tell()
3553
{
36-
if (IsNull()) {
37-
throw std::ios_base::failure("AutoFile::tell: file handle is nullptr");
38-
}
39-
int64_t r{std::ftell(m_file)};
40-
if (r < 0) {
41-
throw std::ios_base::failure("AutoFile::tell: ftell failed");
42-
}
43-
return r;
54+
if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::tell: position unknown");
55+
return *m_position;
4456
}
4557

4658
void AutoFile::read(Span<std::byte> dst)
@@ -60,6 +72,7 @@ void AutoFile::ignore(size_t nSize)
6072
throw std::ios_base::failure(feof() ? "AutoFile::ignore: end of file" : "AutoFile::ignore: fread failed");
6173
}
6274
nSize -= nNow;
75+
if (m_position.has_value()) *m_position += nNow;
6376
}
6477
}
6578

@@ -70,19 +83,19 @@ void AutoFile::write(Span<const std::byte> src)
7083
if (std::fwrite(src.data(), 1, src.size(), m_file) != src.size()) {
7184
throw std::ios_base::failure("AutoFile::write: write failed");
7285
}
86+
if (m_position.has_value()) *m_position += src.size();
7387
} else {
74-
auto current_pos{std::ftell(m_file)};
75-
if (current_pos < 0) throw std::ios_base::failure("AutoFile::write: ftell failed");
88+
if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::write: position unknown");
7689
std::array<std::byte, 4096> buf;
7790
while (src.size() > 0) {
7891
auto buf_now{Span{buf}.first(std::min<size_t>(src.size(), buf.size()))};
7992
std::copy(src.begin(), src.begin() + buf_now.size(), buf_now.begin());
80-
util::Xor(buf_now, m_xor, current_pos);
93+
util::Xor(buf_now, m_xor, *m_position);
8194
if (std::fwrite(buf_now.data(), 1, buf_now.size(), m_file) != buf_now.size()) {
8295
throw std::ios_base::failure{"XorFile::write: failed"};
8396
}
8497
src = src.subspan(buf_now.size());
85-
current_pos += buf_now.size();
98+
*m_position += buf_now.size();
8699
}
87100
}
88101
}

src/streams.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,10 @@ class AutoFile
390390
protected:
391391
std::FILE* m_file;
392392
std::vector<std::byte> m_xor;
393+
std::optional<int64_t> m_position;
393394

394395
public:
395-
explicit AutoFile(std::FILE* file, std::vector<std::byte> data_xor={}) : m_file{file}, m_xor{std::move(data_xor)} {}
396+
explicit AutoFile(std::FILE* file, std::vector<std::byte> data_xor={});
396397

397398
~AutoFile() { fclose(); }
398399

src/test/streams_tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE(streams_buffered_file)
261261
for (uint8_t j = 0; j < 40; ++j) {
262262
file << j;
263263
}
264-
std::rewind(file.Get());
264+
file.seek(0, SEEK_SET);
265265

266266
// The buffer size (second arg) must be greater than the rewind
267267
// amount (third arg).
@@ -391,7 +391,7 @@ BOOST_AUTO_TEST_CASE(streams_buffered_file_skip)
391391
for (uint8_t j = 0; j < 40; ++j) {
392392
file << j;
393393
}
394-
std::rewind(file.Get());
394+
file.seek(0, SEEK_SET);
395395

396396
// The buffer is 25 bytes, allow rewinding 10 bytes.
397397
BufferedFile bf{file, 25, 10};
@@ -444,7 +444,7 @@ BOOST_AUTO_TEST_CASE(streams_buffered_file_rand)
444444
for (uint8_t i = 0; i < fileSize; ++i) {
445445
file << i;
446446
}
447-
std::rewind(file.Get());
447+
file.seek(0, SEEK_SET);
448448

449449
size_t bufSize = m_rng.randrange(300) + 1;
450450
size_t rewindSize = m_rng.randrange(bufSize);

src/util/asmap.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,10 @@ std::vector<bool> DecodeAsmap(fs::path path)
203203
LogPrintf("Failed to open asmap file from disk\n");
204204
return bits;
205205
}
206-
fseek(filestr, 0, SEEK_END);
207-
int length = ftell(filestr);
206+
file.seek(0, SEEK_END);
207+
int length = file.tell();
208208
LogPrintf("Opened asmap file %s (%d bytes) from disk\n", fs::quoted(fs::PathToString(path)), length);
209-
fseek(filestr, 0, SEEK_SET);
209+
file.seek(0, SEEK_SET);
210210
uint8_t cur_byte;
211211
for (int i = 0; i < length; ++i) {
212212
file >> cur_byte;

0 commit comments

Comments
 (0)