diff --git a/cmd/capi/execute.cpp b/cmd/capi/execute.cpp index b9672399a1..01487631e3 100644 --- a/cmd/capi/execute.cpp +++ b/cmd/capi/execute.cpp @@ -158,12 +158,12 @@ std::vector collect_all_snapshots(const SnapshotRepositor SilkwormHeadersSnapshot raw_headers_snapshot{ .segment{ .file_path = make_path(segment_file), - .memory_address = header_snapshot->memory_file_address(), - .memory_length = header_snapshot->memory_file_size()}, + .memory_address = header_snapshot->memory_file_region().data(), + .memory_length = header_snapshot->memory_file_region().size()}, .header_hash_index{ .file_path = make_path(segment_file.index_file()), - .memory_address = idx_header_hash->memory_file_address(), - .memory_length = idx_header_hash->memory_file_size()}}; + .memory_address = idx_header_hash->memory_file_region().data(), + .memory_length = idx_header_hash->memory_file_region().size()}}; headers_snapshot_sequence.push_back(raw_headers_snapshot); } break; case SnapshotType::bodies: { @@ -172,12 +172,12 @@ std::vector collect_all_snapshots(const SnapshotRepositor SilkwormBodiesSnapshot raw_bodies_snapshot{ .segment{ .file_path = make_path(segment_file), - .memory_address = body_snapshot->memory_file_address(), - .memory_length = body_snapshot->memory_file_size()}, + .memory_address = body_snapshot->memory_file_region().data(), + .memory_length = body_snapshot->memory_file_region().size()}, .block_num_index{ .file_path = make_path(segment_file.index_file()), - .memory_address = idx_body_number->memory_file_address(), - .memory_length = idx_body_number->memory_file_size()}}; + .memory_address = idx_body_number->memory_file_region().data(), + .memory_length = idx_body_number->memory_file_region().size()}}; bodies_snapshot_sequence.push_back(raw_bodies_snapshot); } break; case SnapshotType::transactions: { @@ -187,16 +187,16 @@ std::vector collect_all_snapshots(const SnapshotRepositor SilkwormTransactionsSnapshot raw_transactions_snapshot{ .segment{ .file_path = make_path(segment_file), - .memory_address = tx_snapshot->memory_file_address(), - .memory_length = tx_snapshot->memory_file_size()}, + .memory_address = tx_snapshot->memory_file_region().data(), + .memory_length = tx_snapshot->memory_file_region().size()}, .tx_hash_index{ .file_path = make_path(segment_file.index_file()), - .memory_address = idx_txn_hash->memory_file_address(), - .memory_length = idx_txn_hash->memory_file_size()}, + .memory_address = idx_txn_hash->memory_file_region().data(), + .memory_length = idx_txn_hash->memory_file_region().size()}, .tx_hash_2_block_index{ .file_path = make_path(segment_file.index_file_for_type(SnapshotType::transactions_to_block)), - .memory_address = idx_txn_hash_2_block->memory_file_address(), - .memory_length = idx_txn_hash_2_block->memory_file_size()}}; + .memory_address = idx_txn_hash_2_block->memory_file_region().data(), + .memory_length = idx_txn_hash_2_block->memory_file_region().size()}}; transactions_snapshot_sequence.push_back(raw_transactions_snapshot); } break; default: @@ -351,10 +351,11 @@ int build_indexes(SilkwormHandle handle, const BuildIndexesSettings& settings, c throw std::runtime_error("Snapshot not found in the repository:" + snapshot_name); } - auto mmf = new SilkwormMemoryMappedFile(); - mmf->file_path = make_path(snapshot->path()); - mmf->memory_address = snapshot->memory_file_address(); - mmf->memory_length = snapshot->memory_file_size(); + auto mmf = new SilkwormMemoryMappedFile{ + .file_path = make_path(snapshot->path()), + .memory_address = snapshot->memory_file_region().data(), + .memory_length = snapshot->memory_file_region().size(), + }; snapshots.push_back(mmf); } diff --git a/silkworm/capi/silkworm_test.cpp b/silkworm/capi/silkworm_test.cpp index f5ddff0369..1c7cdf4c01 100644 --- a/silkworm/capi/silkworm_test.cpp +++ b/silkworm/capi/silkworm_test.cpp @@ -426,42 +426,42 @@ TEST_CASE_METHOD(CApiTest, "CAPI silkworm_add_snapshot", "[silkworm][capi]") { SilkwormHeadersSnapshot valid_shs{ .segment = SilkwormMemoryMappedFile{ .file_path = header_snapshot_path_string.c_str(), - .memory_address = header_snapshot.memory_file_address(), - .memory_length = header_snapshot.memory_file_size(), + .memory_address = header_snapshot.memory_file_region().data(), + .memory_length = header_snapshot.memory_file_region().size(), }, .header_hash_index = SilkwormMemoryMappedFile{ .file_path = header_index_path_string.c_str(), - .memory_address = header_snapshot.idx_header_hash()->memory_file_address(), - .memory_length = header_snapshot.idx_header_hash()->memory_file_size(), + .memory_address = header_snapshot.idx_header_hash()->memory_file_region().data(), + .memory_length = header_snapshot.idx_header_hash()->memory_file_region().size(), }, }; SilkwormBodiesSnapshot valid_sbs{ .segment = SilkwormMemoryMappedFile{ .file_path = body_snapshot_path_string.c_str(), - .memory_address = body_snapshot.memory_file_address(), - .memory_length = body_snapshot.memory_file_size(), + .memory_address = body_snapshot.memory_file_region().data(), + .memory_length = body_snapshot.memory_file_region().size(), }, .block_num_index = SilkwormMemoryMappedFile{ .file_path = body_index_path_string.c_str(), - .memory_address = body_snapshot.idx_body_number()->memory_file_address(), - .memory_length = body_snapshot.idx_body_number()->memory_file_size(), + .memory_address = body_snapshot.idx_body_number()->memory_file_region().data(), + .memory_length = body_snapshot.idx_body_number()->memory_file_region().size(), }, }; SilkwormTransactionsSnapshot valid_sts{ .segment = SilkwormMemoryMappedFile{ .file_path = tx_snapshot_path_string.c_str(), - .memory_address = tx_snapshot.memory_file_address(), - .memory_length = tx_snapshot.memory_file_size(), + .memory_address = tx_snapshot.memory_file_region().data(), + .memory_length = tx_snapshot.memory_file_region().size(), }, .tx_hash_index = SilkwormMemoryMappedFile{ .file_path = tx_hash_index_path_string.c_str(), - .memory_address = tx_snapshot.idx_txn_hash()->memory_file_address(), - .memory_length = tx_snapshot.idx_txn_hash()->memory_file_size(), + .memory_address = tx_snapshot.idx_txn_hash()->memory_file_region().data(), + .memory_length = tx_snapshot.idx_txn_hash()->memory_file_region().size(), }, .tx_hash_2_block_index = SilkwormMemoryMappedFile{ .file_path = tx_hash2block_index_path_string.c_str(), - .memory_address = tx_snapshot.idx_txn_hash_2_block()->memory_file_address(), - .memory_length = tx_snapshot.idx_txn_hash_2_block()->memory_file_size(), + .memory_address = tx_snapshot.idx_txn_hash_2_block()->memory_file_region().data(), + .memory_length = tx_snapshot.idx_txn_hash_2_block()->memory_file_region().size(), }, }; diff --git a/silkworm/db/snapshots/rec_split/rec_split.hpp b/silkworm/db/snapshots/rec_split/rec_split.hpp index ce6a68dffc..47f7549c68 100644 --- a/silkworm/db/snapshots/rec_split/rec_split.hpp +++ b/silkworm/db/snapshots/rec_split/rec_split.hpp @@ -275,7 +275,7 @@ class RecSplit { SILK_TRACE << "RecSplit encoded file path: " << encoded_file_->path(); check_minimum_length(kFirstMetadataHeaderLength); - const auto address = encoded_file_->address(); + const auto address = encoded_file_->region().data(); encoded_file_->advise_sequential(); @@ -333,7 +333,7 @@ class RecSplit { offset += kEliasFano32CountLength; const uint64_t u = endian::load_big_u64(address + offset); offset += kEliasFano32ULength; - std::span remaining_data{address + offset, encoded_file_->length() - offset}; + auto remaining_data = encoded_file_->region().subspan(offset); ef_offsets_ = std::make_unique(count, u, remaining_data); offset += ef_offsets_->data().size() * sizeof(uint64_t); @@ -359,7 +359,7 @@ class RecSplit { golomb_param_max_index_ = golomb_param_size - 1; offset += kGolombParamSizeLength; - MemoryMappedInputStream mmis{address + offset, encoded_file_->length() - offset}; + MemoryMappedInputStream mmis{encoded_file_->region().subspan(offset)}; // Read Golomb-Rice codes mmis >> golomb_rice_codes_; @@ -369,7 +369,7 @@ class RecSplit { mmis >> double_ef_index_; offset += 5 * sizeof(uint64_t) + double_ef_index_.data().size() * sizeof(uint64_t); - SILKWORM_ASSERT(offset == encoded_file_->length()); + SILKWORM_ASSERT(offset == encoded_file_->size()); encoded_file_->advise_random(); @@ -600,10 +600,10 @@ class RecSplit { const auto record = operator()(murmur_hash_3(key, length)); const auto position = 1 + 8 + bytes_per_record_ * (record + 1); - const auto address = encoded_file_->address(); - ensure(position + sizeof(uint64_t) < encoded_file_->length(), + const auto region = encoded_file_->region(); + ensure(position + sizeof(uint64_t) < region.size(), [&]() { return "position: " + std::to_string(position) + " plus 8 exceeds file length"; }); - return endian::load_big_u64(address + position) & record_mask_; + return endian::load_big_u64(region.data() + position) & record_mask_; } //! Return the offset of the i-th element in the index. Perfect hash table lookup is not performed, @@ -631,8 +631,7 @@ class RecSplit { return std::filesystem::last_write_time(index_path_); } - [[nodiscard]] uint8_t* memory_file_address() const { return encoded_file_ ? encoded_file_->address() : nullptr; } - [[nodiscard]] std::size_t memory_file_size() const { return encoded_file_ ? encoded_file_->length() : 0; } + [[nodiscard]] MemoryMappedRegion memory_file_region() const { return encoded_file_ ? encoded_file_->region() : MemoryMappedRegion{}; } private: static inline std::size_t skip_bits(std::size_t m) { return memo[m] & 0xFFFF; } @@ -832,9 +831,9 @@ class RecSplit { [[nodiscard]] inline uint64_t hash128_to_bucket(const hash128_t& hash) const { return remap128(hash.first, bucket_count_); } void check_minimum_length(std::size_t minimum_length) { - if (encoded_file_ && encoded_file_->length() < minimum_length) { + if (encoded_file_ && encoded_file_->size() < minimum_length) { throw std::runtime_error("index " + encoded_file_->path().filename().string() + " is too short: " + - std::to_string(encoded_file_->length())); + std::to_string(encoded_file_->size())); } } diff --git a/silkworm/db/snapshots/seg/decompressor.cpp b/silkworm/db/snapshots/seg/decompressor.cpp index b5a7feb43f..8d40384b9b 100644 --- a/silkworm/db/snapshots/seg/decompressor.cpp +++ b/silkworm/db/snapshots/seg/decompressor.cpp @@ -309,11 +309,12 @@ Decompressor::~Decompressor() { void Decompressor::open() { compressed_file_ = std::make_unique(compressed_path_, compressed_region_); - if (compressed_file_->length() < kMinimumFileSize) { - throw std::runtime_error("compressed file is too short: " + std::to_string(compressed_file_->length())); + auto compressed_file_size = compressed_file_->size(); + if (compressed_file_size < kMinimumFileSize) { + throw std::runtime_error("compressed file is too short: " + std::to_string(compressed_file_size)); } - const auto address = compressed_file_->address(); + const auto address = compressed_file_->region().data(); compressed_file_->advise_sequential(); @@ -338,10 +339,10 @@ void Decompressor::open() { // Store the start offset and length of the data words words_start_ = address + positions_dict_offset + position_dict_length; - words_length_ = compressed_file_->length() - (positions_dict_offset + position_dict_length); - SILKWORM_ASSERT(address + compressed_file_->length() == words_start_ + words_length_); + words_length_ = compressed_file_size - (positions_dict_offset + position_dict_length); + SILKWORM_ASSERT(address + compressed_file_size == words_start_ + words_length_); SILK_TRACE << "Decompressor words start offset: " << (words_start_ - address) << " words length: " << words_length_ - << " total length: " << compressed_file_->length(); + << " total size: " << compressed_file_size; compressed_file_->advise_random(); } diff --git a/silkworm/db/snapshots/snapshot.cpp b/silkworm/db/snapshots/snapshot.cpp index 6c20eaff0c..d993fce751 100644 --- a/silkworm/db/snapshots/snapshot.cpp +++ b/silkworm/db/snapshots/snapshot.cpp @@ -43,16 +43,10 @@ Snapshot::Snapshot(SnapshotPath path) Snapshot::Snapshot(SnapshotPath path, MemoryMappedRegion segment_region) : path_(std::move(path)), decoder_{path_.path(), segment_region} {} -uint8_t* Snapshot::memory_file_address() const { +MemoryMappedRegion Snapshot::memory_file_region() const { const auto memory_file{decoder_.memory_file()}; - if (!memory_file) return nullptr; - return memory_file->address(); -} - -std::size_t Snapshot::memory_file_size() const { - const auto memory_file{decoder_.memory_file()}; - if (!memory_file) return 0; - return memory_file->length(); + if (!memory_file) return MemoryMappedRegion{}; + return memory_file->region(); } void Snapshot::reopen_segment() { diff --git a/silkworm/db/snapshots/snapshot.hpp b/silkworm/db/snapshots/snapshot.hpp index 40cbfee2eb..22ba0cb16e 100644 --- a/silkworm/db/snapshots/snapshot.hpp +++ b/silkworm/db/snapshots/snapshot.hpp @@ -73,8 +73,7 @@ class Snapshot { [[nodiscard]] bool empty() const { return item_count() == 0; } [[nodiscard]] std::size_t item_count() const { return decoder_.words_count(); } - [[nodiscard]] uint8_t* memory_file_address() const; - [[nodiscard]] std::size_t memory_file_size() const; + [[nodiscard]] MemoryMappedRegion memory_file_region() const; void reopen_segment(); virtual void reopen_index() = 0; diff --git a/silkworm/db/snapshots/snapshot_decompressor_test.cpp b/silkworm/db/snapshots/snapshot_decompressor_test.cpp index bf64cb3c48..a8a3612f1c 100644 --- a/silkworm/db/snapshots/snapshot_decompressor_test.cpp +++ b/silkworm/db/snapshots/snapshot_decompressor_test.cpp @@ -229,7 +229,7 @@ TEST_CASE("Decompressor::Decompressor from memory", "[silkworm][node][seg][decom SetLogVerbosityGuard guard{log::Level::kNone}; test::TemporarySnapshotFile tmp_snapshot{create_nonempty_snapshot_file()}; MemoryMappedFile mmf{tmp_snapshot.path()}; - Decompressor decoder_from_memory{tmp_snapshot.path(), MemoryMappedRegion{mmf.address(), mmf.length()}}; + Decompressor decoder_from_memory{tmp_snapshot.path(), mmf.region()}; CHECK(!decoder_from_memory.is_open()); CHECK(decoder_from_memory.compressed_path() == tmp_snapshot.path()); CHECK(decoder_from_memory.words_count() == 0); diff --git a/silkworm/infra/common/memory_mapped_file.cpp b/silkworm/infra/common/memory_mapped_file.cpp index 7e132e4d77..88fd3a810d 100644 --- a/silkworm/infra/common/memory_mapped_file.cpp +++ b/silkworm/infra/common/memory_mapped_file.cpp @@ -43,10 +43,9 @@ MemoryMappedFile::MemoryMappedFile(std::filesystem::path path, std::optionaladdress != nullptr, "MemoryMappedFile: address is null"); - ensure(region->length > 0, "MemoryMappedFile: length is zero"); - address_ = region->address; - length_ = region->length; + ensure(region->data() != nullptr, "MemoryMappedFile: address is null"); + ensure(!region->empty(), "MemoryMappedFile: length is zero"); + region_ = *region; } else { map_existing(read_only); } @@ -84,9 +83,10 @@ void MemoryMappedFile::map_existing(bool read_only) { [[maybe_unused]] auto _ = gsl::finally([fd]() { if (INVALID_HANDLE_VALUE != fd) ::CloseHandle(fd); }); - length_ = std::filesystem::file_size(path_); + auto size = std::filesystem::file_size(path_); + auto address = static_cast(mmap(fd, size, read_only)); + region_ = {address, size}; - address_ = static_cast(mmap(fd, read_only)); fd = INVALID_HANDLE_VALUE; } @@ -99,7 +99,7 @@ void MemoryMappedFile::advise_random() { void MemoryMappedFile::advise_sequential() { } -void* MemoryMappedFile::mmap(FileDescriptor fd, bool read_only) { +void* MemoryMappedFile::mmap(FileDescriptor fd, size_t size, bool read_only) { DWORD protection = static_cast(read_only ? PAGE_READONLY : PAGE_READWRITE); mapping_ = ::CreateFileMapping(fd, nullptr, protection, 0, 0, nullptr); // note: no size specified to avoid MapViewOfFile failure @@ -108,7 +108,7 @@ void* MemoryMappedFile::mmap(FileDescriptor fd, bool read_only) { } DWORD desired_access = static_cast(read_only ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS); - void* memory = (LPTSTR)::MapViewOfFile(mapping_, desired_access, 0, static_cast(0), length_); + void* memory = (LPTSTR)::MapViewOfFile(mapping_, desired_access, 0, static_cast(0), size); if (memory == nullptr) { throw std::runtime_error{"MapViewOfFile failed for: " + path_.string() + " error: " + std::to_string(GetLastError())}; @@ -142,9 +142,9 @@ void MemoryMappedFile::map_existing(bool read_only) { } [[maybe_unused]] auto _ = gsl::finally([fd]() { ::close(fd); }); - length_ = std::filesystem::file_size(path_); - - address_ = static_cast(mmap(fd, read_only)); + auto size = std::filesystem::file_size(path_); + auto address = static_cast(mmap(fd, size, read_only)); + region_ = {address, size}; } void MemoryMappedFile::advise_normal() { @@ -159,10 +159,10 @@ void MemoryMappedFile::advise_sequential() { advise(MADV_SEQUENTIAL); } -void* MemoryMappedFile::mmap(FileDescriptor fd, bool read_only) { +void* MemoryMappedFile::mmap(FileDescriptor fd, size_t size, bool read_only) { int flags = MAP_SHARED; - const auto address = ::mmap(nullptr, length_, read_only ? PROT_READ : (PROT_READ | PROT_WRITE), flags, fd, 0); + const auto address = ::mmap(nullptr, size, read_only ? PROT_READ : (PROT_READ | PROT_WRITE), flags, fd, 0); if (address == MAP_FAILED) { throw std::runtime_error{"mmap failed for: " + path_.string() + " error: " + safe_strerror(errno)}; } @@ -171,8 +171,8 @@ void* MemoryMappedFile::mmap(FileDescriptor fd, bool read_only) { } void MemoryMappedFile::unmap() { - if (address_ != nullptr) { - const int result = ::munmap(address_, length_); + if (region_.data() != nullptr) { + const int result = ::munmap(region_.data(), region_.size()); if (result == -1) { throw std::runtime_error{"munmap failed for: " + path_.string() + " error: " + safe_strerror(errno)}; } @@ -180,7 +180,7 @@ void MemoryMappedFile::unmap() { } void MemoryMappedFile::advise(int advice) { - const int result = ::madvise(address_, length_, advice); + const int result = ::madvise(region_.data(), region_.size(), advice); if (result == -1) { // Ignore not implemented in kernel error because it still works (from Erigon) if (errno != ENOSYS) { diff --git a/silkworm/infra/common/memory_mapped_file.hpp b/silkworm/infra/common/memory_mapped_file.hpp index bebfc32ad5..9fdc10a06e 100644 --- a/silkworm/infra/common/memory_mapped_file.hpp +++ b/silkworm/infra/common/memory_mapped_file.hpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -69,10 +70,7 @@ using FileDescriptor = HANDLE; using FileDescriptor = int; #endif -struct MemoryMappedRegion { - uint8_t* address{nullptr}; - std::size_t length{0}; -}; +using MemoryMappedRegion = std::span; class MemoryMappedFile { public: @@ -91,12 +89,12 @@ class MemoryMappedFile { return path_; } - [[nodiscard]] uint8_t* address() const { - return address_; + [[nodiscard]] MemoryMappedRegion region() const { + return region_; } - [[nodiscard]] std::size_t length() const { - return length_; + [[nodiscard]] size_t size() const { + return region_.size(); } [[nodiscard]] std::filesystem::file_time_type last_write_time() const { @@ -110,17 +108,14 @@ class MemoryMappedFile { private: void map_existing(bool read_only); - void* mmap(FileDescriptor fd, bool read_only); + void* mmap(FileDescriptor fd, size_t size, bool read_only); void unmap(); //! The path to the file std::filesystem::path path_; //! The address of the mapped area - uint8_t* address_{nullptr}; - - //! The file size - std::size_t length_{0}; + MemoryMappedRegion region_; //! Flag indicating if memory-mapping is managed internally or not bool managed_; @@ -136,17 +131,15 @@ class MemoryMappedFile { }; struct MemoryMappedStreamBuf : std::streambuf { - MemoryMappedStreamBuf(char const* base, std::size_t size) { - char* p{const_cast(base)}; // NOLINT(cppcoreguidelines-pro-type-const-cast) - this->setg(p, p, p + size); + MemoryMappedStreamBuf(MemoryMappedRegion region) { + auto p = reinterpret_cast(region.data()); + this->setg(p, p, p + region.size()); } }; struct MemoryMappedInputStream : virtual MemoryMappedStreamBuf, std::istream { - MemoryMappedInputStream(char const* base, std::size_t size) - : MemoryMappedStreamBuf(base, size), std::istream(static_cast(this)) {} - MemoryMappedInputStream(unsigned char const* base, std::size_t size) - : MemoryMappedInputStream(reinterpret_cast(base), size) {} + MemoryMappedInputStream(MemoryMappedRegion region) + : MemoryMappedStreamBuf(region), std::istream(static_cast(this)) {} }; } // namespace silkworm diff --git a/silkworm/infra/common/memory_mapped_file_benchmark.cpp b/silkworm/infra/common/memory_mapped_file_benchmark.cpp index 645c2ace3f..5c69c41f76 100644 --- a/silkworm/infra/common/memory_mapped_file_benchmark.cpp +++ b/silkworm/infra/common/memory_mapped_file_benchmark.cpp @@ -69,9 +69,7 @@ static void benchmark_checksum_memory_mapped_file(benchmark::State& state) { silkworm::MemoryMappedFile mapped_file{tmp_file_path}; mapped_file.advise_sequential(); int checksum{0}; - std::size_t count{0}; - for (auto it{mapped_file.address()}; count < mapped_file.length(); ++it, ++count) { - const auto byte{*it}; + for (auto byte : mapped_file.region()) { checksum += byte; } benchmark::DoNotOptimize(checksum); diff --git a/silkworm/infra/common/memory_mapped_file_test.cpp b/silkworm/infra/common/memory_mapped_file_test.cpp index 88b75f84b4..ed98258511 100644 --- a/silkworm/infra/common/memory_mapped_file_test.cpp +++ b/silkworm/infra/common/memory_mapped_file_test.cpp @@ -59,12 +59,12 @@ TEST_CASE("MemoryMappedFile from file", "[silkworm][infra][common][memory_mapped MemoryMappedFile mmf{tmp_file}; SECTION("has expected memory address and size") { - CHECK(mmf.address() != nullptr); - CHECK(mmf.length() == kFileContent.size()); + CHECK(mmf.region().data() != nullptr); + CHECK(mmf.size() == kFileContent.size()); } SECTION("has expected content") { - const auto data{mmf.address()}; + const auto data{mmf.region().data()}; CHECK(data[0] == '\x01'); CHECK(data[1] == '\x02'); CHECK(data[2] == '\x03'); @@ -79,7 +79,7 @@ TEST_CASE("MemoryMappedFile from file", "[silkworm][infra][common][memory_mapped } SECTION("input stream") { - MemoryMappedInputStream mmis{mmf.address(), mmf.length()}; + MemoryMappedInputStream mmis{mmf.region()}; std::string s; mmis >> s; CHECK(s == kFileContent); @@ -100,7 +100,7 @@ TEST_CASE("MemoryMappedFile from file", "[silkworm][infra][common][memory_mapped TEST_CASE("MemoryMappedFile from memory", "[silkworm][infra][common][memory_mapped_file]") { SECTION("constructor fails for null address") { - CHECK_THROWS_AS(MemoryMappedFile("", MemoryMappedRegion{nullptr, 100}), std::logic_error); + CHECK_THROWS_AS(MemoryMappedFile("", MemoryMappedRegion{}), std::logic_error); } SECTION("constructor fails for zero length") { @@ -114,7 +114,7 @@ TEST_CASE("MemoryMappedFile from memory", "[silkworm][infra][common][memory_mapp tmp_stream.write("\x01", 1); tmp_stream.close(); MemoryMappedFile mmf_from_file{tmp_file}; - CHECK_NOTHROW(MemoryMappedFile(tmp_file, MemoryMappedRegion{mmf_from_file.address(), mmf_from_file.length()})); + CHECK_NOTHROW(MemoryMappedFile(tmp_file, mmf_from_file.region())); } const std::string kFileContent{"\x01\x02\x03"}; @@ -123,17 +123,16 @@ TEST_CASE("MemoryMappedFile from memory", "[silkworm][infra][common][memory_mapp tmp_stream.write(kFileContent.data(), static_cast(kFileContent.size())); tmp_stream.close(); MemoryMappedFile mmf_from_file{tmp_file}; - const auto address{mmf_from_file.address()}; - const auto length{mmf_from_file.length()}; - MemoryMappedFile mmf{tmp_file, MemoryMappedRegion{mmf_from_file.address(), mmf_from_file.length()}}; + const auto region{mmf_from_file.region()}; + MemoryMappedFile mmf{tmp_file, mmf_from_file.region()}; SECTION("has expected memory address and size") { - CHECK(mmf.address() == address); - CHECK(mmf.length() == length); + CHECK(mmf.region().data() == region.data()); + CHECK(mmf.region().size() == region.size()); } SECTION("has expected content") { - const auto data{mmf.address()}; + const auto data{mmf.region().data()}; CHECK(data[0] == '\x01'); CHECK(data[1] == '\x02'); CHECK(data[2] == '\x03'); @@ -148,7 +147,7 @@ TEST_CASE("MemoryMappedFile from memory", "[silkworm][infra][common][memory_mapp } SECTION("input stream") { - MemoryMappedInputStream mmis{mmf.address(), mmf.length()}; + MemoryMappedInputStream mmis{mmf.region()}; std::string s; mmis >> s; CHECK(s == kFileContent); @@ -158,7 +157,7 @@ TEST_CASE("MemoryMappedFile from memory", "[silkworm][infra][common][memory_mapp const auto tmp_path = std::filesystem::temp_directory_path() / "example.bin"; std::ofstream{tmp_path.c_str()}.put('a'); MemoryMappedFile mmf_from_path{tmp_path}; - MemoryMappedFile mmf_from_memory{tmp_path, MemoryMappedRegion{mmf_from_path.address(), mmf_from_path.length()}}; + MemoryMappedFile mmf_from_memory{tmp_path, mmf_from_file.region()}; const auto ftime = mmf_from_memory.last_write_time(); // Move file write time 1 hour to the future std::filesystem::last_write_time(tmp_path, ftime + 1h);