diff options
| author | Martin Ridgers <[email protected]> | 2021-11-01 12:50:47 +0100 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-11-01 12:50:47 +0100 |
| commit | 643e96f85a2348bef2f6f3368d2d62c32eee0119 (patch) | |
| tree | e9987c5078ce281653c08b531f67910a0a050c8d | |
| parent | Merged main (diff) | |
| parent | Moved declaration of ZenDiskCacheLayer::CacheBucket in the .h (diff) | |
| download | zen-643e96f85a2348bef2f6f3368d2d62c32eee0119.tar.xz zen-643e96f85a2348bef2f6f3368d2d62c32eee0119.zip | |
Merged main
| -rw-r--r-- | zencore/xmake.lua | 2 | ||||
| -rw-r--r-- | zenserver/cache/structuredcachestore.cpp | 122 | ||||
| -rw-r--r-- | zenserver/cache/structuredcachestore.h | 86 |
3 files changed, 117 insertions, 93 deletions
diff --git a/zencore/xmake.lua b/zencore/xmake.lua index 1abd86b7b..218f299d7 100644 --- a/zencore/xmake.lua +++ b/zencore/xmake.lua @@ -17,9 +17,9 @@ target('zencore') "vcpkg::spdlog", "vcpkg::fmt", "vcpkg::doctest", + "vcpkg::json11", "vcpkg::lz4", "vcpkg::mimalloc", - "vcpkg::json11", "vcpkg::cpr", "vcpkg::curl", -- required by cpr "vcpkg::zlib", -- required by curl diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index f527e501a..5566f4587 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -17,7 +17,6 @@ #include <zencore/testing.h> #include <zencore/testutils.h> #include <zencore/thread.h> -#include <zenstore/basicfile.h> #include <zenstore/cas.h> #include <zenstore/caslog.h> #include <zenstore/cidstore.h> @@ -323,107 +322,48 @@ ZenCacheMemoryLayer::CacheBucket::Put(const IoHash& HashKey, const ZenCacheValue ////////////////////////////////////////////////////////////////////////// -#pragma pack(push) -#pragma pack(1) +inline DiskLocation::DiskLocation() = default; -struct DiskLocation +inline DiskLocation::DiskLocation(uint64_t Offset, uint64_t ValueSize, uint32_t IndexSize, uint64_t Flags) +: OffsetAndFlags(CombineOffsetAndFlags(Offset, Flags)) +, LowerSize(ValueSize & 0xFFFFffff) +, IndexDataSize(IndexSize) { - inline DiskLocation() = default; - - inline DiskLocation(uint64_t Offset, uint64_t ValueSize, uint32_t IndexSize, uint64_t Flags) - : OffsetAndFlags(CombineOffsetAndFlags(Offset, Flags)) - , LowerSize(ValueSize & 0xFFFFffff) - , IndexDataSize(IndexSize) - { - } - - static const uint64_t kOffsetMask = 0x0000'ffFF'ffFF'ffFFull; - static const uint64_t kSizeMask = 0x00FF'0000'0000'0000ull; - static const uint64_t kFlagsMask = 0xff00'0000'0000'0000ull; - static const uint64_t kStandaloneFile = 0x8000'0000'0000'0000ull; - static const uint64_t kStructured = 0x4000'0000'0000'0000ull; - static const uint64_t kTombStone = 0x2000'0000'0000'0000ull; - - static uint64_t CombineOffsetAndFlags(uint64_t Offset, uint64_t Flags) { return Offset | Flags; } +} - inline uint64_t Offset() const { return OffsetAndFlags & kOffsetMask; } - inline uint64_t Size() const { return LowerSize; } - inline uint64_t IsFlagSet(uint64_t Flag) const { return OffsetAndFlags & Flag; } - inline ZenContentType GetContentType() const - { - ZenContentType ContentType = ZenContentType::kBinary; +inline uint64_t DiskLocation::CombineOffsetAndFlags(uint64_t Offset, uint64_t Flags) +{ + return Offset | Flags; +} - if (IsFlagSet(DiskLocation::kStructured)) - { - ContentType = ZenContentType::kCbObject; - } +inline uint64_t DiskLocation::Offset() const +{ + return OffsetAndFlags & kOffsetMask; +} - return ContentType; - } +inline uint64_t DiskLocation::Size() const +{ + return LowerSize; +} -private: - uint64_t OffsetAndFlags = 0; - uint32_t LowerSize = 0; - uint32_t IndexDataSize = 0; -}; +inline uint64_t DiskLocation::IsFlagSet(uint64_t Flag) const +{ + return OffsetAndFlags & Flag; +} -struct DiskIndexEntry +inline ZenContentType DiskLocation::GetContentType() const { - IoHash Key; - DiskLocation Location; -}; + ZenContentType ContentType = ZenContentType::kBinary; -#pragma pack(pop) + if (IsFlagSet(DiskLocation::kStructured)) + { + ContentType = ZenContentType::kCbObject; + } -static_assert(sizeof(DiskIndexEntry) == 36); + return ContentType; +} -struct ZenCacheDiskLayer::CacheBucket -{ - CacheBucket(); - ~CacheBucket(); - - void OpenOrCreate(std::filesystem::path BucketDir, bool AllowCreate = true); - static bool Delete(std::filesystem::path BucketDir); - - bool Get(const IoHash& HashKey, ZenCacheValue& OutValue); - void Put(const IoHash& HashKey, const ZenCacheValue& Value); - void Drop(); - void Flush(); - void Scrub(ScrubContext& Ctx); - void GarbageCollect(GcContext& GcCtx); - - inline bool IsOk() const { return m_IsOk; } - -private: - std::filesystem::path m_BucketDir; - Oid m_BucketId; - bool m_IsOk = false; - uint64_t m_LargeObjectThreshold = 64 * 1024; - - // These files are used to manage storage of small objects for this bucket - - BasicFile m_SobsFile; - TCasLogFile<DiskIndexEntry> m_SlogFile; - - RwLock m_IndexLock; - tsl::robin_map<IoHash, DiskLocation, IoHash::Hasher> m_Index; - uint64_t m_WriteCursor = 0; - - void BuildPath(WideStringBuilderBase& Path, const IoHash& HashKey); - void PutStandaloneCacheValue(const IoHash& HashKey, const ZenCacheValue& Value); - bool GetStandaloneCacheValue(const DiskLocation& Loc, const IoHash& HashKey, ZenCacheValue& OutValue); - bool GetInlineCacheValue(const DiskLocation& Loc, ZenCacheValue& OutValue); - - // These locks are here to avoid contention on file creation, therefore it's sufficient - // that we take the same lock for the same hash - // - // These locks are small and should really be spaced out so they don't share cache lines, - // but we don't currently access them at particularly high frequency so it should not be - // an issue in practice - - RwLock m_ShardedLocks[256]; - inline RwLock& LockForHash(const IoHash& Hash) { return m_ShardedLocks[Hash.Hash[19]]; } -}; +////////////////////////////////////////////////////////////////////////// ZenCacheDiskLayer::CacheBucket::CacheBucket() { diff --git a/zenserver/cache/structuredcachestore.h b/zenserver/cache/structuredcachestore.h index 6260d3e43..5adc7492e 100644 --- a/zenserver/cache/structuredcachestore.h +++ b/zenserver/cache/structuredcachestore.h @@ -7,7 +7,9 @@ #include <zencore/iohash.h> #include <zencore/thread.h> #include <zencore/uid.h> +#include <zenstore/basicfile.h> #include <zenstore/cas.h> +#include <zenstore/caslog.h> ZEN_THIRD_PARTY_INCLUDES_START #include <tsl/robin_map.h> @@ -97,6 +99,42 @@ private: Configuration m_Configuration; }; +#pragma pack(push) +#pragma pack(1) + +struct DiskLocation +{ + static const uint64_t kOffsetMask = 0x0000'ffFF'ffFF'ffFFull; + static const uint64_t kSizeMask = 0x00FF'0000'0000'0000ull; + static const uint64_t kFlagsMask = 0xff00'0000'0000'0000ull; + static const uint64_t kStandaloneFile = 0x8000'0000'0000'0000ull; + static const uint64_t kStructured = 0x4000'0000'0000'0000ull; + static const uint64_t kTombStone = 0x2000'0000'0000'0000ull; + + DiskLocation(); + DiskLocation(uint64_t Offset, uint64_t ValueSize, uint32_t IndexSize, uint64_t Flags); + static uint64_t CombineOffsetAndFlags(uint64_t Offset, uint64_t Flags); + uint64_t Offset() const; + uint64_t Size() const; + uint64_t IsFlagSet(uint64_t Flag) const; + ZenContentType GetContentType() const; + +private: + uint64_t OffsetAndFlags = 0; + uint32_t LowerSize = 0; + uint32_t IndexDataSize = 0; +}; + +struct DiskIndexEntry +{ + IoHash Key; + DiskLocation Location; +}; + +#pragma pack(pop) + +static_assert(sizeof(DiskIndexEntry) == 36); + class ZenCacheDiskLayer { public: @@ -116,7 +154,53 @@ private: /** A cache bucket manages a single directory containing metadata and data for that bucket */ - struct CacheBucket; + struct CacheBucket + { + CacheBucket(); + ~CacheBucket(); + + void OpenOrCreate(std::filesystem::path BucketDir, bool AllowCreate = true); + static bool Delete(std::filesystem::path BucketDir); + + bool Get(const IoHash& HashKey, ZenCacheValue& OutValue); + void Put(const IoHash& HashKey, const ZenCacheValue& Value); + void Drop(); + void Flush(); + void Scrub(ScrubContext& Ctx); + void GarbageCollect(GcContext& GcCtx); + + inline bool IsOk() const { return m_IsOk; } + + private: + std::filesystem::path m_BucketDir; + Oid m_BucketId; + bool m_IsOk = false; + uint64_t m_LargeObjectThreshold = 64 * 1024; + + // These files are used to manage storage of small objects for this bucket + + BasicFile m_SobsFile; + TCasLogFile<DiskIndexEntry> m_SlogFile; + + RwLock m_IndexLock; + tsl::robin_map<IoHash, DiskLocation, IoHash::Hasher> m_Index; + uint64_t m_WriteCursor = 0; + + void BuildPath(WideStringBuilderBase& Path, const IoHash& HashKey); + void PutStandaloneCacheValue(const IoHash& HashKey, const ZenCacheValue& Value); + bool GetStandaloneCacheValue(const DiskLocation& Loc, const IoHash& HashKey, ZenCacheValue& OutValue); + bool GetInlineCacheValue(const DiskLocation& Loc, ZenCacheValue& OutValue); + + // These locks are here to avoid contention on file creation, therefore it's sufficient + // that we take the same lock for the same hash + // + // These locks are small and should really be spaced out so they don't share cache lines, + // but we don't currently access them at particularly high frequency so it should not be + // an issue in practice + + RwLock m_ShardedLocks[256]; + inline RwLock& LockForHash(const IoHash& Hash) { return m_ShardedLocks[Hash.Hash[19]]; } + }; std::filesystem::path m_RootDir; RwLock m_Lock; |