# stree / stree32 — guide
> **Class:** `guide` · **Function:** `stree`. The how-to. Chosen design in
> [`stree-design.md`](stree-design.md); measured numbers + reproduce commands in
> [`benchmarks.md`](benchmarks.md).
## Pick a width
- Keys fit in **32 bits** and aren't OSM/skade ids → `stree32::STree32` (denser, faster
once RAM-bound).
- Keys are **i64** (OSM node ids, skade snapshot ids) → `stree::STree64`.
Never reach for a generic `STree<T>` — it does not exist by design (see
[`stree-reasoning.md`](stree-reasoning.md)).
## In-RAM lookup
```rust
use znippy_zoomies::stree32::STree32;
let mut keys: Vec<u32> = load_keys();
keys.sort_unstable(); // the tree requires sorted input
let tree = STree32::new(&keys); // build once (expensive), query many (cheap)
assert_eq!(tree.find_exact(missing), None);
if let Some(idx) = tree.find_exact(q) { /* keys[idx] == q */ }
```
## Batched queries (hide the miss latency)
A single `find_exact` is latency-bound. For a bulk of queries, use the pipelined batch —
`P` queries in flight, each prefetching its next hop:
```rust
// P is the pipeline depth; 16 pegs every core at 100%.
let hits = tree.batch_stream::<16>(&queries); // Vec<Option<usize>>, one per query
```
`batch_prefetch::<P>` and `batch_stream::<P>` return **identical** results to a serial
`find_exact` loop (a tested invariant) — the batch is purely a throughput win.
## mmap-backed (the on-disk column is the leaf layer)
When keys already live in a sorted on-disk column, build only the internal nodes and let
the file *be* the leaves:
```rust
use znippy_zoomies::stree32::STree32Mmap;
// default stride 4 = pure u32 SoA column:
let tree = STree32Mmap::open(path)?;
let hit = tree.find_exact(q);
let hits = tree.lookup_batch_pipeline::<16>(&queries);
// AoS records whose leading 4 bytes are the LE u32 key:
let tree = STree32Mmap::new_with_stride(path, record_size)?;
```
## Verify + bench
```sh
cargo test -p znippy-zoomies --release stree32_bench -- --nocapture # correctness + in-cache micro-bench
cargo test -p znippy-zoomies --release stree32_bench_ram -- --ignored --nocapture # 512 MB RAM-bound (heavy)
```
Expect ~9× over `binary_search` in cache, ~21× RAM-bound at 512 MB (full table in
[`benchmarks.md`](benchmarks.md)).