pub struct Engine { /* private fields */ }Expand description
The core LSM-tree storage engine.
Engine provides a fully synchronous key-value API with WAL durability,
Bloom filters, block cache, and background flush/compaction/GC.
§Opening
use flowdb::{Engine, Config};
let engine = Engine::open(Config::default()).unwrap();§Writing
use flowdb::Record;
engine.write_batch_owned(vec![
Record::new("sensor:temp", 1_700_000_000_000, b"22.5".to_vec()),
]).unwrap();§Reading
use flowdb::Query;
for rec in engine.query(Query::prefix("sensor:")).unwrap() {
println!("{}", rec.key_str());
}§Shutdown
engine.shutdown().unwrap();If the engine is behind an Arc, use Engine::close instead.
Implementations§
Source§impl Engine
impl Engine
Sourcepub fn spawn_background_maintenance(&self) -> Option<MaintenanceHandle>
pub fn spawn_background_maintenance(&self) -> Option<MaintenanceHandle>
Spawn a background maintenance thread that periodically flushes the
memtable to SSTable, runs compaction, garbage-collects expired
SST files, and syncs the WAL. The thread runs until the returned
MaintenanceHandle is dropped or the engine is shut down.
Unlike an async runtime approach, this uses a plain OS thread and does not require a Tokio context, making FlowDB fully runtime-agnostic.
Sourcepub fn open(config: Config) -> Result<Self>
pub fn open(config: Config) -> Result<Self>
Open (or create) an engine at the configured data directory.
On first call with create_if_missing: true (default), the data directory
and its sub-directories (WAL/, SST/, INDEX/) are created automatically.
If the directory already contains valid data (WAL + SST files), the engine recovers by replaying the WAL from the last flushed sequence number.
Sourcepub fn write_batch(&self, batch: &[Record]) -> Result<()>
pub fn write_batch(&self, batch: &[Record]) -> Result<()>
Write a batch of records using the engine’s default TTL.
This is a borrowed-input variant — the caller retains ownership of batch.
Sourcepub fn write_batch_owned(&self, batch: Vec<Record>) -> Result<()>
pub fn write_batch_owned(&self, batch: Vec<Record>) -> Result<()>
Write a batch of records (owned input, no TTL override).
Equivalent to write_batch but takes ownership of the Vec, which can
avoid a clone in some call sites.
Sourcepub fn write_batch_sync(&self, batch: Vec<Record>) -> Result<()>
pub fn write_batch_sync(&self, batch: Vec<Record>) -> Result<()>
Write a batch synchronously, bypassing the background write pipeline.
This method encodes, WAL-logs, and memtable-inserts on the calling thread. It is useful when the caller needs a synchronous durability guarantee without waiting for the background writer.
pub fn write_batch_ttl( &self, batch: &[Record], ttl_secs: Option<u64>, ) -> Result<()>
pub fn query(&self, query: Query) -> Result<Vec<Record>>
pub fn query_by_prefix(&self, key: &str) -> Result<Vec<Record>>
pub fn query_by_key_range(&self, start: &str, end: &str) -> Result<Vec<Record>>
pub fn query_time_range(&self, start: i64, end: i64) -> Result<Vec<Record>>
pub fn query_prefix_time_range( &self, key: &str, start: i64, end: i64, ) -> Result<Vec<Record>>
pub fn query_key_time_range( &self, start_key: &str, end_key: &str, start: i64, end: i64, ) -> Result<Vec<Record>>
pub fn get(&self, key: &str, ts: i64) -> Result<Option<Record>>
pub fn get_sync(&self, key: &str, ts: i64) -> Option<Record>
pub fn delete_batch(&self, keys_ts: &[(String, i64)]) -> Result<()>
pub fn delete_range(&self, start_key: &str, end_key: &str) -> Result<()>
pub fn patch_record( &self, key: &str, ts: i64, new_value: Option<Vec<u8>>, new_ttl_secs: Option<u64>, ) -> Result<Record>
pub fn stats(&self) -> EngineStats
pub fn metrics_text(&self) -> String
pub fn flush(&self) -> Result<()>
pub fn trigger_gc(&self) -> Result<u64>
pub fn trigger_compaction(&self) -> Result<bool>
Sourcepub fn shutdown(self) -> Result<()>
pub fn shutdown(self) -> Result<()>
Shut down the engine, flushing the memtable and WAL. Consumes
self — use Engine::close if the engine is behind an Arc.
Sourcepub fn close(&self) -> Result<()>
pub fn close(&self) -> Result<()>
Flush the memtable and WAL without consuming self.
This is the Arc<Engine>-friendly alternative to shutdown. Use
it when the engine is shared across threads. The background
maintenance thread (if any) is NOT stopped — drop the
MaintenanceHandle first, or simply let Engine::shutdown
consume it.
Sourcepub fn scan(&self, range: ScanRange) -> Result<ScanIterator>
pub fn scan(&self, range: ScanRange) -> Result<ScanIterator>
Lazy iterator scan with default ReadOptions.
Sourcepub fn scan_opt(
&self,
range: ScanRange,
_opts: &ReadOptions,
) -> Result<ScanIterator>
pub fn scan_opt( &self, range: ScanRange, _opts: &ReadOptions, ) -> Result<ScanIterator>
Lazy iterator scan with caller-provided ReadOptions.
Sourcepub fn scan_prefix(&self, prefix: &str) -> Result<ScanIterator>
pub fn scan_prefix(&self, prefix: &str) -> Result<ScanIterator>
Convenience: prefix scan returning a lazy iterator.
Sourcepub fn scan_prefix_time_range(
&self,
prefix: &str,
ts_start: i64,
ts_end: i64,
) -> Result<ScanIterator>
pub fn scan_prefix_time_range( &self, prefix: &str, ts_start: i64, ts_end: i64, ) -> Result<ScanIterator>
Convenience: prefix + time-range scan returning a lazy iterator.
Sourcepub fn get_latest(&self, key: &str) -> Result<Option<Record>>
pub fn get_latest(&self, key: &str) -> Result<Option<Record>>
Get the latest record for a given key (highest ts).
Unlike the old scan-then-last approach which is O(n) in the number of versions, this walks memtables and SST blocks via the block index, yielding O(log n) or O(k) where k is the number of blocks.