aboutsummaryrefslogtreecommitdiff
path: root/zenstore/caslog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zenstore/caslog.cpp')
-rw-r--r--zenstore/caslog.cpp46
1 files changed, 38 insertions, 8 deletions
diff --git a/zenstore/caslog.cpp b/zenstore/caslog.cpp
index 055e3feda..03a56f010 100644
--- a/zenstore/caslog.cpp
+++ b/zenstore/caslog.cpp
@@ -39,13 +39,23 @@ CasLogFile::~CasLogFile()
}
void
-CasLogFile::Open(std::filesystem::path FileName, size_t RecordSize, bool IsCreate)
+CasLogFile::Open(std::filesystem::path FileName, size_t RecordSize, Mode Mode)
{
m_RecordSize = RecordSize;
std::error_code Ec;
- m_File.Open(FileName, IsCreate, Ec);
+ BasicFile::Mode FileMode = BasicFile::Mode::kRead;
+ switch (Mode)
+ {
+ case Mode::kWrite:
+ FileMode = BasicFile::Mode::kWrite;
+ break;
+ case Mode::kTruncate:
+ FileMode = BasicFile::Mode::kTruncate;
+ break;
+ }
+ m_File.Open(FileName, FileMode, Ec);
if (Ec)
{
throw std::system_error(Ec, fmt::format("Failed to open log file '{}'", FileName));
@@ -53,8 +63,12 @@ CasLogFile::Open(std::filesystem::path FileName, size_t RecordSize, bool IsCreat
uint64_t AppendOffset = 0;
- if (IsCreate || (m_File.FileSize() < sizeof(FileHeader)))
+ if ((Mode == Mode::kTruncate) || (m_File.FileSize() < sizeof(FileHeader)))
{
+ if (Mode == Mode::kRead)
+ {
+ throw std::runtime_error(fmt::format("Mangled log header (file to small) in '{}'", FileName));
+ }
// Initialize log by writing header
FileHeader Header = {.RecordSize = gsl::narrow<uint32_t>(RecordSize), .LogId = Oid::NewOid(), .ValidatedTail = 0};
memcpy(Header.Magic, FileHeader::MagicSequence, sizeof Header.Magic);
@@ -106,20 +120,36 @@ CasLogFile::GetLogSize()
return m_File.FileSize();
}
+uint64_t
+CasLogFile::GetLogCount()
+{
+ uint64_t LogFileSize = m_AppendOffset.load(std::memory_order_acquire);
+ if (LogFileSize < sizeof(FileHeader))
+ {
+ return 0;
+ }
+ const uint64_t LogBaseOffset = sizeof(FileHeader);
+ const size_t LogEntryCount = (LogFileSize - LogBaseOffset) / m_RecordSize;
+ return LogEntryCount;
+}
+
void
-CasLogFile::Replay(std::function<void(const void*)>&& Handler)
+CasLogFile::Replay(std::function<void(const void*)>&& Handler, uint64_t SkipEntryCount)
{
uint64_t LogFileSize = m_File.FileSize();
// Ensure we end up on a clean boundary
- const uint64_t LogBaseOffset = sizeof(FileHeader);
- const size_t LogEntryCount = (LogFileSize - LogBaseOffset) / m_RecordSize;
+ uint64_t LogBaseOffset = sizeof(FileHeader);
+ size_t LogEntryCount = (LogFileSize - LogBaseOffset) / m_RecordSize;
- if (LogEntryCount == 0)
+ if (LogEntryCount <= SkipEntryCount)
{
return;
}
+ LogBaseOffset += SkipEntryCount * m_RecordSize;
+ LogEntryCount -= SkipEntryCount;
+
// This should really be streaming the data rather than just
// reading it into memory, though we don't tend to get very
// large logs so it may not matter
@@ -142,7 +172,7 @@ CasLogFile::Replay(std::function<void(const void*)>&& Handler)
void
CasLogFile::Append(const void* DataPointer, uint64_t DataSize)
{
- ZEN_ASSERT(DataSize == m_RecordSize);
+ ZEN_ASSERT((DataSize % m_RecordSize) == 0);
uint64_t AppendOffset = m_AppendOffset.fetch_add(DataSize);