Cache and Compaction
Cache and compaction in Lens — pluggable cache policies, background compaction, and metrics for B-tree operations.
Purpose
B-tree key/value database with batches, snapshots, sub-databases, iterators, cache, compaction, and metrics.
This page follows the real source shape for Lens and explains the workflow a developer is likely to use first.
Developer workflow
Start from the smallest constructor or builder, perform one meaningful operation, inspect the returned state, then add the relevant policy, storage, or network integration. The examples below should be expanded whenever the crate API changes.
For most workloads, the default CompactionOptions are correct. Tune only when metrics show sustained backlog (pending_compactions growing) or read amplification beyond your latency budget.
Primary types to know
AllowAllLensPolicy— models/lens/src/lens_policy.rsBatch— models/lens/src/batch.rsBlockCache— models/lens/src/block.rsBlockPointer— models/lens/src/node.rsCacheStats— models/lens/src/block.rsCompactionOptions— models/lens/src/config.rsKey— models/lens/src/node.rsLens— models/lens/src/lens.rsLensConfig— models/lens/src/config.rsLensMetrics— models/lens/src/metrics.rsLensMetricsSnapshot— models/lens/src/metrics.rsMetadata— models/lens/src/lens.rs
Example shape
use lens::{CompactionOptions, Lens, LensConfig};
use std::sync::Arc;
use std::time::Duration;
use strand::{Strand, StrandConfig};
use tokio::sync::RwLock as AsyncRwLock;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configure cache size, compaction policy, and snapshot retention up-front.
let cfg = LensConfig {
cache_size: 4 * 1024 * 1024, // 4 MiB block cache
auto_compact: true,
compact_threshold: 0.6,
snapshot_retention: Duration::from_secs(900),
..LensConfig::default()
};
let dir = tempfile::tempdir()?;
let strand = Strand::new(StrandConfig::new().with_storage(dir.path())).await?;
let lens = Lens::new(Arc::new(AsyncRwLock::new(strand)), cfg).await?;
// Drive a few reads/writes through the B-tree to populate the cache.
for i in 0..16u32 {
lens.put(format!("key-{i:02}").as_bytes(), &i.to_be_bytes()).await?;
}
let _ = lens.get(b"key-07").await?;
// CacheStats reports the LRU/heap state after the warmup pass.
let stats = lens.cache_stats();
println!(
"cache hits={} misses={} hit_ratio={:.2}",
stats.hits,
stats.misses,
stats.hit_ratio(),
);
// Document compaction tuning even when auto-compact handles the trigger.
let _compaction = CompactionOptions {
target_fill_factor: 0.75,
merge_small_nodes: true,
batch_size: 64,
};
lens.clear_cache();
Ok(())
}