aboutsummaryrefslogtreecommitdiff
path: root/zenstore/compactcas.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-03-23 23:00:52 +0100
committerDan Engelbrecht <[email protected]>2022-03-31 11:29:27 +0200
commit3ffb09b9016a84bd8c9b33a8bdd69c9bf1a16a6a (patch)
tree9bcf821b79c753f4c61e7a4abf8ed402f936ca05 /zenstore/compactcas.cpp
parentUse simpler data structures (diff)
downloadzen-3ffb09b9016a84bd8c9b33a8bdd69c9bf1a16a6a.tar.xz
zen-3ffb09b9016a84bd8c9b33a8bdd69c9bf1a16a6a.zip
reduce lock times
Diffstat (limited to 'zenstore/compactcas.cpp')
-rw-r--r--zenstore/compactcas.cpp105
1 files changed, 52 insertions, 53 deletions
diff --git a/zenstore/compactcas.cpp b/zenstore/compactcas.cpp
index fcb3efd5f..053d441b0 100644
--- a/zenstore/compactcas.cpp
+++ b/zenstore/compactcas.cpp
@@ -116,9 +116,7 @@ CasContainerStrategy::InsertChunk(const void* ChunkData, size_t ChunkSize, const
{
RwLock::SharedLockScope _l(m_LocationMapLock);
- auto KeyIt = m_LocationMap.find(ChunkHash);
-
- if (KeyIt != m_LocationMap.end())
+ if (m_LocationMap.contains(ChunkHash))
{
return CasStore::InsertResult{.New = false};
}
@@ -164,13 +162,13 @@ CasContainerStrategy::InsertChunk(const void* ChunkData, size_t ChunkSize, const
WriteBlock->Write(ChunkData, ChunkSize, InsertOffset);
- const BlockStoreLocation Location(WriteBlockIndex, InsertOffset, ChunkSize);
- CasDiskIndexEntry IndexEntry{.Key = ChunkHash, .Location = BlockStoreDiskLocation(Location, m_PayloadAlignment)};
+ BlockStoreDiskLocation Location({.BlockIndex = WriteBlockIndex, .Offset = InsertOffset, .Size = ChunkSize}, m_PayloadAlignment);
+ const CasDiskIndexEntry IndexEntry{.Key = ChunkHash, .Location = Location};
m_TotalSize.fetch_add(static_cast<uint64_t>(ChunkSize));
{
RwLock::ExclusiveLockScope __(m_LocationMapLock);
- m_LocationMap.emplace(ChunkHash, BlockStoreDiskLocation(Location, m_PayloadAlignment));
+ m_LocationMap.emplace(ChunkHash, Location);
m_CasLog.Append(IndexEntry);
}
@@ -234,13 +232,7 @@ CasContainerStrategy::Flush()
if (m_CurrentInsertOffset > 0)
{
uint32_t WriteBlockIndex = m_WriteBlockIndex.load(std::memory_order_acquire);
- auto WriteBlock = m_WriteBlock;
- WriteBlockIndex++;
- while (m_ChunkBlocks.contains(WriteBlockIndex))
- {
- WriteBlockIndex = (WriteBlockIndex + 1) & BlockStoreDiskLocation::MaxBlockIndex;
- }
- WriteBlock->Flush();
+ WriteBlockIndex = (WriteBlockIndex + 1) & BlockStoreDiskLocation::MaxBlockIndex;
m_WriteBlock.reset();
m_WriteBlockIndex.store(WriteBlockIndex, std::memory_order_release);
m_CurrentInsertOffset = 0;
@@ -252,9 +244,6 @@ CasContainerStrategy::Flush()
void
CasContainerStrategy::Scrub(ScrubContext& Ctx)
{
- const uint64_t WindowSize = 4 * 1024 * 1024;
-
- std::vector<CasDiskIndexEntry> BigChunks;
std::vector<CasDiskIndexEntry> BadChunks;
// We do a read sweep through the payloads file and validate
@@ -263,8 +252,10 @@ CasContainerStrategy::Scrub(ScrubContext& Ctx)
// pass. An alternative strategy would be to use memory mapping.
{
- IoBuffer ReadBuffer{WindowSize};
- void* BufferBase = ReadBuffer.MutableData();
+ std::vector<CasDiskIndexEntry> BigChunks;
+ const uint64_t WindowSize = 4 * 1024 * 1024;
+ IoBuffer ReadBuffer{WindowSize};
+ void* BufferBase = ReadBuffer.MutableData();
RwLock::SharedLockScope _(m_InsertLock); // TODO: Refactor so we don't have to keep m_InsertLock all the time?
RwLock::SharedLockScope __(m_LocationMapLock);
@@ -348,8 +339,8 @@ CasContainerStrategy::Scrub(ScrubContext& Ctx)
for (const CasDiskIndexEntry& Entry : BadChunks)
{
BadChunkHashes.push_back(Entry.Key);
- m_CasLog.Append({.Key = Entry.Key, .Location = Entry.Location, .Flags = CasDiskIndexEntry::kTombstone});
m_LocationMap.erase(Entry.Key);
+ m_CasLog.Append({.Key = Entry.Key, .Location = Entry.Location, .Flags = CasDiskIndexEntry::kTombstone});
}
}
@@ -475,35 +466,42 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
TotalChunkHashes.reserve(TotalChunkCount);
for (const auto& Entry : LocationMap)
{
- uint32_t BlockIndex = Entry.second.GetBlockIndex();
- if (static_cast<uint64_t>(BlockIndex) == ExcludeBlockIndex)
- {
- continue;
- }
TotalChunkHashes.push_back(Entry.first);
- if (BlockIndexToChunkMapIndex.contains(BlockIndex))
- {
- continue;
- }
- BlockIndexToChunkMapIndex[BlockIndex] = KeepChunks.size();
- KeepChunks.resize(KeepChunks.size() + 1);
- KeepChunks.back().reserve(GuesstimateCountPerBlock);
- DeleteChunks.resize(DeleteChunks.size() + 1);
- DeleteChunks.back().reserve(GuesstimateCountPerBlock);
}
uint64_t DeleteCount = 0;
uint64_t NewTotalSize = 0;
GcCtx.FilterCas(TotalChunkHashes, [&](const IoHash& ChunkHash, bool Keep) {
- auto KeyIt = LocationMap.find(ChunkHash);
- uint32_t BlockIndex = KeyIt->second.GetBlockIndex();
- size_t ChunkMapIndex = BlockIndexToChunkMapIndex[BlockIndex];
+ auto KeyIt = LocationMap.find(ChunkHash);
+ const BlockStoreDiskLocation& Location = KeyIt->second;
+ uint32_t BlockIndex = Location.GetBlockIndex();
+
+ if (static_cast<uint64_t>(BlockIndex) == ExcludeBlockIndex)
+ {
+ return;
+ }
+
+ auto BlockIndexPtr = BlockIndexToChunkMapIndex.find(BlockIndex);
+ size_t ChunkMapIndex = 0;
+ if (BlockIndexPtr == BlockIndexToChunkMapIndex.end())
+ {
+ ChunkMapIndex = KeepChunks.size();
+ BlockIndexToChunkMapIndex[BlockIndex] = ChunkMapIndex;
+ KeepChunks.resize(ChunkMapIndex + 1);
+ KeepChunks.back().reserve(GuesstimateCountPerBlock);
+ DeleteChunks.resize(ChunkMapIndex + 1);
+ DeleteChunks.back().reserve(GuesstimateCountPerBlock);
+ }
+ else
+ {
+ ChunkMapIndex = BlockIndexPtr->second;
+ }
if (Keep)
{
auto& ChunkMap = KeepChunks[ChunkMapIndex];
ChunkMap.push_back(ChunkHash);
- NewTotalSize += KeyIt->second.GetSize();
+ NewTotalSize += Location.GetSize();
}
else
{
@@ -551,37 +549,38 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
for (uint32_t BlockIndex : BlocksToReWrite)
{
const size_t ChunkMapIndex = BlockIndexToChunkMapIndex[BlockIndex];
- const auto& KeepMap = KeepChunks[ChunkMapIndex];
+
+ std::shared_ptr<BlockStoreFile> OldBlockFile;
+ {
+ RwLock::SharedLockScope _i(m_LocationMapLock);
+ OldBlockFile = m_ChunkBlocks[BlockIndex];
+ }
+
+ const auto& KeepMap = KeepChunks[ChunkMapIndex];
if (KeepMap.empty())
{
- std::shared_ptr<BlockStoreFile> BlockFile;
- const auto& DeleteMap = DeleteChunks[ChunkMapIndex];
- auto LogEntries = MakeCasDiskEntries({}, DeleteMap);
+ const auto& DeleteMap = DeleteChunks[ChunkMapIndex];
+ auto LogEntries = MakeCasDiskEntries({}, DeleteMap);
{
RwLock::ExclusiveLockScope _i(m_LocationMapLock);
Stopwatch Timer;
const auto TimerGuard = MakeGuard([&Timer, &ReadBlockTimeUs] { ReadBlockTimeUs += Timer.GetElapsedTimeUs(); });
UpdateLocations(LogEntries);
m_CasLog.Append(LogEntries);
- m_ChunkBlocks[BlockIndex].swap(BlockFile);
+ m_ChunkBlocks[BlockIndex].reset();
}
DeletedChunks.insert(DeletedChunks.end(), DeleteMap.begin(), DeleteMap.end());
ZEN_DEBUG("marking cas store file for delete {}, block {}", m_ContainerBaseName, std::to_string(BlockIndex));
std::error_code Ec;
- BlockFile->MarkAsDeleteOnClose(Ec);
+ OldBlockFile->MarkAsDeleteOnClose(Ec);
if (Ec)
{
- ZEN_WARN("Failed to flag file '{}' for deletion: '{}'", BlockFile->GetPath(), Ec.message());
+ ZEN_WARN("Failed to flag file '{}' for deletion: '{}'", OldBlockFile->GetPath(), Ec.message());
}
continue;
}
- std::shared_ptr<BlockStoreFile> OldBlockFile;
- {
- RwLock::SharedLockScope _i(m_LocationMapLock);
- OldBlockFile = m_ChunkBlocks[BlockIndex];
- OldBlockFile->Open();
- }
+ OldBlockFile->Open();
std::vector<uint8_t> Chunk;
for (const IoHash& ChunkHash : KeepMap)
@@ -1322,7 +1321,7 @@ TEST_CASE("compactcas.compact.totalsize")
std::random_device rd;
std::mt19937 g(rd());
-// for (uint32_t i = 0; i < 100; ++i)
+ // for (uint32_t i = 0; i < 100; ++i)
{
ScopedTemporaryDirectory TempDir;
@@ -1425,7 +1424,7 @@ TEST_CASE("compactcas.gc.removefile")
TEST_CASE("compactcas.gc.compact")
{
-// for (uint32_t i = 0; i < 100; ++i)
+ // for (uint32_t i = 0; i < 100; ++i)
{
ScopedTemporaryDirectory TempDir;
@@ -1892,7 +1891,7 @@ TEST_CASE("compactcas.legacyconversion")
TEST_CASE("compactcas.threadedinsert") // * doctest::skip(true))
{
-// for (uint32_t i = 0; i < 100; ++i)
+ // for (uint32_t i = 0; i < 100; ++i)
{
ScopedTemporaryDirectory TempDir;