aboutsummaryrefslogtreecommitdiff
path: root/src/zenstore/blockstore.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-08-30 11:26:42 +0200
committerGitHub Enterprise <[email protected]>2024-08-30 11:26:42 +0200
commitcbb9ed149517cf781bf21bff4650d7d01bd6d567 (patch)
treea185fe2a84cd6681caae7a71bb72d398421f97b6 /src/zenstore/blockstore.cpp
parentzenserver process launch/termination improvements (#138) (diff)
downloadzen-cbb9ed149517cf781bf21bff4650d7d01bd6d567.tar.xz
zen-cbb9ed149517cf781bf21bff4650d7d01bd6d567.zip
meta info store (#75)
- Feature: Added option `--gc-cache-attachment-store` which caches referenced attachments in cache records on disk for faster GC - default is `false` - Feature: Added option `--gc-projectstore-attachment-store` which caches referenced attachments in project store oplogs on disk for faster GC - default is `false`
Diffstat (limited to 'src/zenstore/blockstore.cpp')
-rw-r--r--src/zenstore/blockstore.cpp154
1 files changed, 147 insertions, 7 deletions
diff --git a/src/zenstore/blockstore.cpp b/src/zenstore/blockstore.cpp
index 70ddcedaf..287a3f7fa 100644
--- a/src/zenstore/blockstore.cpp
+++ b/src/zenstore/blockstore.cpp
@@ -90,6 +90,7 @@ BlockStoreFile::Create(uint64_t InitialSize)
RetriesLeft--;
return true;
});
+ RemoveMeta();
void* FileHandle = m_File.Handle();
@@ -99,15 +100,26 @@ BlockStoreFile::Create(uint64_t InitialSize)
}
uint64_t
-BlockStoreFile::FileSize()
+BlockStoreFile::FileSize() const
{
- return m_CachedFileSize == 0 ? m_File.FileSize() : m_CachedFileSize;
+ if (m_CachedFileSize == 0)
+ {
+ std::error_code Ec;
+ uint64_t Size = m_File.FileSize(Ec);
+ if (Ec)
+ {
+ return 0;
+ }
+ return Size;
+ }
+ return m_CachedFileSize;
}
void
BlockStoreFile::MarkAsDeleteOnClose()
{
m_IoBuffer.SetDeleteOnClose(true);
+ RemoveMeta();
}
IoBuffer
@@ -157,6 +169,90 @@ BlockStoreFile::IsOpen() const
return !!m_IoBuffer;
}
+bool
+BlockStoreFile::SetMetaData(const IoBuffer& Payload)
+{
+ if (!Payload)
+ {
+ RemoveMeta();
+ return true;
+ }
+ const std::filesystem::path MetaPath = GetMetaPath();
+ std::error_code Ec;
+ TemporaryFile::SafeWriteFile(MetaPath, Payload.GetView(), Ec);
+ if (Ec)
+ {
+ ZEN_WARN("Unable to set meta data for block '{}' at meta path: '{}'. Reason: '{}'", m_Path, MetaPath, Ec.message());
+ return false;
+ }
+ return true;
+}
+
+static bool
+IsMetaDataValid(const std::filesystem::path& BlockPath, const std::filesystem::path& MetaPath)
+{
+ std::error_code Ec;
+ std::filesystem::file_time_type MetaWriteTime = std::filesystem::last_write_time(MetaPath, Ec);
+ if (Ec)
+ {
+ return false;
+ }
+ std::filesystem::file_time_type BlockWriteTime = std::filesystem::last_write_time(BlockPath, Ec);
+ if (Ec)
+ {
+ return false;
+ }
+ if (MetaWriteTime < BlockWriteTime)
+ {
+ std::filesystem::remove(MetaPath, Ec);
+ return false;
+ }
+ return true;
+}
+
+IoBuffer
+BlockStoreFile::GetMetaData() const
+{
+ const std::filesystem::path MetaPath = GetMetaPath();
+ if (IsMetaDataValid(m_Path, MetaPath))
+ {
+ return IoBufferBuilder::MakeFromFile(MetaPath);
+ }
+ return {};
+}
+
+uint64_t
+BlockStoreFile::MetaSize() const
+{
+ const std::filesystem::path MetaPath = GetMetaPath();
+ if (IsMetaDataValid(m_Path, MetaPath))
+ {
+ std::error_code DummyEc;
+ if (uint64_t Size = std::filesystem::file_size(MetaPath, DummyEc); !DummyEc)
+ {
+ return Size;
+ }
+ }
+ return 0;
+}
+
+void
+BlockStoreFile::RemoveMeta()
+{
+ std::filesystem::path MetaPath = GetMetaPath();
+ std::error_code DummyEc;
+ std::filesystem::remove(MetaPath, DummyEc);
+}
+
+std::filesystem::path
+BlockStoreFile::GetMetaPath() const
+{
+ std::filesystem::path MetaPath(m_Path);
+ return MetaPath.replace_extension(".meta");
+}
+
+////////////////////////////////////////////////////////
+
constexpr uint64_t DefaultIterateSmallChunkWindowSize = 2 * 1024 * 1024;
constexpr uint64_t IterateSmallChunkMaxGapSize = 4 * 1024;
@@ -215,7 +311,7 @@ BlockStore::Initialize(const std::filesystem::path& BlocksBasePath, uint64_t Max
}
Ref<BlockStoreFile> BlockFile{new BlockStoreFile(Path)};
BlockFile->Open();
- m_TotalSize.fetch_add(BlockFile->FileSize(), std::memory_order::relaxed);
+ m_TotalSize.fetch_add(BlockFile->TotalSize(), std::memory_order::relaxed);
m_ChunkBlocks[BlockIndex] = BlockFile;
FoundBlocks[BlockIndex] = BlockFile->FileSize();
if (BlockIndex >= NextBlockIndex)
@@ -283,7 +379,7 @@ BlockStore::SyncExistingBlocksOnDisk(const BlockIndexSet& KnownLocations)
std::filesystem::path BlockPath = GetBlockPath(m_BlocksBasePath, BlockIndex);
if (m_ChunkBlocks[BlockIndex])
{
- m_TotalSize.fetch_sub(m_ChunkBlocks[BlockIndex]->FileSize(), std::memory_order::relaxed);
+ m_TotalSize.fetch_sub(m_ChunkBlocks[BlockIndex]->TotalSize(), std::memory_order::relaxed);
m_ChunkBlocks[BlockIndex]->MarkAsDeleteOnClose();
}
m_ChunkBlocks.erase(BlockIndex);
@@ -781,6 +877,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot,
{
ZEN_DEBUG("dropping incomplete cas block store file '{}'", NewBlockFile->GetPath());
m_TotalSize.fetch_sub(NewBlockFile->FileSize(), std::memory_order::relaxed);
+ ZEN_ASSERT_SLOW(NewBlockFile->MetaSize() == 0);
NewBlockFile->MarkAsDeleteOnClose();
}
});
@@ -833,7 +930,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot,
ZEN_DEBUG("marking cas block store file '{}' for delete, block #{}", OldBlockFile->GetPath(), BlockIndex);
ZEN_ASSERT(m_ChunkBlocks[BlockIndex] == OldBlockFile);
m_ChunkBlocks.erase(BlockIndex);
- m_TotalSize.fetch_sub(OldBlockFile->FileSize(), std::memory_order::relaxed);
+ m_TotalSize.fetch_sub(OldBlockFile->TotalSize(), std::memory_order::relaxed);
OldBlockFile->MarkAsDeleteOnClose();
}
continue;
@@ -1003,7 +1100,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot,
ZEN_DEBUG("marking cas block store file '{}' for delete, block #{}", OldBlockFile->GetPath(), BlockIndex);
ZEN_ASSERT(m_ChunkBlocks[BlockIndex] == OldBlockFile);
m_ChunkBlocks.erase(BlockIndex);
- m_TotalSize.fetch_sub(OldBlockFile->FileSize(), std::memory_order::relaxed);
+ m_TotalSize.fetch_sub(OldBlockFile->TotalSize(), std::memory_order::relaxed);
OldBlockFile->MarkAsDeleteOnClose();
}
}
@@ -1500,9 +1597,10 @@ BlockStore::CompactBlocks(const BlockStoreCompactState& CompactState,
LogPrefix,
OldBlockFile->GetPath().filename(),
NiceBytes(OldBlockSize));
+ m_TotalSize.fetch_sub(OldBlockSize);
+ m_TotalSize.fetch_sub(OldBlockFile->MetaSize());
OldBlockFile->MarkAsDeleteOnClose();
m_ChunkBlocks.erase(BlockIndex);
- m_TotalSize.fetch_sub(OldBlockSize);
RemovedSize += OldBlockSize;
}
return true;
@@ -1544,6 +1642,48 @@ BlockStore::GetBlockPath(const std::filesystem::path& BlocksBasePath, const uint
return Path.ToPath();
}
+bool
+BlockStore::IsWriting(uint32_t BlockIndex) const
+{
+ RwLock::SharedLockScope _(m_InsertLock);
+ if (std::find(m_ActiveWriteBlocks.begin(), m_ActiveWriteBlocks.end(), BlockIndex) != m_ActiveWriteBlocks.end())
+ {
+ return true;
+ }
+ if (BlockIndex == m_WriteBlockIndex.load() && m_WriteBlock)
+ {
+ return true;
+ }
+ return false;
+}
+
+void
+BlockStore::SetMetaData(uint32_t BlockIndex, const IoBuffer& Payload)
+{
+ RwLock::ExclusiveLockScope _(m_InsertLock);
+ if (auto It = m_ChunkBlocks.find(BlockIndex); It != m_ChunkBlocks.end() && It->second)
+ {
+ uint64_t OldMetaSize = It->second->MetaSize();
+ if (It->second->SetMetaData(Payload))
+ {
+ uint64_t NewMetaSize = It->second->MetaSize();
+ m_TotalSize += NewMetaSize;
+ m_TotalSize -= OldMetaSize;
+ }
+ }
+}
+
+IoBuffer
+BlockStore::GetMetaData(uint32_t BlockIndex) const
+{
+ RwLock::SharedLockScope _(m_InsertLock);
+ if (auto It = m_ChunkBlocks.find(BlockIndex); It != m_ChunkBlocks.end() && It->second)
+ {
+ return It->second->GetMetaData();
+ }
+ return {};
+}
+
#if ZEN_WITH_TESTS
TEST_CASE("blockstore.blockstoredisklocation")