// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include namespace zen { /** Content-defined chunking helper */ class ZenChunkHelper { public: void SetChunkSize(size_t MinSize, size_t MaxSize, size_t AvgSize); size_t ScanChunk(const void* DataBytes, size_t ByteCount); void Reset(); // This controls which chunking approach is used - threshold or // modulo based. Threshold is faster and generates similarly sized // chunks void SetUseThreshold(bool NewState) { m_UseThreshold = NewState; } inline size_t ChunkSizeMin() const { return m_ChunkSizeMin; } inline size_t ChunkSizeMax() const { return m_ChunkSizeMax; } inline size_t ChunkSizeAvg() const { return m_ChunkSizeAvg; } inline uint64_t BytesScanned() const { return m_BytesScanned; } static constexpr size_t kNoBoundaryFound = size_t(~0ull); private: size_t m_ChunkSizeMin = 0; size_t m_ChunkSizeMax = 0; size_t m_ChunkSizeAvg = 0; uint32_t m_Discriminator = 0; // Computed in SetChunkSize() uint32_t m_Threshold = 0; // Computed in SetChunkSize() bool m_UseThreshold = true; static constexpr size_t kChunkSizeLimitMax = 64 * 1024 * 1024; static constexpr size_t kChunkSizeLimitMin = 1024; static constexpr size_t kDefaultAverageChunkSize = 64 * 1024; static constexpr int kWindowSize = 48; uint8_t m_Window[kWindowSize]; uint32_t m_WindowSize = 0; uint32_t m_CurrentHash = 0; uint32_t m_CurrentChunkSize = 0; uint64_t m_BytesScanned = 0; size_t InternalScanChunk(const void* DataBytes, size_t ByteCount); void InternalReset(); }; } // namespace zen