diff options
| author | Dan Engelbrecht <[email protected]> | 2022-12-07 11:21:41 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-12-07 02:21:41 -0800 |
| commit | 100c8f966b1c5b2fb190748f0177600562d1c5fe (patch) | |
| tree | fc85e350dea47330149a1d42eb7a6c7ae0a06111 /zencore/iobuffer.cpp | |
| parent | Cache request record/replay (#198) (diff) | |
| download | zen-100c8f966b1c5b2fb190748f0177600562d1c5fe.tar.xz zen-100c8f966b1c5b2fb190748f0177600562d1c5fe.zip | |
optimizations (#200)
* Use direct file read and direct buffer allocation for small IoBuffer materalization
* Reduce range of materialized data in CompositeBuffer reading
CompressedBuffer header reading often only need a small part and not the whole file
* reduce lock contention in IoBuffer::Materialize
* Reduce parsing of compressed headers
Validate header type at decompression
* faster CreateDirectories - start from leaf going up and recurse back
* optimized BufferHeader::IsValid
* Add ValidateCompressedHeader to use when we don't need the actual compressed data
Validate that we always get compressed data in CidStore::AddChunk
* changelog
Diffstat (limited to 'zencore/iobuffer.cpp')
| -rw-r--r-- | zencore/iobuffer.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/zencore/iobuffer.cpp b/zencore/iobuffer.cpp index 16dd22a58..2522daf35 100644 --- a/zencore/iobuffer.cpp +++ b/zencore/iobuffer.cpp @@ -34,7 +34,7 @@ namespace zen { ////////////////////////////////////////////////////////////////////////// void -IoBufferCore::AllocateBuffer(size_t InSize, size_t Alignment) +IoBufferCore::AllocateBuffer(size_t InSize, size_t Alignment) const { #if ZEN_PLATFORM_WINDOWS if (((InSize & 0xffFF) == 0) && (Alignment == 0x10000)) @@ -238,7 +238,7 @@ IoBufferExtendedCore::~IoBufferExtendedCore() m_DataPtr = nullptr; } -static constexpr size_t MappingLockCount = 64; +static constexpr size_t MappingLockCount = 128; static_assert(IsPow2(MappingLockCount), "MappingLockCount must be power of two"); static RwLock g_MappingLocks[MappingLockCount]; @@ -247,7 +247,7 @@ static RwLock& MappingLockForInstance(const IoBufferExtendedCore* instance) { intptr_t base = (intptr_t)instance; - size_t lock_index = ((base >> 8) ^ (base >> 16)) & (MappingLockCount - 1u); + size_t lock_index = ((base >> 5) ^ (base >> 13)) & (MappingLockCount - 1u); return g_MappingLocks[lock_index]; } @@ -271,9 +271,38 @@ IoBufferExtendedCore::Materialize() const if (m_DataBytes == 0) { - m_Flags.fetch_or(NewFlags, std::memory_order_release); // Fake a "valid" pointer, nobody should read this as size is zero m_DataPtr = reinterpret_cast<uint8_t*>(&m_MmapHandle); + m_Flags.fetch_or(NewFlags, std::memory_order_release); + return; + } + + const size_t DisableMMapSizeLimit = 0x1000ull; + + if (m_DataBytes < DisableMMapSizeLimit) + { + AllocateBuffer(m_DataBytes, sizeof(void*)); + NewFlags |= kIsOwnedByThis; + +#if ZEN_PLATFORM_WINDOWS + OVERLAPPED Ovl{}; + + Ovl.Offset = DWORD(m_FileOffset & 0xffff'ffffu); + Ovl.OffsetHigh = DWORD(m_FileOffset >> 32); + + DWORD dwNumberOfBytesRead = 0; + BOOL Success = ::ReadFile(m_FileHandle, (void*)m_DataPtr, DWORD(m_DataBytes), &dwNumberOfBytesRead, &Ovl); + + ZEN_ASSERT(Success); + ZEN_ASSERT(dwNumberOfBytesRead == m_DataBytes); +#else + static_assert(sizeof(off_t) >= sizeof(uint64_t), "sizeof(off_t) does not support large files"); + int Fd = int(uintptr_t(m_FileHandle)); + int BytesRead = pread(Fd, (void*)m_DataPtr, m_DataBytes, m_FileOffset); + bool Success = (BytesRead > 0); +#endif // ZEN_PLATFORM_WINDOWS + + m_Flags.fetch_or(NewFlags, std::memory_order_release); return; } |