aboutsummaryrefslogtreecommitdiff
path: root/zenstore/compactcas.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-03-15 19:50:29 +0100
committerDan Engelbrecht <[email protected]>2022-03-31 11:28:32 +0200
commitfa4aae1fa674b60f0fa6ff48f5d42844c99d8962 (patch)
tree4e4dd58ab2230decab83a6d80225c3833de54455 /zenstore/compactcas.cpp
parentManage lifetime of FileHandle (diff)
downloadzen-fa4aae1fa674b60f0fa6ff48f5d42844c99d8962.tar.xz
zen-fa4aae1fa674b60f0fa6ff48f5d42844c99d8962.zip
Check usage of block instead of size on disk
Fixed check for new block in InsertChunk
Diffstat (limited to 'zenstore/compactcas.cpp')
-rw-r--r--zenstore/compactcas.cpp60
1 files changed, 37 insertions, 23 deletions
diff --git a/zenstore/compactcas.cpp b/zenstore/compactcas.cpp
index a44f7a6c0..6c74cac2e 100644
--- a/zenstore/compactcas.cpp
+++ b/zenstore/compactcas.cpp
@@ -211,8 +211,7 @@ CasContainerStrategy::InsertChunk(const void* ChunkData, size_t ChunkSize, const
// New entry
- uint64_t CurrentBlockSize = m_CurrentBlock.lock()->FileSize();
- if (CurrentBlockSize + m_CurrentInsertOffset > m_MaxBlockSize)
+ if ((m_CurrentInsertOffset + ChunkSize) > m_MaxBlockSize)
{
RwLock::ExclusiveLockScope __(m_LocationMapLock);
uint16_t NewBlockIndex = m_CurrentBlockIndex + 1;
@@ -224,7 +223,7 @@ CasContainerStrategy::InsertChunk(const void* ChunkData, size_t ChunkSize, const
throw std::runtime_error(fmt::format("unable to allocate a new block in {}", m_ContainerBaseName));
}
}
- m_CurrentBlockIndex = NewBlockIndex;
+ m_CurrentBlockIndex = NewBlockIndex;
auto SmallObjectFile = std::make_shared<ChunkBlock>(m_Config.RootDirectory, m_ContainerBaseName, m_CurrentBlockIndex);
SmallObjectFile->Create(m_MaxBlockSize);
m_OpenBlocks[m_CurrentBlockIndex] = SmallObjectFile;
@@ -534,7 +533,7 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
return;
}
}
- m_CurrentBlockIndex = NewBlockIndex;
+ m_CurrentBlockIndex = NewBlockIndex;
auto SmallObjectFile = std::make_shared<ChunkBlock>(m_Config.RootDirectory, m_ContainerBaseName, m_CurrentBlockIndex);
SmallObjectFile->Create(m_MaxBlockSize);
m_OpenBlocks[m_CurrentBlockIndex] = SmallObjectFile;
@@ -565,7 +564,7 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
// size when creating it?
RwLock::ExclusiveLockScope _i(m_InsertLock);
- auto BlockFile = m_OpenBlocks[BlockIndex];
+ auto BlockFile = m_OpenBlocks[BlockIndex];
ZEN_INFO("marking cas store file for delete {}, block {}", m_ContainerBaseName, std::to_string(BlockIndex));
BlockFile->MarkAsDeleteOnClose();
m_OpenBlocks.erase(BlockIndex);
@@ -826,15 +825,24 @@ CasContainerStrategy::OpenContainer(bool IsNewStore)
}
});
- std::unordered_set<uint16_t> ReferencedBlockIndexes;
+ std::unordered_map<uint16_t, uint64_t> BlockUsage;
for (const auto& Entry : m_LocationMap)
{
const auto& Location = Entry.second;
m_TotalSize.fetch_add(Location.Size);
- ReferencedBlockIndexes.insert(Location.BlockIndex);
+ uint64_t NextBlockStart = Location.Offset + Location.Size;
+ auto It = BlockUsage.find(Location.BlockIndex);
+ if (It == BlockUsage.end())
+ {
+ BlockUsage[Location.BlockIndex] = NextBlockStart;
+ continue;
+ }
+ if (It->second < NextBlockStart)
+ {
+ It->second = NextBlockStart;
+ }
}
- uint32_t SmallestBlockSize = gsl::narrow<uint32_t>(m_MaxBlockSize);
for (const std::filesystem::directory_entry& Entry : std::filesystem::directory_iterator(m_Config.RootDirectory))
{
if (Entry.is_regular_file())
@@ -857,7 +865,7 @@ CasContainerStrategy::OpenContainer(bool IsNewStore)
try
{
uint16_t BlockIndex = static_cast<uint16_t>(std::stoi(FileName.substr(m_ContainerBaseName.length() + 1)));
- if (!ReferencedBlockIndexes.contains(BlockIndex))
+ if (!BlockUsage.contains(BlockIndex))
{
// Clear out unused blocks
std::filesystem::remove(Entry.path());
@@ -865,18 +873,7 @@ CasContainerStrategy::OpenContainer(bool IsNewStore)
}
auto SmallObjectFile = std::make_shared<ChunkBlock>(m_Config.RootDirectory, m_ContainerBaseName, BlockIndex);
SmallObjectFile->Open();
- uint64_t FileSize = SmallObjectFile->FileSize();
- if (FileSize < SmallestBlockSize)
- {
- m_CurrentBlockIndex = BlockIndex;
- SmallestBlockSize = gsl::narrow<std::uint32_t>(FileSize);
- }
m_OpenBlocks[BlockIndex] = SmallObjectFile;
- if (FileSize < SmallestBlockSize)
- {
- m_CurrentBlockIndex = BlockIndex;
- SmallestBlockSize = gsl::narrow<std::uint32_t>(FileSize);
- }
}
catch (const std::invalid_argument&)
{
@@ -884,9 +881,26 @@ CasContainerStrategy::OpenContainer(bool IsNewStore)
}
}
}
- if (m_OpenBlocks.empty())
+
+ uint32_t LargestSizeToUse = gsl::narrow<uint32_t>(m_MaxBlockSize - m_PayloadAlignment);
+ uint32_t SmallestBlockSize = LargestSizeToUse;
+ bool CreateNewBlock = m_OpenBlocks.empty();
+ if (!CreateNewBlock)
{
- auto SmallObjectFile = std::make_shared<ChunkBlock>(m_Config.RootDirectory, m_ContainerBaseName, m_CurrentBlockIndex);
+ for (const auto& Entry : BlockUsage)
+ {
+ if (Entry.second < SmallestBlockSize)
+ {
+ SmallestBlockSize = gsl::narrow<uint32_t>(Entry.second);
+ m_CurrentBlockIndex = Entry.first;
+ CreateNewBlock = false;
+ }
+ }
+ }
+
+ if (CreateNewBlock)
+ {
+ auto SmallObjectFile = std::make_shared<ChunkBlock>(m_Config.RootDirectory, m_ContainerBaseName, m_CurrentBlockIndex);
SmallObjectFile->Create(m_MaxBlockSize);
m_OpenBlocks[m_CurrentBlockIndex] = SmallObjectFile;
m_CurrentBlock = SmallObjectFile;
@@ -895,7 +909,7 @@ CasContainerStrategy::OpenContainer(bool IsNewStore)
else
{
m_CurrentBlock = m_OpenBlocks[m_CurrentBlockIndex];
- m_CurrentInsertOffset = static_cast<uint32_t>(AlignPositon(m_CurrentBlock.lock()->FileSize(), m_PayloadAlignment));
+ m_CurrentInsertOffset = static_cast<uint32_t>(AlignPositon(SmallestBlockSize, m_PayloadAlignment));
}
// TODO: should validate integrity of container files here