diff options
Diffstat (limited to 'src/zenserver/cache/cachedisklayer.cpp')
| -rw-r--r-- | src/zenserver/cache/cachedisklayer.cpp | 95 |
1 files changed, 51 insertions, 44 deletions
diff --git a/src/zenserver/cache/cachedisklayer.cpp b/src/zenserver/cache/cachedisklayer.cpp index fafc6bbee..894676d6a 100644 --- a/src/zenserver/cache/cachedisklayer.cpp +++ b/src/zenserver/cache/cachedisklayer.cpp @@ -860,7 +860,7 @@ ZenCacheDiskLayer::CacheBucket::Flush() Payloads = m_Payloads; AccessTimes = m_AccessTimes; } - SaveManifest(MakeManifest(std::move(Index), std::move(AccessTimes), std::move(Payloads))); + SaveManifest(MakeManifest(std::move(Index), std::move(AccessTimes), Payloads)); } void @@ -878,7 +878,9 @@ ZenCacheDiskLayer::CacheBucket::SaveManifest(CbObject&& Manifest) } CbObject -ZenCacheDiskLayer::CacheBucket::MakeManifest(IndexMap&& Index, std::vector<AccessTime>&& AccessTimes, std::vector<BucketPayload>&& Payloads) +ZenCacheDiskLayer::CacheBucket::MakeManifest(IndexMap&& Index, + std::vector<AccessTime>&& AccessTimes, + const std::vector<BucketPayload>& Payloads) { using namespace std::literals; @@ -1405,7 +1407,7 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) Payloads = m_Payloads; AccessTimes = m_AccessTimes; } - SaveManifest(MakeManifest(std::move(Index), std::move(AccessTimes), std::move(Payloads))); + SaveManifest(MakeManifest(std::move(Index), std::move(AccessTimes), Payloads)); }); m_SlogFile.Flush(); @@ -1464,6 +1466,7 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) std::vector<DiskIndexEntry> ExpiredStandaloneEntries; IndexMap Index; + std::vector<BucketPayload> Payloads; BlockStore::ReclaimSnapshotState BlockStoreState; { bool Expected = false; @@ -1474,8 +1477,7 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) } auto FlushingGuard = MakeGuard([&] { m_IsFlushing.store(false); }); - std::vector<AccessTime> AccessTimes; - std::vector<BucketPayload> Payloads; + std::vector<AccessTime> AccessTimes; { ZEN_TRACE_CPU("Z$::Disk::Bucket::CollectGarbage::State"); RwLock::SharedLockScope IndexLock(m_IndexLock); @@ -1502,7 +1504,7 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) { if (auto It = Index.find(Key); It != Index.end()) { - const BucketPayload& Payload = m_Payloads[It->second]; + const BucketPayload& Payload = Payloads[It->second]; DiskIndexEntry Entry = {.Key = It->first, .Location = Payload.Location}; if (Entry.Location.Flags & DiskLocation::kStandaloneFile) { @@ -1522,7 +1524,7 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) m_SlogFile.Append(ExpiredStandaloneEntries); } } - SaveManifest(MakeManifest(std::move(Index), std::move(AccessTimes), std::move(Payloads))); + SaveManifest(MakeManifest(std::move(Index), std::move(AccessTimes), Payloads)); } if (GcCtx.IsDeletionMode()) @@ -1600,15 +1602,17 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) std::vector<IoHash> TotalChunkHashes; TotalChunkHashes.reserve(TotalChunkCount); - for (const auto& Entry : Index) { - const DiskLocation& Location = m_Payloads[Entry.second].Location; - - if (Location.Flags & DiskLocation::kStandaloneFile) + for (const auto& Entry : Index) { - continue; + const DiskLocation& Location = Payloads[Entry.second].Location; + + if (Location.Flags & DiskLocation::kStandaloneFile) + { + continue; + } + TotalChunkHashes.push_back(Entry.first); } - TotalChunkHashes.push_back(Entry.first); } if (TotalChunkHashes.empty()) @@ -1626,7 +1630,7 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) GcCtx.FilterCids(TotalChunkHashes, [&](const IoHash& ChunkHash, bool Keep) { auto KeyIt = Index.find(ChunkHash); - const DiskLocation& DiskLocation = m_Payloads[KeyIt->second].Location; + const DiskLocation& DiskLocation = Payloads[KeyIt->second].Location; BlockStoreLocation Location = DiskLocation.GetBlockLocation(m_PayloadAlignment); size_t ChunkIndex = ChunkLocations.size(); ChunkLocations.push_back(Location); @@ -1661,48 +1665,51 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) [&](const BlockStore::MovedChunksArray& MovedChunks, const BlockStore::ChunkIndexArray& RemovedChunks) { std::vector<DiskIndexEntry> LogEntries; LogEntries.reserve(MovedChunks.size() + RemovedChunks.size()); - for (const auto& Entry : MovedChunks) - { - size_t ChunkIndex = Entry.first; - const BlockStoreLocation& NewLocation = Entry.second; - const IoHash& ChunkHash = ChunkIndexToChunkHash[ChunkIndex]; - const BucketPayload& OldPayload = m_Payloads[Index[ChunkHash]]; - const DiskLocation& OldDiskLocation = OldPayload.Location; - LogEntries.push_back( - {.Key = ChunkHash, .Location = DiskLocation(NewLocation, m_PayloadAlignment, OldDiskLocation.GetFlags())}); - } - for (const size_t ChunkIndex : RemovedChunks) - { - const IoHash& ChunkHash = ChunkIndexToChunkHash[ChunkIndex]; - const BucketPayload& OldPayload = m_Payloads[Index[ChunkHash]]; - const DiskLocation& OldDiskLocation = OldPayload.Location; - LogEntries.push_back({.Key = ChunkHash, - .Location = DiskLocation(OldDiskLocation.GetBlockLocation(m_PayloadAlignment), - m_PayloadAlignment, - OldDiskLocation.GetFlags() | DiskLocation::kTombStone)}); - DeletedChunks.insert(ChunkHash); - } - - m_SlogFile.Append(LogEntries); - m_SlogFile.Flush(); { RwLock::ExclusiveLockScope __(m_IndexLock); Stopwatch Timer; const auto ____ = MakeGuard([&] { uint64_t ElapsedUs = Timer.GetElapsedTimeUs(); - ReadBlockTimeUs += ElapsedUs; - ReadBlockLongestTimeUs = std::max(ElapsedUs, ReadBlockLongestTimeUs); + WriteBlockTimeUs += ElapsedUs; + WriteBlockLongestTimeUs = std::max(ElapsedUs, WriteBlockLongestTimeUs); }); - for (const DiskIndexEntry& Entry : LogEntries) + for (const auto& Entry : MovedChunks) { - if (Entry.Location.GetFlags() & DiskLocation::kTombStone) + size_t ChunkIndex = Entry.first; + const BlockStoreLocation& NewLocation = Entry.second; + const IoHash& ChunkHash = ChunkIndexToChunkHash[ChunkIndex]; + size_t PayloadIndex = m_Index[ChunkHash]; + BucketPayload& Payload = m_Payloads[PayloadIndex]; + if (Payloads[Index[ChunkHash]].Location != m_Payloads[PayloadIndex].Location) { - m_Index.erase(Entry.Key); + // Entry has been updated while GC was running, ignore the move continue; } - m_Payloads[m_Index[Entry.Key]].Location = Entry.Location; + Payload.Location = DiskLocation(NewLocation, m_PayloadAlignment, Payload.Location.GetFlags()); + LogEntries.push_back({.Key = ChunkHash, .Location = Payload.Location}); + } + for (const size_t ChunkIndex : RemovedChunks) + { + const IoHash& ChunkHash = ChunkIndexToChunkHash[ChunkIndex]; + size_t PayloadIndex = m_Index[ChunkHash]; + const BucketPayload& Payload = m_Payloads[PayloadIndex]; + if (Payloads[Index[ChunkHash]].Location != Payload.Location) + { + // Entry has been updated while GC was running, ignore the delete + continue; + } + const DiskLocation& OldDiskLocation = Payload.Location; + LogEntries.push_back({.Key = ChunkHash, + .Location = DiskLocation(OldDiskLocation.GetBlockLocation(m_PayloadAlignment), + m_PayloadAlignment, + OldDiskLocation.GetFlags() | DiskLocation::kTombStone)}); + m_Index.erase(ChunkHash); + DeletedChunks.insert(ChunkHash); } } + + m_SlogFile.Append(LogEntries); + m_SlogFile.Flush(); }, [&]() { return GcCtx.CollectSmallObjects(); }); } |