File Abstractions
The file package encapsulates direct file-system interaction for WAL, SST, and value-log files. It provides portable mmap helpers, allocation primitives, and log file wrappers.
1. Core Types
| Type | Purpose | Key Methods |
|---|---|---|
Options | Parameter bag for opening files (FID, path, size). | Used by WAL/vlog managers. |
CoreFile | Interface abstracting platform-specific operations. | NewReader, Bytes, Sync, Delete. |
MmapFile | Cross-platform mmap wrapper. | OpenMmapFile, AppendBuffer, Truncature, Sync. |
LogFile | Value-log specific helper built on MmapFile. | Open, Write, Read, DoneWriting, EncodeEntry. |
Darwin-specific builds live alongside (mmap_darwin.go, sstable_darwin.go) ensuring the package compiles on macOS without manual tuning.
2. Mmap Management
OpenMmapFileopens or creates a file, optionally extending it tomaxSz, then mmaps it. The returnedMmapFileexposesData []byteand the underlying*os.Filehandle.- Writes grow the map on demand:
AppendBufferchecks if the write would exceed the current mapping and callsTruncatureto expand (doubling up to 1 GiB increments). Syncflushes dirty pages (mmap.Msync), whileDeleteunmaps, truncates, closes, and removes the file—used when dropping SSTs or value-log segments.
RocksDB relies on custom Env implementations for portability; NoKV keeps the logic in Go, relying on build tags for OS differences.
3. LogFile Semantics
LogFile wraps MmapFile to simplify value-log operations:
lf := &file.LogFile{}
_ = lf.Open(&file.Options{FID: 1, FileName: "00001.vlog", MaxSz: 1<<29})
ptr, _ := lf.EncodeEntry(entry, buf, offset)
_ = lf.Write(offset, buf.Bytes())
_ = lf.DoneWriting(nextOffset)
Openmmaps the file and records current size (guarded to< 4 GiB).Readvalidates offsets against both the mmap length and tracked size, preventing partial reads when GC or drop operations shrink the file.EncodeEntryuses the sharedkv.EntryHeaderand CRC32 helpers to produce the exact on-disk layout consumed byvlog.Managerandwal.Manager.DoneWritingsyncs, truncates to the provided offset, reinitialises the mmap, and keeps the file open in read-write mode—supporting subsequent appends.Rewind(viavlog.Manager.Rewind) leveragesLogFile.TruncateandInitto roll back partial batches after errors.
4. SST Helpers
While SSTable builders/readers live under lsm/table.go, they rely on file helpers to map index/data blocks efficiently. The build tags (sstable_linux.go, sstable_darwin.go) provide OS-specific tuning for direct I/O hints or mmap flags.
5. Comparison
| Engine | Approach |
|---|---|
| RocksDB | C++ Env & random-access file wrappers. |
| Badger | y.File abstraction with mmap. |
| NoKV | Go-native mmap wrappers with explicit log helpers. |
By keeping all filesystem primitives in one package, NoKV ensures WAL, vlog, and SST layers share consistent behaviour (sync semantics, truncation rules) and simplifies testing (mmap_linux_test.go).
6. Operational Notes
- Value-log and WAL segments rely on
DoneWriting/Truncateto seal files; avoid manipulating files externally or mmap metadata may desynchronise. LogFile.AddSizeupdates the cached size used by reads—critical when rewinding or rewriting segments.SyncDir(seemmap_linux.go) is invoked when new files are created to persist directory entries, similar to RocksDB’sEnv::FsyncDir.
For more on how these primitives plug into higher layers, see docs/wal.md and docs/vlog.md.