From 100c8f966b1c5b2fb190748f0177600562d1c5fe Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 7 Dec 2022 11:21:41 +0100 Subject: optimizations (#200) * Use direct file read and direct buffer allocation for small IoBuffer materalization * Reduce range of materialized data in CompositeBuffer reading CompressedBuffer header reading often only need a small part and not the whole file * reduce lock contention in IoBuffer::Materialize * Reduce parsing of compressed headers Validate header type at decompression * faster CreateDirectories - start from leaf going up and recurse back * optimized BufferHeader::IsValid * Add ValidateCompressedHeader to use when we don't need the actual compressed data Validate that we always get compressed data in CidStore::AddChunk * changelog --- zenserver/cache/structuredcachestore.cpp | 47 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'zenserver/cache/structuredcachestore.cpp') diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index 1f48aaebe..75f845cbf 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -491,7 +491,7 @@ ZenCacheMemoryLayer::CacheBucket::Scrub(ScrubContext& Ctx) std::vector BadHashes; - auto ValidateEntry = [](ZenContentType ContentType, IoBuffer Buffer) { + auto ValidateEntry = [](const IoHash& Hash, ZenContentType ContentType, IoBuffer Buffer) { if (ContentType == ZenContentType::kCbObject) { CbValidateError Error = ValidateCompactBinary(Buffer, CbValidateMode::All); @@ -499,7 +499,13 @@ ZenCacheMemoryLayer::CacheBucket::Scrub(ScrubContext& Ctx) } if (ContentType == ZenContentType::kCompressedBinary) { - if (CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Buffer)); !Compressed) + IoHash RawHash; + uint64_t RawSize; + if (!CompressedBuffer::ValidateCompressedHeader(Buffer, RawHash, RawSize)) + { + return false; + } + if (Hash != RawHash) { return false; } @@ -509,7 +515,7 @@ ZenCacheMemoryLayer::CacheBucket::Scrub(ScrubContext& Ctx) for (auto& Kv : m_CacheMap) { - if (!ValidateEntry(Kv.second.Payload.GetContentType(), Kv.second.Payload)) + if (!ValidateEntry(Kv.first, Kv.second.Payload.GetContentType(), Kv.second.Payload)) { BadHashes.push_back(Kv.first); } @@ -1021,7 +1027,7 @@ ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx) std::vector ChunkLocations; std::vector ChunkIndexToChunkHash; - auto ValidateEntry = [](ZenContentType ContentType, IoBuffer Buffer) { + auto ValidateEntry = [](const IoHash& Hash, ZenContentType ContentType, IoBuffer Buffer) { if (ContentType == ZenContentType::kCbObject) { CbValidateError Error = ValidateCompactBinary(Buffer, CbValidateMode::All); @@ -1029,7 +1035,13 @@ ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx) } if (ContentType == ZenContentType::kCompressedBinary) { - if (CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Buffer)); !Compressed) + IoHash RawHash; + uint64_t RawSize; + if (!CompressedBuffer::ValidateCompressedHeader(Buffer, RawHash, RawSize)) + { + return false; + } + if (RawHash != Hash) { return false; } @@ -1077,7 +1089,7 @@ ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx) BadKeys.push_back(HashKey); continue; } - if (!ValidateEntry(Loc.GetContentType(), Value.Value)) + if (!ValidateEntry(HashKey, Loc.GetContentType(), Value.Value)) { BadKeys.push_back(HashKey); continue; @@ -1108,7 +1120,7 @@ ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx) return; } ZenContentType ContentType = m_Index.at(Hash).Location.GetContentType(); - if (!ValidateEntry(ContentType, Buffer)) + if (!ValidateEntry(Hash, ContentType, Buffer)) { BadKeys.push_back(Hash); return; @@ -1127,7 +1139,7 @@ ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx) return; } ZenContentType ContentType = m_Index.at(Hash).Location.GetContentType(); - if (!ValidateEntry(ContentType, Buffer)) + if (!ValidateEntry(Hash, ContentType, Buffer)) { BadKeys.push_back(Hash); return; @@ -1678,18 +1690,8 @@ ZenCacheDiskLayer::CacheBucket::PutStandaloneCacheValue(const IoHash& HashKey, c DataFile.MoveTemporaryIntoPlace(FsPath, Ec); if (Ec) { - std::filesystem::path ParentPath = FsPath.parent_path(); - if (!std::filesystem::is_directory(ParentPath)) - { - Ec.clear(); - std::filesystem::create_directories(ParentPath, Ec); - if (Ec) - { - throw std::system_error( - Ec, - fmt::format("Failed to create parent directory '{}' for file '{}' for put in '{}'", ParentPath, FsPath, m_BucketDir)); - } - } + CreateDirectories(FsPath.parent_path()); + Ec.clear(); // Try again DataFile.MoveTemporaryIntoPlace(FsPath, Ec); @@ -3100,7 +3102,8 @@ TEST_CASE("z$.scrub") { IoBuffer AttachmentData = CreateBinaryCacheValue(AttachmentSizes[Index]); CompressedBuffer CompressedAttachmentData = CompressedBuffer::Compress(SharedBuffer(AttachmentData)); - Record.AddBinaryAttachment(fmt::format("attachment-{}", Index), IoHash::FromBLAKE3(CompressedAttachmentData.GetRawHash())); + Record.AddBinaryAttachment(fmt::format("attachment-{}", Index), + IoHash::FromBLAKE3(CompressedAttachmentData.DecodeRawHash())); Result.Attachments[Index] = CompressedAttachmentData; } Result.Record = Record.Save().GetBuffer().AsIoBuffer(); @@ -3142,7 +3145,7 @@ TEST_CASE("z$.scrub") Zcs.Put("mybucket", Cid, {.Value = Record.Record}); for (const CompressedBuffer& Attachment : Record.Attachments) { - CidStore.AddChunk(Attachment); + CidStore.AddChunk(Attachment.GetCompressed().Flatten().AsIoBuffer(), IoHash::FromBLAKE3(Attachment.DecodeRawHash())); } } }; -- cgit v1.2.3