From a6925de9bca8579637fa8a4152ab2b77ef5ca90e Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Mon, 13 Oct 2025 13:32:36 +0200 Subject: refactor builds cmd (#566) Move builds download code from builds_cmd.cpp to remotestorelib --- src/zenutil/bufferedopenfile.cpp | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/zenutil/bufferedopenfile.cpp (limited to 'src/zenutil/bufferedopenfile.cpp') diff --git a/src/zenutil/bufferedopenfile.cpp b/src/zenutil/bufferedopenfile.cpp new file mode 100644 index 000000000..360011302 --- /dev/null +++ b/src/zenutil/bufferedopenfile.cpp @@ -0,0 +1,75 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include + +#include +#include + +namespace zen { + +BufferedOpenFile::BufferedOpenFile(const std::filesystem::path Path, + std::atomic& OpenReadCount, + std::atomic& CurrentOpenFileCount, + std::atomic& ReadCount, + std::atomic& ReadByteCount) +: m_Source(Path, BasicFile::Mode::kRead) +, m_SourceSize(m_Source.FileSize()) +, m_OpenReadCount(OpenReadCount) +, m_CurrentOpenFileCount(CurrentOpenFileCount) +, m_ReadCount(ReadCount) +, m_ReadByteCount(ReadByteCount) + +{ + m_OpenReadCount++; + m_CurrentOpenFileCount++; +} + +BufferedOpenFile::~BufferedOpenFile() +{ + m_CurrentOpenFileCount--; +} + +CompositeBuffer +BufferedOpenFile::GetRange(uint64_t Offset, uint64_t Size) +{ + ZEN_TRACE_CPU("BufferedOpenFile::GetRange"); + + ZEN_ASSERT((m_CacheBlockIndex == (uint64_t)-1) || m_Cache); + auto _ = MakeGuard([&]() { ZEN_ASSERT((m_CacheBlockIndex == (uint64_t)-1) || m_Cache); }); + + ZEN_ASSERT((Offset + Size) <= m_SourceSize); + const uint64_t BlockIndexStart = Offset / BlockSize; + const uint64_t BlockIndexEnd = (Offset + Size - 1) / BlockSize; + + std::vector BufferRanges; + BufferRanges.reserve(BlockIndexEnd - BlockIndexStart + 1); + + uint64_t ReadOffset = Offset; + for (uint64_t BlockIndex = BlockIndexStart; BlockIndex <= BlockIndexEnd; BlockIndex++) + { + const uint64_t BlockStartOffset = BlockIndex * BlockSize; + if (m_CacheBlockIndex != BlockIndex) + { + uint64_t CacheSize = Min(BlockSize, m_SourceSize - BlockStartOffset); + ZEN_ASSERT(CacheSize > 0); + m_Cache = IoBuffer(CacheSize); + m_Source.Read(m_Cache.GetMutableView().GetData(), CacheSize, BlockStartOffset); + m_ReadCount++; + m_ReadByteCount += CacheSize; + m_CacheBlockIndex = BlockIndex; + } + + const uint64_t BytesRead = ReadOffset - Offset; + ZEN_ASSERT(BlockStartOffset <= ReadOffset); + const uint64_t OffsetIntoBlock = ReadOffset - BlockStartOffset; + ZEN_ASSERT(OffsetIntoBlock < m_Cache.GetSize()); + const uint64_t BlockBytes = Min(m_Cache.GetSize() - OffsetIntoBlock, Size - BytesRead); + BufferRanges.emplace_back(SharedBuffer(IoBuffer(m_Cache, OffsetIntoBlock, BlockBytes))); + ReadOffset += BlockBytes; + } + CompositeBuffer Result(std::move(BufferRanges)); + ZEN_ASSERT(Result.GetSize() == Size); + return Result; +} + +} // namespace zen -- cgit v1.2.3