aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcachestore.h
diff options
context:
space:
mode:
authorMartin Ridgers <[email protected]>2021-11-01 12:50:47 +0100
committerMartin Ridgers <[email protected]>2021-11-01 12:50:47 +0100
commit643e96f85a2348bef2f6f3368d2d62c32eee0119 (patch)
treee9987c5078ce281653c08b531f67910a0a050c8d /zenserver/cache/structuredcachestore.h
parentMerged main (diff)
parentMoved declaration of ZenDiskCacheLayer::CacheBucket in the .h (diff)
downloadzen-643e96f85a2348bef2f6f3368d2d62c32eee0119.tar.xz
zen-643e96f85a2348bef2f6f3368d2d62c32eee0119.zip
Merged main
Diffstat (limited to 'zenserver/cache/structuredcachestore.h')
-rw-r--r--zenserver/cache/structuredcachestore.h86
1 files changed, 85 insertions, 1 deletions
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;