aboutsummaryrefslogtreecommitdiff
path: root/src/zenstore/blockstore.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-10-27 11:17:36 +0100
committerGitHub Enterprise <[email protected]>2025-10-27 11:17:36 +0100
commit91e085f7caa9c384d8dab781e9b29ce0d70f6626 (patch)
treec0ced6e0e825b5074d3012b037fc20847e22a513 /src/zenstore/blockstore.cpp
parentuse already built lookup when verifying folder (#615) (diff)
downloadzen-91e085f7caa9c384d8dab781e9b29ce0d70f6626.tar.xz
zen-91e085f7caa9c384d8dab781e9b29ce0d70f6626.zip
optimize blockstore flush (#614)
* rework block store block flushing to only happen once at end of block write outside of locks * fix warning at startup if no gc.dlog file exists
Diffstat (limited to 'src/zenstore/blockstore.cpp')
-rw-r--r--src/zenstore/blockstore.cpp83
1 files changed, 55 insertions, 28 deletions
diff --git a/src/zenstore/blockstore.cpp b/src/zenstore/blockstore.cpp
index 337a5f8e0..86aa234c3 100644
--- a/src/zenstore/blockstore.cpp
+++ b/src/zenstore/blockstore.cpp
@@ -177,19 +177,10 @@ BlockStoreFile::Write(const void* Data, uint64_t Size, uint64_t FileOffset)
}
void
-BlockStoreFile::Flush(uint64_t FinalSize)
+BlockStoreFile::Flush()
{
ZEN_TRACE_CPU("BlockStoreFile::Flush");
m_File.Flush();
- if (FinalSize != (uint64_t)-1)
- {
- ZEN_ASSERT(FinalSize <= m_IoBuffer.GetSize());
- uint64_t ExpectedSize = 0;
- while (!m_CachedFileSize.compare_exchange_weak(ExpectedSize, FinalSize))
- {
- ZEN_ASSERT(ExpectedSize <= FinalSize);
- }
- }
}
BasicFile&
@@ -568,6 +559,42 @@ BlockStore::GetFreeBlockIndex(uint32_t ProbeIndex, RwLock::ExclusiveLockScope&,
}
void
+BlockStore::AddActiveWriteBlock(RwLock::ExclusiveLockScope& Lock, uint32_t BlockIndex)
+{
+ ZEN_UNUSED(Lock);
+ m_ActiveWriteBlocks.push_back(BlockIndex);
+}
+
+void
+BlockStore::RemoveActiveWriteBlock(uint32_t BlockIndex)
+{
+ eastl::fixed_vector<Ref<BlockStoreFile>, 2> FlushBlocks;
+ {
+ RwLock::ExclusiveLockScope _(m_InsertLock);
+ m_ActiveWriteBlocks.erase(std::find(m_ActiveWriteBlocks.begin(), m_ActiveWriteBlocks.end(), BlockIndex));
+ for (auto It = m_BlocksToFlush.begin(); It != m_BlocksToFlush.end();)
+ {
+ const uint32_t FlushBlockIndex = *It;
+ if (std::find(m_ActiveWriteBlocks.begin(), m_ActiveWriteBlocks.end(), FlushBlockIndex) == m_ActiveWriteBlocks.end())
+ {
+ FlushBlocks.push_back(m_ChunkBlocks[FlushBlockIndex]);
+ ZEN_DEBUG("Flushing block {} at '{}'", FlushBlockIndex, GetBlockPath(m_BlocksBasePath, FlushBlockIndex));
+ It = m_BlocksToFlush.erase(It);
+ }
+ else
+ {
+ It++;
+ }
+ }
+ }
+ for (Ref<BlockStoreFile>& FlushBlock : FlushBlocks)
+ {
+ FlushBlock->Flush();
+ FlushBlock = nullptr;
+ }
+}
+
+void
BlockStore::WriteChunk(const void* Data, uint64_t Size, uint32_t Alignment, const WriteChunkCallback& Callback)
{
ZEN_MEMSCOPE(GetBlocksTag());
@@ -589,10 +616,8 @@ BlockStore::WriteChunk(const void* Data, uint64_t Size, uint32_t Alignment, cons
{
if (m_WriteBlock)
{
- m_WriteBlock->Flush(m_CurrentInsertOffset);
- m_WriteBlock = nullptr;
+ m_BlocksToFlush.push_back(WriteBlockIndex);
}
-
WriteBlockIndex += IsWriting ? 1 : 0;
std::filesystem::path BlockPath;
WriteBlockIndex = GetFreeBlockIndex(WriteBlockIndex, InsertLock, BlockPath);
@@ -604,6 +629,8 @@ BlockStore::WriteChunk(const void* Data, uint64_t Size, uint32_t Alignment, cons
Ref<BlockStoreFile> NewBlockFile(new BlockStoreFile(BlockPath));
NewBlockFile->Create(m_MaxBlockSize);
+ ZEN_DEBUG("Created block {} at '{}'", WriteBlockIndex, BlockPath);
+
m_ChunkBlocks[WriteBlockIndex] = NewBlockFile;
m_WriteBlock = NewBlockFile;
m_WriteBlockIndex.store(WriteBlockIndex, std::memory_order_release);
@@ -613,12 +640,10 @@ BlockStore::WriteChunk(const void* Data, uint64_t Size, uint32_t Alignment, cons
uint32_t AlignedWriteSize = AlignedInsertOffset - m_CurrentInsertOffset + ChunkSize;
m_CurrentInsertOffset = AlignedInsertOffset + ChunkSize;
Ref<BlockStoreFile> WriteBlock = m_WriteBlock;
- m_ActiveWriteBlocks.push_back(WriteBlockIndex);
+ AddActiveWriteBlock(InsertLock, WriteBlockIndex);
InsertLock.ReleaseNow();
- auto _ = MakeGuard([this, WriteBlockIndex]() {
- RwLock::ExclusiveLockScope _(m_InsertLock);
- m_ActiveWriteBlocks.erase(std::find(m_ActiveWriteBlocks.begin(), m_ActiveWriteBlocks.end(), WriteBlockIndex));
- });
+
+ auto _ = MakeGuard([this, WriteBlockIndex]() { RemoveActiveWriteBlock(WriteBlockIndex); });
WriteBlock->Write(Data, ChunkSize, AlignedInsertOffset);
m_TotalSize.fetch_add(AlignedWriteSize, std::memory_order::relaxed);
@@ -662,6 +687,10 @@ BlockStore::WriteChunks(std::span<const IoBuffer> Datas, uint32_t Alignment, con
uint32_t AlignedInsertOffset = RoundUp(m_CurrentInsertOffset, Alignment);
if ((!m_WriteBlock) || ((AlignedInsertOffset + RangeSize) > m_MaxBlockSize))
{
+ if (m_WriteBlock)
+ {
+ m_BlocksToFlush.push_back(WriteBlockIndex);
+ }
std::filesystem::path BlockPath;
WriteBlockIndex = GetFreeBlockIndex(WriteBlockIndex, InsertLock, BlockPath);
if (WriteBlockIndex == (uint32_t)m_MaxBlockCount)
@@ -671,6 +700,8 @@ BlockStore::WriteChunks(std::span<const IoBuffer> Datas, uint32_t Alignment, con
Ref<BlockStoreFile> NewBlockFile(new BlockStoreFile(BlockPath));
NewBlockFile->Create(m_MaxBlockSize);
+ ZEN_DEBUG("Created block {} at '{}'", WriteBlockIndex, BlockPath);
+
m_ChunkBlocks[WriteBlockIndex] = NewBlockFile;
m_WriteBlock = NewBlockFile;
m_WriteBlockIndex.store(WriteBlockIndex, std::memory_order_release);
@@ -689,12 +720,10 @@ BlockStore::WriteChunks(std::span<const IoBuffer> Datas, uint32_t Alignment, con
}
m_CurrentInsertOffset = AlignedInsertOffset + RangeSize;
Ref<BlockStoreFile> WriteBlock = m_WriteBlock;
- m_ActiveWriteBlocks.push_back(WriteBlockIndex);
+ AddActiveWriteBlock(InsertLock, WriteBlockIndex);
InsertLock.ReleaseNow();
- auto _ = MakeGuard([this, WriteBlockIndex]() {
- RwLock::ExclusiveLockScope _(m_InsertLock);
- m_ActiveWriteBlocks.erase(std::find(m_ActiveWriteBlocks.begin(), m_ActiveWriteBlocks.end(), WriteBlockIndex));
- });
+
+ auto _ = MakeGuard([this, WriteBlockIndex]() { RemoveActiveWriteBlock(WriteBlockIndex); });
{
MutableMemoryView WriteBuffer(Buffer.data(), RangeSize);
@@ -784,7 +813,7 @@ BlockStore::Flush(bool ForceNewBlock)
{
if (m_WriteBlock)
{
- m_WriteBlock->Flush(m_CurrentInsertOffset);
+ m_WriteBlock->Flush();
}
m_WriteBlock = nullptr;
m_CurrentInsertOffset = 0;
@@ -1185,7 +1214,7 @@ BlockStore::CompactBlocks(const BlockStoreCompactState& CompactState,
if (NewBlockFile)
{
ZEN_ASSERT_SLOW(NewBlockFile->IsOpen());
- NewBlockFile->Flush(WriteOffset);
+ NewBlockFile->Flush();
uint64_t NewBlockSize = NewBlockFile->FileSize();
MovedSize += NewBlockSize;
NewBlockFile = nullptr;
@@ -1322,7 +1351,7 @@ BlockStore::CompactBlocks(const BlockStoreCompactState& CompactState,
if (NewBlockFile)
{
ZEN_ASSERT_SLOW(NewBlockFile->IsOpen());
- NewBlockFile->Flush(WriteOffset);
+ NewBlockFile->Flush();
uint64_t NewBlockSize = NewBlockFile->FileSize();
MovedSize += NewBlockSize;
NewBlockFile = nullptr;
@@ -1453,8 +1482,6 @@ TEST_CASE("blockstore.blockfile")
CHECK(std::string(Boop) == "boop");
File1.Flush();
CHECK(File1.FileSize() == 10);
- File1.Flush(10);
- CHECK(File1.FileSize() == 10);
}
{
BlockStoreFile File1(RootDirectory / "1");