aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcachestore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zenserver/cache/structuredcachestore.cpp')
-rw-r--r--zenserver/cache/structuredcachestore.cpp129
1 files changed, 80 insertions, 49 deletions
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp
index 018955e65..502ca6605 100644
--- a/zenserver/cache/structuredcachestore.cpp
+++ b/zenserver/cache/structuredcachestore.cpp
@@ -24,15 +24,16 @@
#include <atlfile.h>
-using namespace zen;
-using namespace fmt::literals;
-
//////////////////////////////////////////////////////////////////////////
-ZenCacheStore::ZenCacheStore(zen::CasStore& Cas, const std::filesystem::path& RootDir) : m_DiskLayer{Cas, RootDir}
+namespace zen {
+
+using namespace fmt::literals;
+
+ZenCacheStore::ZenCacheStore(CasStore& Cas, const std::filesystem::path& RootDir) : m_DiskLayer{Cas, RootDir}
{
ZEN_INFO("initializing structured cache at '{}'", RootDir);
- zen::CreateDirectories(RootDir);
+ CreateDirectories(RootDir);
}
ZenCacheStore::~ZenCacheStore()
@@ -40,7 +41,7 @@ ZenCacheStore::~ZenCacheStore()
}
bool
-ZenCacheStore::Get(std::string_view InBucket, const zen::IoHash& HashKey, ZenCacheValue& OutValue)
+ZenCacheStore::Get(std::string_view InBucket, const IoHash& HashKey, ZenCacheValue& OutValue)
{
bool Ok = m_MemLayer.Get(InBucket, HashKey, OutValue);
@@ -68,7 +69,7 @@ ZenCacheStore::Get(std::string_view InBucket, const zen::IoHash& HashKey, ZenCac
}
void
-ZenCacheStore::Put(std::string_view InBucket, const zen::IoHash& HashKey, const ZenCacheValue& Value)
+ZenCacheStore::Put(std::string_view InBucket, const IoHash& HashKey, const ZenCacheValue& Value)
{
// Store value and index
@@ -104,6 +105,12 @@ ZenCacheStore::Flush()
m_DiskLayer.Flush();
}
+void
+ZenCacheStore::Scrub(ScrubContext& Ctx)
+{
+ m_DiskLayer.Scrub(Ctx);
+ m_MemLayer.Scrub(Ctx);
+}
//////////////////////////////////////////////////////////////////////////
ZenCacheMemoryLayer::ZenCacheMemoryLayer()
@@ -115,7 +122,7 @@ ZenCacheMemoryLayer::~ZenCacheMemoryLayer()
}
bool
-ZenCacheMemoryLayer::Get(std::string_view InBucket, const zen::IoHash& HashKey, ZenCacheValue& OutValue)
+ZenCacheMemoryLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCacheValue& OutValue)
{
CacheBucket* Bucket = nullptr;
@@ -139,7 +146,7 @@ ZenCacheMemoryLayer::Get(std::string_view InBucket, const zen::IoHash& HashKey,
}
void
-ZenCacheMemoryLayer::Put(std::string_view InBucket, const zen::IoHash& HashKey, const ZenCacheValue& Value)
+ZenCacheMemoryLayer::Put(std::string_view InBucket, const IoHash& HashKey, const ZenCacheValue& Value)
{
CacheBucket* Bucket = nullptr;
@@ -178,8 +185,14 @@ ZenCacheMemoryLayer::DropBucket(std::string_view Bucket)
return !!m_Buckets.erase(std::string(Bucket));
}
+void
+ZenCacheMemoryLayer::Scrub(ScrubContext& Ctx)
+{
+ ZEN_UNUSED(Ctx);
+}
+
bool
-ZenCacheMemoryLayer::CacheBucket::Get(const zen::IoHash& HashKey, ZenCacheValue& OutValue)
+ZenCacheMemoryLayer::CacheBucket::Get(const IoHash& HashKey, ZenCacheValue& OutValue)
{
RwLock::SharedLockScope _(m_bucketLock);
@@ -196,7 +209,7 @@ ZenCacheMemoryLayer::CacheBucket::Get(const zen::IoHash& HashKey, ZenCacheValue&
}
void
-ZenCacheMemoryLayer::CacheBucket::Put(const zen::IoHash& HashKey, const ZenCacheValue& Value)
+ZenCacheMemoryLayer::CacheBucket::Put(const IoHash& HashKey, const ZenCacheValue& Value)
{
RwLock::ExclusiveLockScope _(m_bucketLock);
@@ -227,7 +240,7 @@ struct DiskLocation
struct DiskIndexEntry
{
- zen::IoHash Key;
+ IoHash Key;
DiskLocation Location;
};
@@ -243,8 +256,8 @@ struct ZenCacheDiskLayer::CacheBucket
void OpenOrCreate(std::filesystem::path BucketDir);
static bool Delete(std::filesystem::path BucketDir);
- bool Get(const zen::IoHash& HashKey, ZenCacheValue& OutValue);
- void Put(const zen::IoHash& HashKey, const ZenCacheValue& Value);
+ bool Get(const IoHash& HashKey, ZenCacheValue& OutValue);
+ void Put(const IoHash& HashKey, const ZenCacheValue& Value);
void Drop();
void Flush();
@@ -260,12 +273,12 @@ private:
BasicFile m_SobsFile;
TCasLogFile<DiskIndexEntry> m_SlogFile;
- void BuildPath(zen::WideStringBuilderBase& Path, const zen::IoHash& HashKey);
- void PutLargeObject(const zen::IoHash& HashKey, const ZenCacheValue& Value);
+ void BuildPath(WideStringBuilderBase& Path, const IoHash& HashKey);
+ void PutLargeObject(const IoHash& HashKey, const ZenCacheValue& Value);
- RwLock m_IndexLock;
- tsl::robin_map<zen::IoHash, DiskLocation, zen::IoHash::Hasher> m_Index;
- uint64_t m_WriteCursor = 0;
+ RwLock m_IndexLock;
+ tsl::robin_map<IoHash, DiskLocation, IoHash::Hasher> m_Index;
+ uint64_t m_WriteCursor = 0;
};
ZenCacheDiskLayer::CacheBucket::CacheBucket(CasStore& Cas) : m_CasStore(Cas)
@@ -281,7 +294,7 @@ ZenCacheDiskLayer::CacheBucket::Delete(std::filesystem::path BucketDir)
{
if (std::filesystem::exists(BucketDir))
{
- zen::DeleteDirectories(BucketDir);
+ DeleteDirectories(BucketDir);
return true;
}
@@ -292,7 +305,7 @@ ZenCacheDiskLayer::CacheBucket::Delete(std::filesystem::path BucketDir)
void
ZenCacheDiskLayer::CacheBucket::OpenOrCreate(std::filesystem::path BucketDir)
{
- zen::CreateDirectories(BucketDir);
+ CreateDirectories(BucketDir);
m_BucketDir = BucketDir;
@@ -357,7 +370,7 @@ ZenCacheDiskLayer::CacheBucket::OpenOrCreate(std::filesystem::path BucketDir)
uint64_t MaxFileOffset = 0;
- if (zen::RwLock::ExclusiveLockScope _(m_IndexLock); m_Index.empty())
+ if (RwLock::ExclusiveLockScope _(m_IndexLock); m_Index.empty())
{
m_SlogFile.Replay([&](const DiskIndexEntry& Record) {
m_Index[Record.Key] = Record.Location;
@@ -372,25 +385,29 @@ ZenCacheDiskLayer::CacheBucket::OpenOrCreate(std::filesystem::path BucketDir)
}
void
-ZenCacheDiskLayer::CacheBucket::BuildPath(zen::WideStringBuilderBase& Path, const zen::IoHash& HashKey)
+ZenCacheDiskLayer::CacheBucket::BuildPath(WideStringBuilderBase& Path, const IoHash& HashKey)
{
- char hex[sizeof(HashKey.Hash) * 2];
- ToHexBytes(HashKey.Hash, sizeof HashKey.Hash, hex);
+ char HexString[sizeof(HashKey.Hash) * 2];
+ ToHexBytes(HashKey.Hash, sizeof HashKey.Hash, HexString);
Path.Append(m_BucketDir.c_str());
+ Path.Append(L"/blob/");
+ Path.AppendAsciiRange(HexString, HexString + 3);
+ Path.Append(L"/");
+ Path.AppendAsciiRange(HexString + 3, HexString + 5);
Path.Append(L"/");
- Path.AppendAsciiRange(hex, hex + sizeof(hex));
+ Path.AppendAsciiRange(HexString + 5, HexString + sizeof(HexString));
}
bool
-ZenCacheDiskLayer::CacheBucket::Get(const zen::IoHash& HashKey, ZenCacheValue& OutValue)
+ZenCacheDiskLayer::CacheBucket::Get(const IoHash& HashKey, ZenCacheValue& OutValue)
{
if (!m_Ok)
{
return false;
}
- zen::RwLock::SharedLockScope _(m_IndexLock);
+ RwLock::SharedLockScope _(m_IndexLock);
if (auto it = m_Index.find(HashKey); it != m_Index.end())
{
@@ -417,7 +434,7 @@ ZenCacheDiskLayer::CacheBucket::Get(const zen::IoHash& HashKey, ZenCacheValue& O
WideStringBuilder<128> DataFilePath;
BuildPath(DataFilePath, HashKey);
- if (zen::IoBuffer Data = IoBufferBuilder::MakeFromFile(DataFilePath.c_str()))
+ if (IoBuffer Data = IoBufferBuilder::MakeFromFile(DataFilePath.c_str()))
{
OutValue.Value = Data;
OutValue.Value.SetContentType(ContentType);
@@ -431,7 +448,7 @@ ZenCacheDiskLayer::CacheBucket::Get(const zen::IoHash& HashKey, ZenCacheValue& O
}
void
-ZenCacheDiskLayer::CacheBucket::Put(const zen::IoHash& HashKey, const ZenCacheValue& Value)
+ZenCacheDiskLayer::CacheBucket::Put(const IoHash& HashKey, const ZenCacheValue& Value)
{
if (!m_Ok)
{
@@ -453,12 +470,12 @@ ZenCacheDiskLayer::CacheBucket::Put(const zen::IoHash& HashKey, const ZenCacheVa
EntryFlags |= DiskLocation::kStructured;
}
- zen::RwLock::ExclusiveLockScope _(m_IndexLock);
+ RwLock::ExclusiveLockScope _(m_IndexLock);
DiskLocation Loc{.OffsetAndFlags = DiskLocation::CombineOffsetAndFlags(m_WriteCursor, EntryFlags),
.Size = gsl::narrow<uint32_t>(Value.Value.Size())};
- m_WriteCursor = zen::RoundUp(m_WriteCursor + Loc.Size, 16);
+ m_WriteCursor = RoundUp(m_WriteCursor + Loc.Size, 16);
if (auto it = m_Index.find(HashKey); it == m_Index.end())
{
@@ -483,7 +500,7 @@ ZenCacheDiskLayer::CacheBucket::Drop()
m_SobsFile.Close();
m_SlogFile.Close();
- zen::DeleteDirectories(m_BucketDir);
+ DeleteDirectories(m_BucketDir);
}
void
@@ -494,12 +511,22 @@ ZenCacheDiskLayer::CacheBucket::Flush()
}
void
-ZenCacheDiskLayer::CacheBucket::PutLargeObject(const zen::IoHash& HashKey, const ZenCacheValue& Value)
+ZenCacheDiskLayer::Scrub(ScrubContext& Ctx)
{
- zen::WideStringBuilder<128> DataFilePath;
+ ZEN_UNUSED(Ctx);
+}
+
+void
+ZenCacheDiskLayer::CacheBucket::PutLargeObject(const IoHash& HashKey, const ZenCacheValue& Value)
+{
+ WideStringBuilder<128> DataFilePath;
BuildPath(DataFilePath, HashKey);
- // TODO: replace this with a more efficient implementation with proper atomic rename
+ // TODO: replace this process with a more efficient implementation with proper atomic rename
+ // and also avoid creating directories if we can
+
+ std::filesystem::path ParentPath = std::filesystem::path(DataFilePath.c_str()).parent_path();
+ CreateDirectories(ParentPath);
CAtlTemporaryFile DataFile;
@@ -507,21 +534,23 @@ ZenCacheDiskLayer::CacheBucket::PutLargeObject(const zen::IoHash& HashKey, const
if (FAILED(hRes))
{
- zen::ThrowSystemException(hRes, "Failed to open temporary file for put at '{}'"_format(m_BucketDir));
+ ThrowSystemException(hRes, "Failed to open temporary file for put at '{}'"_format(m_BucketDir));
}
hRes = DataFile.Write(Value.Value.Data(), gsl::narrow<DWORD>(Value.Value.Size()));
if (FAILED(hRes))
{
- zen::ThrowSystemException(hRes, "Failed to write payload ({} bytes) to file"_format(NiceBytes(Value.Value.Size())));
+ ThrowSystemException(hRes, "Failed to write payload ({} bytes) to file"_format(NiceBytes(Value.Value.Size())));
}
+ // Move file into place (note: not fully atomic!)
+
hRes = DataFile.Close(DataFilePath.c_str());
if (FAILED(hRes))
{
- zen::ThrowSystemException(hRes, "Failed to finalize file '{}'"_format(zen::WideToUtf8(DataFilePath)));
+ ThrowSystemException(hRes, "Failed to finalize file '{}'"_format(WideToUtf8(DataFilePath)));
}
// Update index
@@ -533,7 +562,7 @@ ZenCacheDiskLayer::CacheBucket::PutLargeObject(const zen::IoHash& HashKey, const
EntryFlags |= DiskLocation::kStructured;
}
- zen::RwLock::ExclusiveLockScope _(m_IndexLock);
+ RwLock::ExclusiveLockScope _(m_IndexLock);
DiskLocation Loc{.OffsetAndFlags = DiskLocation::CombineOffsetAndFlags(0, EntryFlags), .Size = 0};
@@ -560,12 +589,12 @@ ZenCacheDiskLayer::ZenCacheDiskLayer(CasStore& Cas, const std::filesystem::path&
ZenCacheDiskLayer::~ZenCacheDiskLayer() = default;
bool
-ZenCacheDiskLayer::Get(std::string_view InBucket, const zen::IoHash& HashKey, ZenCacheValue& OutValue)
+ZenCacheDiskLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCacheValue& OutValue)
{
CacheBucket* Bucket = nullptr;
{
- zen::RwLock::SharedLockScope _(m_Lock);
+ RwLock::SharedLockScope _(m_Lock);
auto it = m_Buckets.find(std::string(InBucket));
@@ -579,7 +608,7 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const zen::IoHash& HashKey, Ze
{
// Bucket needs to be opened/created
- zen::RwLock::ExclusiveLockScope _(m_Lock);
+ RwLock::ExclusiveLockScope _(m_Lock);
if (auto it = m_Buckets.find(std::string(InBucket)); it != m_Buckets.end())
{
@@ -603,12 +632,12 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const zen::IoHash& HashKey, Ze
}
void
-ZenCacheDiskLayer::Put(std::string_view InBucket, const zen::IoHash& HashKey, const ZenCacheValue& Value)
+ZenCacheDiskLayer::Put(std::string_view InBucket, const IoHash& HashKey, const ZenCacheValue& Value)
{
CacheBucket* Bucket = nullptr;
{
- zen::RwLock::SharedLockScope _(m_Lock);
+ RwLock::SharedLockScope _(m_Lock);
auto it = m_Buckets.find(std::string(InBucket));
@@ -622,7 +651,7 @@ ZenCacheDiskLayer::Put(std::string_view InBucket, const zen::IoHash& HashKey, co
{
// New bucket needs to be created
- zen::RwLock::ExclusiveLockScope _(m_Lock);
+ RwLock::ExclusiveLockScope _(m_Lock);
if (auto it = m_Buckets.find(std::string(InBucket)); it != m_Buckets.end())
{
@@ -651,7 +680,7 @@ ZenCacheDiskLayer::Put(std::string_view InBucket, const zen::IoHash& HashKey, co
bool
ZenCacheDiskLayer::DropBucket(std::string_view InBucket)
{
- zen::RwLock::ExclusiveLockScope _(m_Lock);
+ RwLock::ExclusiveLockScope _(m_Lock);
auto it = m_Buckets.find(std::string(InBucket));
@@ -679,7 +708,7 @@ ZenCacheDiskLayer::Flush()
Buckets.reserve(m_Buckets.size());
{
- zen::RwLock::SharedLockScope _(m_Lock);
+ RwLock::SharedLockScope _(m_Lock);
for (auto& Kv : m_Buckets)
{
@@ -705,7 +734,7 @@ ZenCacheTracker::~ZenCacheTracker()
}
void
-ZenCacheTracker::TrackAccess(std::string_view Bucket, const zen::IoHash& HashKey)
+ZenCacheTracker::TrackAccess(std::string_view Bucket, const IoHash& HashKey)
{
ZEN_UNUSED(Bucket);
ZEN_UNUSED(HashKey);
@@ -715,3 +744,5 @@ void
ZenCacheTracker::Flush()
{
}
+
+} // namespace zen