nano-wal

A simple, lightweight Write-Ahead Log (WAL) implementation in Rust designed for append-only operations with configurable retention, segment management, and optional random access for memory-constrained systems.
Features
- Append-only operations: Efficient write operations with optional durability guarantees
- Entry references: Get position references for written entries enabling random access
- Random access reads: Read specific entries directly using their references with signature verification
- Segment rotation: Automatic segment file rotation based on configurable time intervals
- Key-based indexing: Fast lookups and enumeration of records by key
- Configurable retention: Automatic cleanup of old entries based on time-based retention policies
- Compaction: Remove expired segments to reclaim disk space
- Memory-efficient: Zero RAM overhead with optional random access for memory-constrained systems
Installation
Add this to your Cargo.toml:
[]
= "0.1.1"
Quick Start
use ;
use Bytes;
use Duration;
// Create a new WAL with default options
let mut wal = new?;
// Append an entry and get its reference
let content = from;
let entry_ref = wal.append_entry?;
// Log an entry with durability (forced sync to disk)
let durable_content = from;
let durable_ref = wal.log_entry?;
// Random access: read specific entry using its reference
let retrieved_content = wal.read_entry_at?;
// Sequential access: retrieve all records for a key
let records: = wal.enumerate_records?.collect;
// Enumerate all keys
let keys: = wal.enumerate_keys?.collect;
// Compact the WAL (remove expired segments)
wal.compact?;
// Clean shutdown
wal.shutdown?;
Configuration
Customize WAL behavior with WalOptions:
use ;
use Duration;
let options = WalOptions ;
let mut wal = new?;
Configuration Options
entry_retention: Duration for which entries are retained before being eligible for compaction (default: 1 week)segments: Number of segments to use per retention period (default: 10 segments, creating time-based rotation)
API Reference
Core Methods
new(filepath: &str, options: WalOptions)- Create a new WAL instanceappend_entry<K>(key: K, content: Bytes, durable: bool) -> EntryRef- Append an entry to the WAL, returns referencelog_entry<K>(key: K, content: Bytes) -> EntryRef- Append an entry with durability enabled, returns referenceread_entry_at(entry_ref: EntryRef) -> Bytes- Read specific entry using its reference (random access)enumerate_records<K>(key: K)- Get all records for a specific key (sequential access)enumerate_keys() -> Vec<String>- Get all unique keys in the WALcompact()- Remove expired segments based on retention policyshutdown()- Clean shutdown and remove all WAL files
Key Types
Keys must implement Hash + AsRef<[u8]> + Display for append operations. Common types like String, &str, and custom types that implement Display work seamlessly.
Entry References
EntryRef is a lightweight reference containing:
segment_id: u64- The segment file identifieroffset: u64- The byte offset within the segment
Entry references enable efficient random access while maintaining zero RAM overhead for the main WAL operations.
File Format
The WAL stores data in binary format across multiple segment files:
- Each segment is named
{segment_id}.logor{segment_id}_{key}.logfor better debugging - Each entry is prefixed with the UTF-8 'NANO-WAL' signature for integrity verification
- Entries contain: signature (8 bytes) + timestamp (8 bytes) + key_length (8 bytes) + key + content_length (8 bytes) + content
- Segments rotate based on time intervals (retention_period / segments)
Use Cases
- Event Sourcing: Store events in append-only fashion with key-based retrieval and random access
- Database WAL: Write-ahead logging for database systems with entry-level recovery
- Message Queues: Persistent message storage with direct access to specific messages
- Audit Logs: Tamper-evident logging with time-based retention and signature verification
- Memory-Constrained Systems: Support RAM-based append-only structures with disk-backed random access
- Cache Persistence: Persistent storage for cache warming with selective entry retrieval
Performance Characteristics
- Write throughput: Optimized for sequential writes with signature prefixing
- Read performance: O(1) key lookups via in-memory index for sequential access, direct file I/O for random access
- Storage efficiency: Time-based segment rotation and automatic compaction
- Memory usage: Zero RAM overhead for entry storage, lightweight in-memory index for key mapping
- Random access: Direct entry retrieval with signature verification for data integrity
Thread Safety
While the WAL struct itself is not Sync, it can be safely used in single-threaded contexts or wrapped in appropriate synchronization primitives (Arc<Mutex<Wal>>) for multi-threaded scenarios. Entry references (EntryRef) are Copy and can be safely shared between threads.
Examples
Basic Usage
use ;
use Bytes;
Event Sourcing with Random Access
use ;
use Bytes;
use json;
use HashMap;
// Memory-efficient approach: store only references in RAM
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.