diff options
| author | Stefan Boberg <[email protected]> | 2021-05-24 21:04:01 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-05-24 21:04:01 +0200 |
| commit | d75de15200195e0854f9ba36a94bc659fb811b09 (patch) | |
| tree | 521e98362f7eccf13cef52f4a398812133c0330a /zenserver/cache/structuredcachestore.cpp | |
| parent | Added support for early release of scoped RWLock helpers (diff) | |
| download | zen-d75de15200195e0854f9ba36a94bc659fb811b09.tar.xz zen-d75de15200195e0854f9ba36a94bc659fb811b09.zip | |
Z$ now tracks content type for large objects as well as small. Large objects are tracked in index
Diffstat (limited to 'zenserver/cache/structuredcachestore.cpp')
| -rw-r--r-- | zenserver/cache/structuredcachestore.cpp | 126 |
1 files changed, 92 insertions, 34 deletions
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index 59588af48..91893d6b3 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -130,6 +130,8 @@ ZenCacheMemoryLayer::Put(std::string_view InBucket, const zen::IoHash& HashKey, ZEN_ASSERT(Bucket != nullptr); + // Note that since the underlying IoBuffer is retained, the content type is also + Bucket->Put(HashKey, Value); } @@ -165,9 +167,19 @@ ZenCacheMemoryLayer::CacheBucket::Put(const zen::IoHash& HashKey, const ZenCache struct DiskLocation { - uint64_t Offset; + uint64_t OffsetAndFlags; uint32_t Size; uint32_t IndexDataSize; + + static const uint64_t kOffsetMask = 0x00FF'ffFF'ffFF'ffFFull; + 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 uint64_t CombineOffsetAndFlags(uint64_t Offset, uint64_t Flags) { return Offset | Flags; } + + inline uint64_t Offset() const { return OffsetAndFlags & kOffsetMask; } + inline uint64_t IsFlagSet(uint64_t Flag) const { return OffsetAndFlags & Flag; } }; struct DiskIndexEntry @@ -297,7 +309,7 @@ ZenCacheDiskLayer::CacheBucket::OpenOrCreate(std::filesystem::path BucketDir) m_SlogFile.Replay([&](const DiskIndexEntry& Record) { m_Index[Record.Key] = Record.Location; - MaxFileOffset = std::max<uint64_t>(MaxFileOffset, Record.Location.Offset + Record.Location.Size); + MaxFileOffset = std::max<uint64_t>(MaxFileOffset, Record.Location.Offset() + Record.Location.Size); }); } @@ -325,32 +337,44 @@ ZenCacheDiskLayer::CacheBucket::Get(const zen::IoHash& HashKey, ZenCacheValue& O return false; } + zen::RwLock::SharedLockScope _(m_IndexLock); + + if (auto it = m_Index.find(HashKey); it != m_Index.end()) { - zen::RwLock::SharedLockScope _(m_IndexLock); + const DiskLocation& Loc = it->second; + + ZenContentType ContentType = ZenContentType::kBinary; + + if (Loc.IsFlagSet(DiskLocation::kStructured)) + { + ContentType = ZenContentType::kCbObject; + } - if (auto it = m_Index.find(HashKey); it != m_Index.end()) + if (!Loc.IsFlagSet(DiskLocation::kStandaloneFile)) { - OutValue.Value = IoBufferBuilder::MakeFromFileHandle(m_SobsFile.Handle(), it->second.Offset, it->second.Size); + OutValue.Value = IoBufferBuilder::MakeFromFileHandle(m_SobsFile.Handle(), Loc.Offset(), Loc.Size); + OutValue.Value.SetContentType(ContentType); return true; } - } + else + { + _.ReleaseNow(); - WideStringBuilder<128> DataFilePath; - BuildPath(DataFilePath, HashKey); + WideStringBuilder<128> DataFilePath; + BuildPath(DataFilePath, HashKey); - zen::IoBuffer Data = IoBufferBuilder::MakeFromFile(DataFilePath.c_str()); + if (zen::IoBuffer Data = IoBufferBuilder::MakeFromFile(DataFilePath.c_str())) + { + OutValue.Value = Data; + OutValue.Value.SetContentType(ContentType); - if (!Data) - { - return false; + return true; + } + } } - OutValue.Value = Data; - - // TODO: should populate index? - - return true; + return false; } void @@ -365,30 +389,38 @@ ZenCacheDiskLayer::CacheBucket::Put(const zen::IoHash& HashKey, const ZenCacheVa { return PutLargeObject(HashKey, Value); } + else + { + // Small object put - // Small object put + uint64_t EntryFlags = 0; - zen::RwLock::ExclusiveLockScope _(m_IndexLock); + if (Value.Value.GetContentType() == ZenContentType::kCbObject) + { + EntryFlags |= DiskLocation::kStructured; + } - DiskLocation Loc{.Offset = m_WriteCursor, .Size = gsl::narrow<uint32_t>(Value.Value.Size())}; + zen::RwLock::ExclusiveLockScope _(m_IndexLock); - m_WriteCursor = zen::RoundUp(m_WriteCursor + Loc.Size, 16); + DiskLocation Loc{.OffsetAndFlags = DiskLocation::CombineOffsetAndFlags(m_WriteCursor, EntryFlags), + .Size = gsl::narrow<uint32_t>(Value.Value.Size())}; - if (auto it = m_Index.find(HashKey); it == m_Index.end()) - { - // Previously unknown object - m_Index.insert({HashKey, Loc}); - } - else - { - // TODO: should check if write is idempotent and bail out if it is? - it.value() = Loc; - } + m_WriteCursor = zen::RoundUp(m_WriteCursor + Loc.Size, 16); - m_SlogFile.Append({.Key = HashKey, .Location = Loc}); - m_SobsFile.Write(Value.Value.Data(), Loc.Size, Loc.Offset); + if (auto it = m_Index.find(HashKey); it == m_Index.end()) + { + // Previously unknown object + m_Index.insert({HashKey, Loc}); + } + else + { + // TODO: should check if write is idempotent and bail out if it is? + it.value() = Loc; + } - return; + m_SlogFile.Append({.Key = HashKey, .Location = Loc}); + m_SobsFile.Write(Value.Value.Data(), Loc.Size, Loc.Offset()); + } } void @@ -429,6 +461,32 @@ ZenCacheDiskLayer::CacheBucket::PutLargeObject(const zen::IoHash& HashKey, const { zen::ThrowSystemException(hRes, "Failed to finalize file '{}'"_format(zen::WideToUtf8(DataFilePath))); } + + // Update index + + uint64_t EntryFlags = 0; + + if (Value.Value.GetContentType() == ZenContentType::kCbObject) + { + EntryFlags |= DiskLocation::kStructured; + } + + zen::RwLock::ExclusiveLockScope _(m_IndexLock); + + DiskLocation Loc{.OffsetAndFlags = DiskLocation::CombineOffsetAndFlags(0, EntryFlags), .Size = 0}; + + if (auto it = m_Index.find(HashKey); it == m_Index.end()) + { + // Previously unknown object + m_Index.insert({HashKey, Loc}); + } + else + { + // TODO: should check if write is idempotent and bail out if it is? + it.value() = Loc; + } + + m_SlogFile.Append({.Key = HashKey, .Location = Loc}); } ////////////////////////////////////////////////////////////////////////// |