// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include #include namespace zen { class CbObjectView; class CbWriter; enum class CachePolicy : uint8_t { None = 0, QueryLocal = 1 << 0, QueryRemote = 1 << 1, Query = QueryLocal | QueryRemote, StoreLocal = 1 << 2, StoreRemote = 1 << 3, Store = StoreLocal | StoreRemote, SkipMeta = 1 << 4, SkipValue = 1 << 5, SkipAttachments = 1 << 6, SkipData = SkipMeta | SkipValue | SkipAttachments, SkipLocalCopy = 1 << 7, Local = QueryLocal | StoreLocal, Remote = QueryRemote | StoreRemote, Default = Query | Store, Disable = None, }; gsl_DEFINE_ENUM_BITMASK_OPERATORS(CachePolicy); CachePolicy ParseQueryCachePolicy(std::string_view QueryPolicy, CachePolicy Default = CachePolicy::Query); CachePolicy ParseStoreCachePolicy(std::string_view StorePolicy, CachePolicy Default = CachePolicy::Store); CachePolicy ParseSkipCachePolicy(std::string_view SkipPolicy, CachePolicy Default = CachePolicy::None); class CacheRecordPolicy { public: CacheRecordPolicy() = default; CachePolicy GetRecordPolicy() const { return m_RecordPolicy; } CachePolicy GetPayloadPolicy(const Oid& PayloadId) const; CachePolicy GetDefaultPayloadPolicy() const { return m_DefaultPayloadPolicy; } static bool Load(CbObjectView RecordPolicyObject, CacheRecordPolicy& OutRecordPolicy); static void Save(const CacheRecordPolicy& Policy, CbWriter& Writer); private: using PayloadPolicyMap = std::unordered_map; CachePolicy m_RecordPolicy = CachePolicy::Default; CachePolicy m_DefaultPayloadPolicy = CachePolicy::Default; PayloadPolicyMap m_PayloadPolicies; }; struct CacheKey { std::string Bucket; IoHash Hash; static CacheKey Create(std::string_view Bucket, const IoHash& Hash) { return {.Bucket = ToLower(Bucket), .Hash = Hash}; } static const CacheKey Empty; }; inline bool operator==(const CacheKey& A, const CacheKey& B) { return A.Bucket == B.Bucket && A.Hash == B.Hash; } inline bool operator!=(const CacheKey& A, const CacheKey& B) { return A.Bucket != B.Bucket || A.Hash != B.Hash; } inline bool operator<(const CacheKey& A, const CacheKey& B) { const std::string& BucketA = A.Bucket; const std::string& BucketB = B.Bucket; return BucketA == BucketB ? A.Hash < B.Hash : BucketA < BucketB; } struct CacheChunkRequest { CacheKey Key; IoHash ChunkId; Oid PayloadId; uint64_t RawOffset = 0ull; uint64_t RawSize = ~uint64_t(0); CachePolicy Policy = CachePolicy::Default; }; inline bool operator<(const CacheChunkRequest& A, const CacheChunkRequest& B) { if (A.Key < B.Key) { return true; } if (B.Key < A.Key) { return false; } if (A.ChunkId < B.ChunkId) { return true; } if (B.ChunkId < A.ChunkId) { return false; } if (A.PayloadId < B.PayloadId) { return true; } if (B.PayloadId < A.PayloadId) { return false; } return A.RawOffset < B.RawOffset; } } // namespace zen