aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/cache/cachedisklayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenserver/cache/cachedisklayer.cpp')
-rw-r--r--src/zenserver/cache/cachedisklayer.cpp95
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(); });
}