diff options
Diffstat (limited to 'zenstore/caslog.cpp')
| -rw-r--r-- | zenstore/caslog.cpp | 46 |
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); |