48 lines
include/mmap_log_writer.h
Declares MmapLogWriter, MappedHeader, and the write contract.
// MmapLogWriter: lock-free circular event log over a memory-mapped file.
#pragma once
#include <cstddef>
#include <cstdint>
#include <string>
 
// Maximum accepted entry size in bytes.
static constexpr size_t kMaxEntryBytes = 4096;
 
// Persistent header at offset 0 of the mapped file.
// Followed immediately by the circular data region.
struct MappedHeader {
  uint32_t magic;   // file identity tag; must equal kLogMagic on open
  uint32_t cursor;  // byte offset of the next write position within the data region;
                    // must be advanced only after the entry data is durably persisted
};
 
static constexpr uint32_t kLogMagic = 0xABCD1234;
 
// Writes events into a memory-mapped circular file without per-write syscalls.
class MmapLogWriter {
public:
  // Parameters:
  //   path     - filesystem path to the log file (created if absent)
  //   capacity - size in bytes of the circular data region (excluding the header)
  // Returns: new MmapLogWriter; call isOpen() before first write
  MmapLogWriter(const std::string& path, size_t capacity);
  ~MmapLogWriter();
 
  // Appends an opaque entry to the circular log.
  // Parameters:
  //   data      - pointer to the entry bytes
  //   entrySize - number of bytes to write; must not exceed kMaxEntryBytes
  // Returns: true if the entry was written and the cursor advanced;
  //          false if entrySize exceeds kMaxEntryBytes or the writer is not open
  bool write(const void* data, size_t entrySize);
 
  // Parameters: none
  // Returns: true if the file is mapped and ready to accept writes
  bool isOpen() const { return region_ != nullptr; }
 
private:
  uint8_t*     region_   = nullptr; // pointer to the start of the circular data region
  MappedHeader* header_  = nullptr; // pointer to the persistent header (before region_)
  size_t       capacity_ = 0;       // total bytes in the circular region
  size_t       cursor_   = 0;       // in-memory cursor, mirrors header_->cursor
  int          fd_       = -1;        // file descriptor for the mapped log file
};