WeaveDocs
Lens

Iteration

Iterators in Lens — forward and reverse range iteration, prefix scans, and per-iterator snapshot isolation.

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.

Primary types to know

  • AllowAllLensPolicy — models/lens/src/lens_policy.rs
  • Batch — models/lens/src/batch.rs
  • BlockCache — models/lens/src/block.rs
  • BlockPointer — models/lens/src/node.rs
  • CacheStats — models/lens/src/block.rs
  • CompactionOptions — models/lens/src/config.rs
  • Key — models/lens/src/node.rs
  • Lens — models/lens/src/lens.rs
  • LensConfig — models/lens/src/config.rs
  • LensMetrics — models/lens/src/metrics.rs
  • LensMetricsSnapshot — models/lens/src/metrics.rs
  • Metadata — models/lens/src/lens.rs

Example shape

use lens::{Direction, Lens, LensConfig, ReadOptions};
use std::sync::Arc;
use strand::{Strand, StrandConfig};
use tokio::sync::RwLock as AsyncRwLock;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let dir = tempfile::tempdir()?;
    let strand = Strand::new(StrandConfig::new().with_storage(dir.path())).await?;
    let lens = Lens::new(Arc::new(AsyncRwLock::new(strand)), LensConfig::default()).await?;

    // Populate the tree so the iterator has something interesting to walk.
    for label in ["alpha", "bravo", "charlie", "delta", "echo", "foxtrot"] {
        lens.put(label.as_bytes(), label.as_bytes()).await?;
    }

    // Reverse-direction range scan with a half-open bound and a row limit.
    let opts = ReadOptions {
        direction: Direction::Reverse,
        include_start: true,
        include_end: false,
        limit: Some(3),
        snapshot: None,
    };
    let mut stream = lens
        .create_read_stream_with_options(Some(b"echo"), Some(b"bravo"), opts)
        .await?;

    let mut seen = 0usize;
    while let Some((key, value)) = stream.next().await? {
        println!(
            "row {:?} -> {} bytes",
            std::str::from_utf8(key.as_bytes()).unwrap_or("?"),
            value.data.len(),
        );
        seen += 1;
    }
    println!("emitted {seen} rows in reverse order");
    Ok(())
}