Cross-referencing an external database during traversal beats paging through results and filtering afterwards.
Non-matching entries still route the traversal, so recall does not collapse at low selectivity.
A predicate is Fn and Sync, since the executor’s threads call it together, and a panic inside it rejects the key.
A VRAM handle refuses a host predicate with Status::Device.
Every long verb’s config takes a progress handler, called with the units finished so far and the units the call finishes if it runs to the end.
Answering ControlFlow::Break(()) stops the call at the next increment boundary.
The handler is FnMut and Send where a predicate is Fn and Sync: it arrives on whichever thread advanced the work and never on two at once, which is what lets it carry a counter or a deadline without a lock of its own.
A panic inside it is read as a stop.
Reports are denominated in whatever the verb consumes: entries for an insertion, queries for a search, re-selected nodes for a refine, an absorb or a split, draws for a sample, shards for a checkpoint, and bytes for a buffer.
How often they arrive is the increment’s size rather than a guarantee, so read the counts and never the number of calls.
What a stop leaves behind is each verb’s own contract.
An insert cannot be stopped: it claims every entry before its first report, ignores a Break, and publishes the whole batch at once.
A stopped search reports Status::Cancelled and leaves no matches.
A stopped refine is the time budget a whole-graph sweep is meant to run under: re-selection claims no identity, and the call still re-links its islands, so the graph stays correct and merely less improved, and it reports Status::Cancelled.
A stopped load creates no index, and a stopped save_buffer leaves no monolith.
API
Types
ProgressCallbackA periodic report of finished and total units; Break stops the call at the next increment wherever the verb can stop, which an insertion cannot.
It runs on whichever thread advanced the work, never on two at once, so it owes Send and may
be FnMut. A panic inside it stops the call like a Break and is re-raised once the call is final.
PredicateA search filter, run on the executor's threads together; a panic rejects the key and is re-raised once the call is final.