A fast, durable, embeddable key-value database written in Rust with Write-Ahead Logging, crash recovery, and real-time change subscriptions.
- π₯ High Performance: In-memory HashMap indexing for O(1) lookups
- πΎ Durability: Write-Ahead Log (WAL) ensures no data loss on crashes
- π Crash Recovery: Automatic state restoration on startup
- π‘ Real-time Events: Subscribe to database changes with callbacks
- π Pluggable Storage: Trait-based architecture supports multiple backends
- π‘οΈ Thread Safe: Concurrent access with proper synchronization
- π§ͺ Well Tested: Comprehensive test suite including crash scenarios
- π¦ Embeddable: Zero external dependencies for core functionality
Add LohDB to your Cargo.toml:
[dependencies]
lohdb = "0.1.0"git clone https://github.com/ashokdudhade/lohdb.git
cd lohdb
cargo build --releaseRun the interactive CLI:
./target/release/lohdb --interactive --data-dir ./my_databaseExample session:
lohdb> set user:1 "Alice Johnson"
β
Set 'user:1' successfully
π‘ Change: Set { key: "user:1", value: [65, 108, 105, 99, 101, 32, 74, 111, 104, 110, 115, 111, 110] }
lohdb> get user:1
π 'user:1' = 'Alice Johnson'
lohdb> set user:2 "Bob Smith"
β
Set 'user:2' successfully
lohdb> list
π Keys (2): user:1, user:2
lohdb> delete user:2
ποΈ Deleted 'user:2'
lohdb> quit
π Goodbye!use lohdb::{Database, DatabaseConfig};
fn main() -> anyhow::Result<()> {
// Configure database
let config = DatabaseConfig {
data_dir: "./my_database".to_string(),
wal_sync_interval_ms: 1000,
};
// Open database (creates if doesn't exist)
let mut db = Database::open(config)?;
// Subscribe to changes
let _subscription = db.subscribe(|event| {
println!("Database changed: {:?}", event);
})?;
// Basic operations
db.set("user:alice".to_string(), b"Alice".to_vec())?;
db.set("user:bob".to_string(), b"Bob".to_vec())?;
// Read data
if let Some(value) = db.get("user:alice")? {
println!("Found: {}", String::from_utf8_lossy(&value));
}
// List all keys
let keys = db.list_keys()?;
println!("All keys: {:?}", keys);
// Delete data
let existed = db.delete("user:bob")?;
println!("Deleted bob: {}", existed);
Ok(())
}ββββββββββββββββ βββββββββββββββββ ββββββββββββββββ
β CLI / API ββββββΆβ Query Engine ββββββΆβ Storage Layerβ
ββββββββββββββββ βββββββββ¬ββββββββ ββββββββ¬ββββββββ
β β
βββββββββΌβββββββββ βββββββββΌβββββββββ
β In-Memory KV ββββ€ WAL (Append β
β Index β β Only Log) β
ββββββββββββββββββ ββββββββββββββββββ
- Storage Engine: Pluggable trait-based storage backends
- Write-Ahead Log: Durability through append-only operation logging
- In-Memory Index: Fast HashMap-based key lookups
- Event System: Real-time change notifications via channels
- Recovery Manager: Automatic WAL replay on startup
- Writes: ~500K ops/sec (in-memory + WAL)
- Reads: ~2M ops/sec (HashMap lookup)
- Recovery: Linear with WAL size
- Memory: Configurable, ~50 bytes per key overhead
LohDB supports pluggable storage through the StorageEngine trait:
- FileStorageEngine: Persistent disk-based storage (default)
- InMemoryStorageEngine: Fast in-memory storage for testing
Implement the StorageEngine trait for custom backends:
use lohdb::{StorageEngine, Result};
struct MyCustomEngine;
impl StorageEngine for MyCustomEngine {
fn initialize(&mut self) -> Result<()> { /* ... */ }
fn store(&mut self, key: &str, value: &[u8]) -> Result<()> { /* ... */ }
fn retrieve(&self, key: &str) -> Result<Option<Vec<u8>>> { /* ... */ }
fn remove(&mut self, key: &str) -> Result<bool> { /* ... */ }
fn list_keys(&self) -> Result<Vec<String>> { /* ... */ }
fn flush(&mut self) -> Result<()> { /* ... */ }
}Subscribe to database changes for real-time notifications:
let subscription = db.subscribe(|event| {
match event {
ChangeEvent::Set { key, value } => {
println!("Key '{}' was set", key);
}
ChangeEvent::Delete { key } => {
println!("Key '{}' was deleted", key);
}
}
})?;
// Subscription automatically cleaned up when droppedEvery operation is logged before execution:
- Write to WAL: Operation serialized and appended to log
- Update Index: In-memory state updated
- Background Sync: Periodic flush to disk
On startup, LohDB automatically:
- Reads WAL: Deserializes all logged operations
- Replays Operations: Rebuilds in-memory state
- Resumes Normal Operation: Database ready for use
- Atomic Operations: Each operation is fully logged before execution
- Checksum Validation: Corrupted WAL entries are detected and skipped
- Graceful Degradation: Partial recovery from damaged logs
Run the full test suite:
# Unit tests
cargo test
# Integration tests
cargo test --test recovery
# Benchmark tests
cargo bench- β Basic CRUD operations
- β Crash recovery scenarios
- β Concurrent access patterns
- β WAL integrity and replay
- β Change subscription system
- β Storage engine pluggability
# Clone repository
git clone https://github.com/yourusername/lohdb.git
cd lohdb
# Install dependencies
cargo build
# Run tests
cargo test
# Format code
cargo fmt
# Lint code
cargo clippyThis project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by RocksDB and LevelDB
- Built with the amazing Rust ecosystem
- Special thanks to the open source community
Built with β€οΈ in Rust
