// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include #include "cas.h" #include #include #include namespace spdlog { class logger; } namespace zen { ////////////////////////////////////////////////////////////////////////// #pragma pack(push) #pragma pack(1) struct CasDiskIndexEntry { static const uint8_t kTombstone = 0x01; IoHash Key; BlockStoreDiskLocation Location; ZenContentType ContentType = ZenContentType::kUnknownContentType; uint8_t Flags = 0; }; #pragma pack(pop) static_assert(sizeof(CasDiskIndexEntry) == 32); /** This implements a storage strategy for small CAS values * * New chunks are simply appended to a small object file, and an index is * maintained to allow chunks to be looked up within the active small object * files * */ struct CasContainerStrategy final : public GcStorage { CasContainerStrategy(GcManager& Gc); ~CasContainerStrategy(); CasStore::InsertResult InsertChunk(IoBuffer Chunk, const IoHash& ChunkHash); IoBuffer FindChunk(const IoHash& ChunkHash); bool HaveChunk(const IoHash& ChunkHash); void FilterChunks(HashKeySet& InOutChunks); void Initialize(const std::filesystem::path& RootDirectory, const std::string_view ContainerBaseName, uint32_t MaxBlockSize, uint64_t Alignment, bool IsNewStore); void Flush(); void Scrub(ScrubContext& Ctx); virtual void CollectGarbage(GcContext& GcCtx) override; virtual GcStorageSize StorageSize() const override { return {.DiskSize = m_TotalSize.load(std::memory_order::acquire)}; } private: CasStore::InsertResult InsertChunk(const void* ChunkData, size_t ChunkSize, const IoHash& ChunkHash); void MakeIndexSnapshot(); uint64_t ReadIndexFile(); uint64_t ReadLog(uint64_t SkipEntryCount); void OpenContainer(bool IsNewStore); spdlog::logger& Log() { return m_Log; } std::filesystem::path m_RootDirectory; spdlog::logger& m_Log; uint64_t m_PayloadAlignment = 1u << 4; uint64_t m_MaxBlockSize = 1u << 28; bool m_IsInitialized = false; TCasLogFile m_CasLog; std::string m_ContainerBaseName; std::filesystem::path m_BlocksBasePath; BlockStore m_BlockStore; RwLock m_LocationMapLock; typedef std::unordered_map LocationMap_t; LocationMap_t m_LocationMap; std::atomic_uint64_t m_TotalSize{}; }; void compactcas_forcelink(); } // namespace zen