diff options
| author | Dan Engelbrecht <[email protected]> | 2022-03-23 23:00:52 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2022-03-31 11:29:27 +0200 |
| commit | 3ffb09b9016a84bd8c9b33a8bdd69c9bf1a16a6a (patch) | |
| tree | 9bcf821b79c753f4c61e7a4abf8ed402f936ca05 /zenstore/compactcas.cpp | |
| parent | Use simpler data structures (diff) | |
| download | zen-3ffb09b9016a84bd8c9b33a8bdd69c9bf1a16a6a.tar.xz zen-3ffb09b9016a84bd8c9b33a8bdd69c9bf1a16a6a.zip | |
reduce lock times
Diffstat (limited to 'zenstore/compactcas.cpp')
| -rw-r--r-- | zenstore/compactcas.cpp | 105 |
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; |