diff options
Diffstat (limited to 'src/zenserver/cache/cachedisklayer.cpp')
| -rw-r--r-- | src/zenserver/cache/cachedisklayer.cpp | 113 |
1 files changed, 75 insertions, 38 deletions
diff --git a/src/zenserver/cache/cachedisklayer.cpp b/src/zenserver/cache/cachedisklayer.cpp index 955ab3a04..2c344dd1d 100644 --- a/src/zenserver/cache/cachedisklayer.cpp +++ b/src/zenserver/cache/cachedisklayer.cpp @@ -255,8 +255,8 @@ public: uint64_t GetSidecarSize() const { return m_ManifestEntryCount * sizeof(ManifestData); } void WriteSidecarFile(const std::filesystem::path& SidecarPath, uint64_t SnapshotLogPosition, - ZenCacheDiskLayer::CacheBucket::IndexMap&& Index, - std::vector<AccessTime>&& AccessTimes, + const ZenCacheDiskLayer::CacheBucket::IndexMap& Index, + const std::vector<AccessTime>& AccessTimes, const std::vector<ZenCacheDiskLayer::CacheBucket::BucketPayload>& Payloads, const std::vector<ZenCacheDiskLayer::CacheBucket::BucketMetaData>& MetaDatas); bool ReadSidecarFile(ZenCacheDiskLayer::CacheBucket& Bucket, @@ -265,11 +265,11 @@ public: std::vector<AccessTime>& AccessTimes, std::vector<ZenCacheDiskLayer::CacheBucket::BucketPayload>& Payloads); - IoBuffer MakeManifest(const Oid& BucketId, - ZenCacheDiskLayer::CacheBucket::IndexMap&& Index, - std::vector<AccessTime>&& AccessTimes, - const std::vector<ZenCacheDiskLayer::CacheBucket::BucketPayload>& Payloads, - const std::vector<ZenCacheDiskLayer::CacheBucket::BucketMetaData>& MetaDatas); + IoBuffer MakeManifest(const Oid& BucketId, + ZenCacheDiskLayer::CacheBucket::IndexMap&& Index, + std::vector<AccessTime>&& AccessTimes, + std::vector<ZenCacheDiskLayer::CacheBucket::BucketPayload>&& Payloads, + std::vector<ZenCacheDiskLayer::CacheBucket::BucketMetaData>&& MetaDatas); CbObject Manifest; @@ -399,11 +399,11 @@ BucketManifestSerializer::GenerateNewManifest(std::filesystem::path ManifestPath } IoBuffer -BucketManifestSerializer::MakeManifest(const Oid& BucketId, - ZenCacheDiskLayer::CacheBucket::IndexMap&& Index, - std::vector<AccessTime>&& AccessTimes, - const std::vector<ZenCacheDiskLayer::CacheBucket::BucketPayload>& Payloads, - const std::vector<ZenCacheDiskLayer::CacheBucket::BucketMetaData>& MetaDatas) +BucketManifestSerializer::MakeManifest(const Oid& BucketId, + ZenCacheDiskLayer::CacheBucket::IndexMap&& Index, + std::vector<AccessTime>&& AccessTimes, + std::vector<ZenCacheDiskLayer::CacheBucket::BucketPayload>&& Payloads, + std::vector<ZenCacheDiskLayer::CacheBucket::BucketMetaData>&& MetaDatas) { using namespace std::literals; @@ -579,8 +579,8 @@ BucketManifestSerializer::ReadSidecarFile(ZenCacheDiskLayer::CacheBucket& void BucketManifestSerializer::WriteSidecarFile(const std::filesystem::path& SidecarPath, uint64_t SnapshotLogPosition, - ZenCacheDiskLayer::CacheBucket::IndexMap&& Index, - std::vector<AccessTime>&& AccessTimes, + const ZenCacheDiskLayer::CacheBucket::IndexMap& Index, + const std::vector<AccessTime>& AccessTimes, const std::vector<ZenCacheDiskLayer::CacheBucket::BucketPayload>& Payloads, const std::vector<ZenCacheDiskLayer::CacheBucket::BucketMetaData>& MetaDatas) { @@ -605,8 +605,11 @@ BucketManifestSerializer::WriteSidecarFile(const std::filesystem::path& { uint64_t WriteOffset = sizeof Header; - BasicFileWriter SidecarWriter(SidecarFile, 128 * 1024); + // BasicFileWriter SidecarWriter(SidecarFile, 128 * 1024); + std::vector<ManifestData> ManifestDataBuffer; + const size_t MaxManifestDataBufferCount = Min(Index.size(), 4096u); // 256 Kb + ManifestDataBuffer.reserve(MaxManifestDataBufferCount); for (auto& Kv : Index) { const IoHash& Key = Kv.first; @@ -621,12 +624,24 @@ BucketManifestSerializer::WriteSidecarFile(const std::filesystem::path& RawSize = MetaDatas[MetaIndex].RawSize; } - ManifestData ManifestEntry = - {.Key = Key, .Timestamp = AccessTimes[PlIndex], .RawHash = RawHash, .Padding_0 = 0, .RawSize = RawSize, .Padding_1 = 0}; - - SidecarWriter.Write(&ManifestEntry, sizeof ManifestEntry, WriteOffset); - - WriteOffset += sizeof ManifestEntry; + ManifestDataBuffer.emplace_back(ManifestData{.Key = Key, + .Timestamp = AccessTimes[PlIndex], + .RawHash = RawHash, + .Padding_0 = 0, + .RawSize = RawSize, + .Padding_1 = 0}); + if (ManifestDataBuffer.size() == MaxManifestDataBufferCount) + { + const uint64_t WriteSize = sizeof(ManifestData) * ManifestDataBuffer.size(); + SidecarFile.Write(ManifestDataBuffer.data(), WriteSize, WriteOffset); + WriteOffset += WriteSize; + ManifestDataBuffer.clear(); + ManifestDataBuffer.reserve(MaxManifestDataBufferCount); + } + } + if (ManifestDataBuffer.size() > 0) + { + SidecarFile.Write(ManifestDataBuffer.data(), sizeof(ManifestData) * ManifestDataBuffer.size(), WriteOffset); } } @@ -1380,12 +1395,12 @@ ZenCacheDiskLayer::CacheBucket::SaveSnapshot(const std::function<uint64_t()>& Cl { try { - bool UseLegacyScheme = false; - uint64_t SidecarSize = 0; + bool UseLegacyScheme = false; IoBuffer Buffer; BucketManifestSerializer ManifestWriter; + if (UseLegacyScheme) { std::vector<AccessTime> AccessTimes; std::vector<BucketPayload> Payloads; @@ -1403,16 +1418,41 @@ ZenCacheDiskLayer::CacheBucket::SaveSnapshot(const std::function<uint64_t()>& Cl MetaDatas = m_MetaDatas; } - if (UseLegacyScheme) + Buffer = ManifestWriter.MakeManifest(m_BucketId, + std::move(Index), + std::move(AccessTimes), + std::move(Payloads), + std::move(MetaDatas)); + const uint64_t RequiredSpace = Buffer.GetSize() + 1024 * 512; + + std::error_code Error; + DiskSpace Space = DiskSpaceInfo(m_BucketDir, Error); + if (Error) { - Buffer = ManifestWriter.MakeManifest(m_BucketId, std::move(Index), std::move(AccessTimes), Payloads, MetaDatas); + ZEN_WARN("get disk space in '{}' FAILED, reason: '{}'", m_BucketDir, Error.message()); + return; } - else + bool EnoughSpace = Space.Free >= RequiredSpace; + if (!EnoughSpace) { - const uint64_t EntryCount = Index.size(); - Buffer = ManifestWriter.MakeSidecarManifest(m_BucketId, EntryCount); - SidecarSize = ManifestWriter.GetSidecarSize(); + uint64_t ReclaimedSpace = ClaimDiskReserveFunc(); + EnoughSpace = (Space.Free + ReclaimedSpace) >= RequiredSpace; } + if (!EnoughSpace) + { + ZEN_WARN("not enough free disk space in '{}'. FAILED to save manifest of size {}", + m_BucketDir, + NiceBytes(Buffer.GetSize())); + return; + } + } + else + { + RwLock::SharedLockScope IndexLock(m_IndexLock); + WriteIndexSnapshot(); + const uint64_t EntryCount = m_Index.size(); + Buffer = ManifestWriter.MakeSidecarManifest(m_BucketId, EntryCount); + uint64_t SidecarSize = ManifestWriter.GetSidecarSize(); const uint64_t RequiredSpace = SidecarSize + Buffer.GetSize() + 1024 * 512; @@ -1437,15 +1477,12 @@ ZenCacheDiskLayer::CacheBucket::SaveSnapshot(const std::function<uint64_t()>& Cl return; } - if (!UseLegacyScheme) - { - ManifestWriter.WriteSidecarFile(GetMetaPath(m_BucketDir, m_BucketName), - m_LogFlushPosition, - std::move(Index), - std::move(AccessTimes), - Payloads, - MetaDatas); - } + ManifestWriter.WriteSidecarFile(GetMetaPath(m_BucketDir, m_BucketName), + m_LogFlushPosition, + m_Index, + m_AccessTimes, + m_Payloads, + m_MetaDatas); } std::filesystem::path ManifestPath = GetManifestPath(m_BucketDir, m_BucketName); |