aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/bufferedopenfile.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-10-13 13:32:36 +0200
committerGitHub Enterprise <[email protected]>2025-10-13 13:32:36 +0200
commita6925de9bca8579637fa8a4152ab2b77ef5ca90e (patch)
treee2742dcc584e78de7f8921bd655c22929b37da80 /src/zenutil/bufferedopenfile.cpp
parentmove service common code into base class (#567) (diff)
downloadzen-a6925de9bca8579637fa8a4152ab2b77ef5ca90e.tar.xz
zen-a6925de9bca8579637fa8a4152ab2b77ef5ca90e.zip
refactor builds cmd (#566)
Move builds download code from builds_cmd.cpp to remotestorelib
Diffstat (limited to 'src/zenutil/bufferedopenfile.cpp')
-rw-r--r--src/zenutil/bufferedopenfile.cpp75
1 files changed, 75 insertions, 0 deletions
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 <zenutil/bufferedopenfile.h>
+
+#include <zencore/scopeguard.h>
+#include <zencore/trace.h>
+
+namespace zen {
+
+BufferedOpenFile::BufferedOpenFile(const std::filesystem::path Path,
+ std::atomic<uint64_t>& OpenReadCount,
+ std::atomic<uint64_t>& CurrentOpenFileCount,
+ std::atomic<uint64_t>& ReadCount,
+ std::atomic<uint64_t>& 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<SharedBuffer> 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