# Batches and Arenas

> UStore for Rust

### Receivers & Deferred Calls

A call addresses the head of the database, a transaction, or a snapshot, and never two of them.
`On` is that view: a read passes the `ustore_view_t` it holds, and a write passes its transaction and whether that watches the write.
A view is `Copy` and borrows the database, transaction or snapshot it came from, which is its `Parent` type, so a view of a snapshot has no verb that writes, and only a view of a transaction stages and commits.

The receiver also decides where a verb runs and how it completes, while the verb and its arguments stay the same:

- `database.head().read(..)` runs on the calling thread.
- `database.head().on(&executor).read(..)` blocks on the executor.
- `database.head().deferred(&executor).read(..)` submits the call and answers a `Deferred`.

`Transaction::on` and `Transaction::deferred` are the same for the view of a transaction watching its keys, and `Snapshot::on` and `Snapshot::deferred` for the view of a snapshot.

```rust
use ustore::Watch;

let mut transaction = database.transaction()?;
transaction.view(Watch::Keys).write(people, &entries, Durability::Buffered)?;
let read_stamp = transaction.stage()?;
let commit_stamp = transaction.commit(Durability::Flushed)?;

let snapshot = database.snapshot()?;
let pinned = snapshot.view().read(people, &[ada], &mut arena)?;
assert!(commit_stamp.0 <= snapshot.read_stamp().0);
```

`Watch` says whether the calls of that view record the keys they touch.
It changes what a call does only at `Isolation::Snapshot`, where `Watch::None` lets a transaction commit over a concurrent writer instead of conflicting with it; a strictly serializable transaction puts every read it makes into the one serial order whatever the view says.
Only a transaction watches anything, so the head of a database and a snapshot carry no such argument.

A transaction conflicts rather than blocks, and reports `Status::WriteConflict`, `ReadConflict` or `PhantomConflict` at its commit.
It keeps its contents whatever the outcome, so `Transaction::reset` discards them and reopens it on the newest state for another try.
`Transaction::stage` is the first phase of a two-phase commit and answers a `ReadStamp`, the stamp the transaction reads at and its commit validates against.
`Transaction::commit` answers a `CommitStamp`, the commit's position in commit order, which every snapshot whose `Snapshot::read_stamp` is at or above it sees.
The two are distinct types, so neither is compared with the other by accident.
`Transaction::rollback` withdraws a stage while keeping the reads and writes, so the transaction can stage again.
A snapshot is a handle the database hands out, pinning the state it was taken at until it is dropped, and every view at it borrows it; `Snapshot::save` writes it out as a database of its own.

`On::deferred` makes a `DeferredOn`, whose verbs return once their call is submitted and answer a `Deferred`.
Every verb keeps its name and its arguments, the transaction verbs `stage`, `commit`, `rollback` and `reset`, `save`, `clear`, `compact` and `collection_drop` included, while the inputs it takes must be owned, since the library reads them after the verb returns.
A deferred view takes keys or edges in an array or a `Vec`, keys beside a `BytesTape` of values or a `CharsTape` of JSON, paths in a `CharsTape`, columns in a `Vec<Column<'static>>`, names and save paths as a `String`, and `'static` collections, roles, fields, names and progress handlers, and a borrow of any of them does not compile.
It borrows the arena as a blocking view does, so the result of a deferred read borrows it too.

```rust
use ustore::stringtape::BytesTape;

let deferred = database.head().deferred(&executor);
let names: BytesTape<u32> = [b"Ada".as_slice(), b"Grace"].into_iter().collect();
let (keys, names) = deferred.write(people, (vec![ada, grace], names), Durability::Buffered)?.await?;

let reading = deferred.read(people, vec![ada, grace], &mut arena)?;
let values = reading.await?; // or: reading.wait()?
assert_eq!(values.get(0), Some(b"Ada".as_slice()));

// an executor serves one call at a time, so four scans overlap on four executors, each into an arena of its own
let executors = (0..4).map(|_| Executor::for_ram(&[], 2)).collect::<Result<Vec<_>, _>>()?;
let mut arenas = executors.iter().map(Arena::new_in).collect::<Result<Vec<_>, _>>()?;
let scans = executors.iter().zip(arenas.iter_mut()).zip(starts)
    .map(|((executor, arena), start)| database.head().deferred(executor).scan(people, start, 1000, arena))
    .collect::<Result<Vec<_>, _>>()?;
for scan in scans { consume(scan.await?); }

transaction.deferred(&executor).write(people, (keys, names), Durability::Buffered)?.await?;
let commit_stamp = transaction.deferred(&executor).commit(Durability::Buffered)?.await?;
```

A `Deferred` is `IntoFuture`, so `.await` runs inside an `async` block on any executor of async tasks.
The crate brings none and needs none beyond `std`, where a dozen lines drive one:

```rust
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};

fn block_on<Output>(task: impl Future<Output = Output>) -> Output {
    let mut task = pin!(task);
    let mut context = Context::from_waker(Waker::noop());
    loop {
        if let Poll::Ready(output) = task.as_mut().poll(&mut context) {
            return output;
        }
    }
}

let values = block_on(async { deferred.read(people, vec![ada], &mut arena)?.await })?;
```

`Deferred::status` reads the call's status through `ustore_outcome_status` without blocking: `Err(Status::Deferred)` while the call is not final, `Ok(())` once it succeeded, and its failure otherwise.
`Deferred::wait` blocks until the call is final through `ustore_outcome_wait`.
Every poll of an awaited `Deferred` reads the status the same way, and one not yet final asks to be polled again, since the library has no wake-up, while `wait` blocks without spinning.
Once final, a call hands back what the same blocking call would: a read its `Values` borrowing the arena, writes and removals their inputs as they are, a stage its `ReadStamp`, and a commit its `CommitStamp`.
A call the binding refuses before it reaches the library, such as a tape holding fewer values than keys, fails at the verb itself.
A call the library refuses at submission, such as one finding its executor serving another call with `Status::Contended`, is final at once and fails at `.await` or `wait`.
A transaction serves one call at a time too, so a call on a transaction serving an unfinished deferred one answers `Status::Contended` as well.
A deferred call runs on the executor's first thread in the caller's place, so polling alone finishes it, and its progress handler runs on the executor's threads.

The crate starts no thread and keeps no count of its own.
A deferred call allocates one box holding its outcome, owned inputs and output slots until it is final, while the argument struct is not among them, since submission copies it.
Dropping an unfinished `Deferred` waits for the call, then frees the box, and a panic its progress handler raised resurfaces from `wait`, `.await`, or a drop outside unwinding.
A forgotten one leaks the box rather than lending the library memory it would reuse, and freeing the database, transaction, snapshot or arena the call names waits in C for every deferred call naming it.
`Deferred` is `Send` whenever its inputs are, so a scoped thread waits off the calling thread, as `std::thread::scope(|scope| scope.spawn(move || reading.wait()).join())` does.

### Executors

A view without an executor runs every call on the calling thread.
An `Executor` is the threads that run calls, shared by any number of databases and views, and is `Send` and `Sync`.
An executor serves one call at a time, and a call submitted while another holds it answers `Status::Contended`.

```rust
use ustore::{Arena, Executor, Mood, RocksDBOptions};

let executor = Executor::for_ram(&[], 8)?;             // memory domains, threads
let near = Executor::for_ram(&[0], 0)?;                // 7/8 of the cores local to NUMA node 0
let shared = unsafe { Executor::on_pool(&[], pool)? }; // borrows another library's threads
let people = Database::open_rocksdb(&RocksDBOptions { executor: Some(&executor), ..RocksDBOptions::at("/var/lib/people") })?;
let mut arena = Arena::new_in(&executor)?;
let (names, _) = people.head().on(&executor).collection_find("names", &mut arena)?;
let values = people.head().on(&executor).read(names, &[ada, grace], &mut arena)?;
executor.drain(Mood::Parked)?;
```

`Executor::for_ram` spawns the threads for the RAM, RocksDB and LevelDB engines across the compute domains local to the memory domains it names, NUMA nodes as the operating system numbers them, where an empty list derives every domain the process may allocate on.
The scratch of each thread and every arena the executor makes live on those domains, and an identifier no domain carries is refused with `Status::InvalidArgument`.
Zero threads take 7/8 of the cores those domains carry, leaving the rest to blocking calls and to the background work of RocksDB and LevelDB.
`Executor::on_pool` borrows the threads of a ForkUnion `fu_pool_t`, so several libraries in one process share them, and is `unsafe`, since the pool must outlive the executor.
`Executor::for_nvme` spawns the threads of the NVMe engine, one I/O ring apiece, and its `IOOptions` tell every database opened on it how to move bytes: the transport, the channels and their buffers.
`Executor::for_vram` drives one CUDA device through one stream, its own or one the caller lends, failing with `Status::Unsupported` in a library built without CUDA, and is `unsafe`, since a lent stream must outlive the executor; `NVMEOptions::compactions` places an NVMe database's merges on it.
`On::on` names the executor and keeps the view blocking, so its verbs answer exactly as they do on the calling thread.
`Executor::drain` waits until no call holds the executor, then parks its threads for `Mood::Parked` or keeps them spinning for `Mood::Spinning`, and dropping the executor waits the same way.

Opening a database blocks, and `RAMOptions`, `RocksDBOptions`, `LevelDBOptions` and `NVMEOptions` name the executor the open runs on, where `None` opens on the calling thread.
The NVMe engine reads the `IOOptions` of its executor once, at the open, so the executor may be dropped before the database.

### Arenas

Every output whose length scales with the call, such as values, presence bits, offsets, keys, degrees, edges, bounds, names and columns, lands in an `Arena`, and the verb answers a view over it without copying.
`Arena::new_in(&executor)` places one where that executor computes, decided once, and `Arena::new()` makes host pages for the calling thread; both call `ustore_arena_init`, and dropping one calls `ustore_arena_free`.
A call rewinds its arena and the arena keeps its high-water mark, so a steady loop allocates once.
`Arena::describe` reports where the outputs live, and a view over device memory is refused with `Status::Device` rather than read on the host.
A read through `&mut arena` hands back a result that borrows it, so a value read out of an arena can neither outlive it nor survive the call that would overwrite it.
Every verb takes its arena last, after its inputs and the config that shapes the work, such as the `BlobsScanConfig` of a scan.
A config converts from its most common knob, so `scan(people, ada, 100, &mut arena)` wants 100 keys, and `BlobsScanConfig { matching, ..BlobsScanConfig::from(100) }` reaches every other knob.
Writes export nothing and take no arena, and fixed-size reports, such as stamps, a `Measurement`, a `Description` or a resolved collection, come back as plain values.

The library rewinds an arena on every call through it, so results from one call stop being readable the moment the next one runs.
That rule is the `&mut Arena` every verb takes, blocking or deferred: while a result is alive the arena stays mutably borrowed, and the call that would overwrite it does not compile.

```rust
let values = database.head().read(people, &[ada], &mut arena)?;
let others = database.head().read(people, &[grace], &mut arena)?; // refused while `values` lives
println!("{:?}", values.get(0));

let (mut found, mut fetched) = (Arena::new()?, Arena::new()?);     // two live results, two arenas
for &key in database.head().scan(people, ada, 100, &mut found)?.keys {
    consume(database.head().read(people, &[key], &mut fetched)?);  // rewinds fetched, never found
}
```

Reuse the arena by letting the result fall out of scope: the next call rewinds it and keeps its memory.
To keep one result while making the next, pass the next call another arena.
An arena serves one call at a time, which is why it is `Send` and never shared, and why deferred calls submitted together take one arena each.
The library never frees an arena under a call: dropping one waits for the calls writing into it, and a call naming an arena that serves another call finishes with `Status::Contended`, so even a forgotten `Deferred` leaves it safe.

### Progress & Cancellation

The configs of `compact`, `save` and the scans carry an optional progress handler, an `FnMut(finished, total) -> ControlFlow<()>`, called with the units finished so far and the units the call finishes if it runs to the end.
Answering `ControlFlow::Break(())` cancels the call, which fails with `Status::Cancelled` and publishes nothing.

```rust
use std::ops::ControlFlow;
use std::time::{Duration, Instant};

let deadline = Instant::now() + Duration::from_secs(30);
let mut before_the_deadline = move |_finished: usize, _total: usize| match Instant::now() < deadline {
    true => ControlFlow::Continue(()),
    false => ControlFlow::Break(()),
};
let config = SaveConfig { path: "/var/lib/people-copy", progress: Some(&mut before_the_deadline) };
match snapshot.save(config) {
    Err(failure) if failure.status == ustore::Status::Cancelled => println!("the copy was removed"),
    other => other?,
}
```

The handler arrives on whichever thread advanced the work, never on two at once and never after the call is final, so it is `FnMut` and `Send`, and carries a counter or a deadline without a lock of its own.
A save counts the bytes of the keys and values it wrote, and a cancelled one removes what it wrote, as a failed one does.
A compaction counts the bytes of the collections compacted where the engine measures them, as RocksDB does, and one unit per collection elsewhere, and a cancelled one stops between collections, keeping what it compacted.
A panic inside the handler cancels the call as well, since unwinding out of the C frame would abort, and resurfaces once the call is final: from the blocking verb, or from `wait`, `.await` or the drop of a `Deferred`.
A deferred view takes only a `'static` handler, since the library calls it after the verb returns.

`use ustore::Arena;`

`use ustore::Blocking;`

`use ustore::CPUClass;`

`use ustore::Deferred;`

`use ustore::Deferring;`

`use ustore::Executor;`

`use ustore::GPUClass;`

`use ustore::GPUDevice;`

`use ustore::GPUVendor;`

`use ustore::Gds;`

`use ustore::IOOptions;`

`use ustore::Mood;`

`use ustore::On;`

`use ustore::Residency;`

`use ustore::Transport;`

`use ustore::Wait;`

`use ustore::*;`

## DeferredOn

A view whose verbs defer their calls on an executor, each answering a [`Deferred`](https://www.unum.cloud/docs/ustore/rust/errors.md#Deferred) once submitted.

```rust
pub type DeferredOn<'view, Parent = Database> = On<'view, Parent, Deferring>;
```

## ProgressCallback

A periodic report of the units a call finished and the units it finishes if it runs to the end, where `ControlFlow::Break` cancels the call, which then fails with [`Status::Cancelled`](https://www.unum.cloud/docs/ustore/rust/errors.md#Cancelled) and publishes nothing.

```rust
pub type ProgressCallback<'handler> = dyn FnMut(usize, usize) -> ControlFlow<()> + Send + 'handler;
```

It runs on whichever thread advanced the work, never on two at once and never after the call is final, so it owes
`Send` and may be `FnMut`. A panic inside it cancels the call as well, and resurfaces once the call is final.

Mirrors `ustore_progress_callback_t`.

## Arena

Memory the library writes every output whose length scales with a call into, reused across calls.

```rust
pub struct Arena
```

An executor places it where it computes, decided once, and nothing is allocated until a call writes into it. Every
call rewinds and refills it, invalidating the previous call's outputs, so a steady loop allocates once. Every verb,
blocking or deferred, borrows it as `&mut Arena` and answers outputs that borrow it in turn, so the borrow checker
both keeps a result from outliving its arena and stops the call that would overwrite it.

Mirrors `ustore_arena_t`; dropping it calls `ustore_arena_free`, which waits for the calls still writing into it.

Implements: `Debug`, `Drop`, `Send`

## new

Makes an arena of host pages for calls on the calling thread.

```rust
pub fn new() -> Result<Self>
```

Calls `ustore_arena_init`.

## new_in

Makes an arena where `executor` computes, serving the calls of its residency.

```rust
pub fn new_in(executor: &Executor) -> Result<Self>
```

Calls `ustore_arena_init`.

## describe

Where the outputs live, as the executor that made the arena decided.

```rust
pub fn describe(&self) -> Result<ArenaDescription>
```

Calls `ustore_arena_describe`.

## Blocking

The completion of an [`On`](#On), whose verbs return once their call is final and answer what it produced.

```rust
pub struct Blocking;
```

Implements: `Clone`, `Copy`, `Debug`

## CPUClass

The CPU generation a database confines its waits, atomics and string kernels to, where [`None`](https://www.unum.cloud/docs/ustore/rust/transactions.md#None) takes what the CPU offers.

```rust
pub enum CPUClass
```

Prints and parses its stable name, like "intel-icelake".

- `Serial` = `1`: Portable kernels that run on any CPU.
- `IntelHaswell` = `2`: x86 cores from Intel Haswell on.
- `IntelSierra` = `3`: x86 efficiency cores from Intel Sierra Forest on.
- `IntelSkylake` = `4`: x86 server cores from Intel Skylake on.
- `IntelIcelake` = `5`: x86 server cores from Intel Ice Lake on.
- `AWSG2` = `6`: Arm cores from AWS Graviton 2 on.
- `AppleM2` = `7`: Arm cores from Apple M2 on.
- `AWSG5` = `8`: Arm server cores from AWS Graviton 5 on.
- `AlibabaC930` = `9`: RISC-V cores with RVV, Zawrs and Zacas, from Alibaba's C930 on.
- `Monoversioned` = `10`: The one class of a monoversioned build.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`, `Display`, `FromStr`

## Deferred

A submitted call, which owns its outcome, inputs and output slots in one box the library reads until the call is final, and borrows its arena as a blocking call does.

```rust
pub struct Deferred<Verb: Calling>
```

[`Deferred::status`](#status) polls without blocking, and [`Deferred::wait`](#wait) blocks until the call is final and hands back
what it produced, while `.await` polls it from async code. Dropping an unfinished one waits for it, then frees the
box. A panic its progress handler raised resurfaces from [`wait`](#wait), `.await`, or a drop outside unwinding.

Rust-only; polling calls `ustore_outcome_status`, and waiting and dropping call `ustore_outcome_wait`.

Implements: `Drop`, `Debug`, `Send`, `IntoFuture`

## status

`Err(Status::Deferred)` until the call is final, then its final status, read without blocking.

```rust
pub fn status(&self) -> Result<(), Status>
```

Calls `ustore_outcome_status`.

## wait

Blocks until the call is final, then hands back what it produced.

```rust
pub fn wait(self) -> Result<Verb::Output>
```

Calls `ustore_outcome_wait`.

## Deferring

The completion of a [`DeferredOn`](#DeferredOn), whose verbs return once their call is submitted and answer a [`Deferred`](https://www.unum.cloud/docs/ustore/rust/errors.md#Deferred).

```rust
pub struct Deferring;
```

Implements: `Clone`, `Copy`, `Debug`

## Executor

The threads that run calls, shared by any number of databases and views.

```rust
pub struct Executor
```

Calls on one executor start in submission order, and a blocking call runs alone: after every call submitted before
it finishes, and before any submitted after it starts. An executor holds at most `deferred_limit` deferred calls at
once, so a submission finding its deferred table full finishes at once with [`Status::Contended`](https://www.unum.cloud/docs/ustore/rust/errors.md#Contended). Dropping the
executor drains it.

Implements: `Debug`, `Send`, `Sync`, `Drop`

## for_ram

Spawns host threads for the RAM, RocksDB and LevelDB engines across the compute domains local to `memory_domains`, NUMA nodes as the operating system numbers them, holding up to `deferred_limit` deferred calls at once, or 256 for zero.

```rust
pub fn for_ram(memory_domains: &[i32], threads: usize, deferred_limit: usize) -> Result<Self>
```

An empty list derives every domain the process may allocate on, and an identifier no domain carries is refused
with [`Status::InvalidArgument`](https://www.unum.cloud/docs/ustore/rust/errors.md#InvalidArgument). The scratch of each thread, and every arena the executor makes, lives on the
domains named. Zero `threads` takes 7/8 of the cores those domains carry, rounded down and at least one, which
leaves the rest to the driver thread, to blocking calls and to the background work of RocksDB and LevelDB.

Calls `ustore_executor_for_ram`.

## on_pool

Creates an executor for the RAM, RocksDB and LevelDB engines over a ForkUnion pool it borrows, so several libraries in one process share one set of threads, while it keeps their scratch on `memory_domains`.

```rust
pub unsafe fn on_pool(
    memory_domains: &[i32],
    pool: *mut c_void,
    deferred_limit: usize,
) -> Result<Self>
```

A batch finding the pool running its lender's dispatch runs on the executor's own driver thread instead of
forking over the lender.

Calls `ustore_executor_on_pool`.

Safety: `pool` must address a live ForkUnion `fu_pool_t` that outlives the executor.

## for_nvme

Spawns the threads of the NVMe engine, each submitting and polling its own I/O ring, where zero `threads` derives them from the cores, and tells every database [`Database::open_nvme`](https://www.unum.cloud/docs/ustore/rust/quickstart.md#open_nvme) opens on it to move bytes as `io` says.

```rust
pub fn for_nvme(threads: usize, io: &IOOptions, deferred_limit: usize) -> Result<Self>
```

Calls `ustore_executor_for_nvme`.

## for_vram

Opens one submission stream on `device`, a [`GPUDevice::ordinal`](#GPUDevice) of either vendor, or borrows the caller's `stream`, all of it driven by one host thread - which is why this takes no thread count - moving bytes as `gds` says.

```rust
pub unsafe fn for_vram(
    device: i32,
    stream: *mut c_void,
    scratch_limit: usize,
    gds: Gds,
    deferred_limit: usize,
) -> Result<Self>
```

Zero `scratch_limit` lets scratch grow as calls ask. It fails with [`Status::Device`](https://www.unum.cloud/docs/ustore/rust/errors.md#Device) for an ordinal no
device carries. [`NVMEOptions::compactions`](https://www.unum.cloud/docs/ustore/rust/quickstart.md#NVMEOptions) places the merges of an NVMe database on one of an NVIDIA device.

Calls `ustore_executor_for_vram`.

Safety: `stream` must be null or a live stream on `device` that outlives the executor: a `cudaStream_t` on NVIDIA and a
`hipStream_t` on AMD.

## drain

Waits for every call submitted before the drain began, then leaves the threads in `mood` whenever they next go idle.

```rust
pub fn drain(&self, mood: Mood) -> Result<()>
```

## GPUClass

The generation of a GPU, as `ustore_gpu_class_t` spells it, like "nvidia-hopper".

```rust
pub enum GPUClass
```

- `NvidiaAmpere` = `1`: Ampere-class NVIDIA and every NVIDIA GPU without a class of its own - A100, A10 & RTX 30.
- `NvidiaAda` = `2`: Ada-class NVIDIA - L4, L40S & RTX 40.
- `NvidiaHopper` = `3`: Hopper-class NVIDIA - H100 & H200.
- `NvidiaBlackwell` = `4`: Blackwell-class NVIDIA - B200, B300 & GB300.
- `NvidiaBlackwellRTX` = `5`: Consumer Blackwell NVIDIA - RTX 50, RTX PRO 6000 & DGX Spark.
- `AmdCDNA3` = `6`: CDNA3 AMD - MI300X & MI325X.
- `AmdCDNA4` = `7`: CDNA4 AMD - MI350X & MI355X.
- `AmdCDNA5` = `8`: CDNA5 AMD - MI400.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`, `Display`, `FromStr`

## GPUDevice

One GPU this process can drive, as [`gpu_devices`](#gpu_devices) lists it.

```rust
pub struct GPUDevice
```

- `ordinal` `usize`: The ordinal [`Executor::for_vram`](#for_vram) names the device by, its position in [`gpu_devices`](#gpu_devices).
- `vendor` `GPUVendor`: The vendor whose runtime drives the device.
- `vendor_ordinal` `u32`: The device's ordinal in its vendor's runtime, as `nvidia-smi` or `rocm-smi` list it.
- `gpu_class` `GPUClass`: The class of the device.
- `compute_units` `u32`: Streaming multiprocessors or compute units.
- `memory_bytes` `u64`: Device memory in bytes.
- `name` `String`: The vendor's own name for the device.

Implements: `Clone`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`

## GPUVendor

The vendor whose runtime drives a GPU, as `ustore_gpu_vendor_t` spells it, like "amd".

```rust
pub enum GPUVendor
```

- `Nvidia` = `1`: NVIDIA, through the CUDA driver.
- `Amd` = `2`: AMD, through the HIP runtime.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`, `Display`, `FromStr`

## Gds

How an executor of [`Executor::for_vram`](#for_vram) moves bytes between the drives and its device through GPUDirect Storage, as `ustore_gds_t` spells it.

```rust
pub enum Gds
```

- `Automatic` = `0`: Direct transfers where the `nvidia_fs` driver is loaded, and cuFile's compatibility mode elsewhere.
- `Direct` = `1`: Direct transfers, refused with [`Status::Device`](https://www.unum.cloud/docs/ustore/rust/errors.md#Device) where the driver is absent.
- `Compatibility` = `2`: cuFile's compatibility mode, which bounces through host pages it manages.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Default`, `Hash`, `Display`, `FromStr`

## IOOptions

How the threads of an executor of [`Executor::for_nvme`](#for_nvme) move bytes between the drives and memory, where every zero size or count keeps the engine's default.

```rust
pub struct IOOptions
```

- `transport` `Transport`: How bytes move between the files and memory.
- `shared_io_channels` `usize`: I/O channels the threads outside the executor share.
- `queue_depth` `usize`: Submissions a channel holds at once.
- `request_buffer_bytes` `u64`: Bytes of each request buffer of a channel.
- `request_buffers_count` `usize`: Request buffers of each channel.
- `stream_buffer_bytes` `u64`: Bytes of each streaming buffer of a channel.
- `stream_buffers_count` `usize`: Streaming buffers of each channel.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Default`, `Hash`

## Mood

What the threads of an [`Executor`](#Executor) do once it goes idle, as `ustore_mood_t` spells it.

```rust
pub enum Mood
```

- `Parked` = `0`: Parked, so the next call pays a wake-up.
- `Spinning` = `1`: Spinning, trading power for the next call's latency.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`, `Display`, `FromStr`

## On

The one view a call addresses: the head of a [`Database`](https://www.unum.cloud/docs/ustore/rust/quickstart.md#Database), a [`Transaction`](https://www.unum.cloud/docs/ustore/rust/transactions.md#Transaction), or a [`Snapshot`](https://www.unum.cloud/docs/ustore/rust/snapshots.md#Snapshot), which is its `Parent`, with the executor its calls run on and how they complete.

```rust
pub struct On<'view, Parent = Database, Completion = Blocking>
```

Every read, write and scan hangs off this type, so a call naming two views at once cannot be written. Reads
pass the `ustore_view_t` it holds, writes pass its transaction and whether that watches them, and the view is
as cheap to copy as the handles it borrows from its parent.

The parent decides which verbs exist beyond the reads every view serves: the head and a transaction write, only
the head clears, compacts and drops collections, only a transaction stages, commits, rolls back and resets, and
only a snapshot saves.

Every verb of a blocking view returns once its call is final and answers what it produced, on the calling thread
or, after [`On::on`](https://www.unum.cloud/docs/ustore/rust/snapshots.md#on), on that executor. The same verb of a [`DeferredOn`](#DeferredOn), which
[`On::deferred`](https://www.unum.cloud/docs/ustore/rust/snapshots.md#deferred) makes, returns once its call is submitted and answers a [`Deferred`](https://www.unum.cloud/docs/ustore/rust/errors.md#Deferred).

Implements: `Debug`, `Clone`, `Copy`

## write

Upserts a batch of values, where an empty value is still a value and [`On::remove`](https://www.unum.cloud/docs/ustore/rust/documents.md#remove) removes keys.

```rust
pub fn write<'collections, Entries: Pairs>(
    &self,
    collections: impl Into<Collections<'collections>>,
    entries: Entries,
    durability: Durability,
) -> Completion::Answer<Write<'collections, Entries>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Entries>,
```

The entries are borrowed [`Entry`](https://www.unum.cloud/docs/ustore/rust/reads-and-writes.md#Entry) values, or owned keys beside a `stringtape::BytesTape` of their values with
32-bit or 64-bit offsets, which a deferred write needs, and the call hands them back. The batch spans as many
collections as it has entries, and a bare [`CollectionID`](https://www.unum.cloud/docs/ustore/rust/collections.md#CollectionID) gives every entry the same one. A transaction
flushes at its commit, so [`Durability::Flushed`](https://www.unum.cloud/docs/ustore/rust/reads-and-writes.md#Flushed) is refused inside one.

Calls `ustore_blobs_write`.

## remove

Removes a batch of keys with their values, whether or not the database holds them, and hands the keys back.

```rust
pub fn remove<'collections, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    durability: Durability,
) -> Completion::Answer<Remove<'collections, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys>,
```

Calls `ustore_blobs_remove`.

## remove_range

Removes every key of one collection from `range.start`, inclusive, to `range.end`, exclusive, with its value, in one atomic call.

```rust
pub fn remove_range(
    &self,
    collection: CollectionID,
    range: Range<Key>,
    durability: Durability,
) -> Completion::Answer<RemoveRange>
```

## read

Reads a batch of keys into the arena, one collection per key or one for all of them, and hands back the [`Values`](https://www.unum.cloud/docs/ustore/rust/reads-and-writes.md#Values).

```rust
pub fn read<'arena, 'collections, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    arena: &'arena mut Arena,
) -> Completion::Answer<Read<'arena, 'collections, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys>,
```

Calls `ustore_blobs_read`.

## read_slices

Reads the same byte range of every value of a batch into the arena, as [`On::read`](#read) reads whole values, where a range past the end of a value reads empty and one running past it stops there.

```rust
pub fn read_slices<'arena, 'collections, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    bytes: impl RangeBounds<u64>,
    arena: &'arena mut Arena,
) -> Completion::Answer<Read<'arena, 'collections, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys>,
```

## scan

Lists up to `wanted` keys of one collection's `range` into the arena, keeping those its `matching` admits, while a [`Cursor`](https://www.unum.cloud/docs/ustore/rust/scans.md#Cursor) walks one with its values.

```rust
pub fn scan<'config, 'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<BlobsScanConfig<'config>>,
    arena: &'arena mut Arena,
) -> Completion::Answer<Scan<'arena, 'config>>
where
    Completion: Accepts<BlobsScanConfig<'config>>,
```

Weighted patterns write one
BM25 score per key beside them.

Calls `ustore_blobs_scan`.

## sample

Draws up to `wanted` keys uniformly at random from one collection into the arena.

```rust
pub fn sample<'arena>(
    &self,
    collection: CollectionID,
    config: impl Into<BlobsSampleConfig>,
    arena: &'arena mut Arena,
) -> Completion::Answer<Sample<'arena>>
```

Calls `ustore_blobs_sample`.

## measure

Estimates the keys and the space a range of keys takes in one collection, through the arena its bounds land in.

```rust
pub fn measure<'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    arena: &'arena mut Arena,
) -> Completion::Answer<Measure<'arena>>
```

Calls `ustore_blobs_measure`.

## cursor

Opens a walk over the keys of one collection's `range`, reading nothing until its first pull, which then sees what this view sees, pull by pull, on this view's executor.

```rust
pub fn cursor(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<BlobsCursorConfig<'view>>,
) -> Result<Cursor<'view>>
```

The cursor holds the database open, and the transaction or snapshot this view reads through, until it is
dropped.

The patterns of `matching` are compiled here once, and its predicate is asked on every pull, so it lives as long
as the cursor.

Calls `ustore_blobs_cursor_init`.

## contains

Which of [`keys`](https://www.unum.cloud/docs/ustore/rust/scans.md#keys) one collection holds, exporting no value.

```rust
pub fn contains<'arena>(
    &self,
    collection: CollectionID,
    keys: &[Key],
    arena: &'arena mut Arena,
) -> Result<Bitmap<'arena>>
```

## on

This view with every call through it running on `executor`, after the calls submitted there before it.

```rust
pub fn on<'with>(self, executor: &'with Executor) -> On<'with, Parent, Completion>
where
    'view: 'with,
```

## deferred

This view with every verb through it deferred on `executor`, answering a [`Deferred`](https://www.unum.cloud/docs/ustore/rust/errors.md#Deferred) once submitted.

```rust
pub fn deferred<'with>(self, executor: &'with Executor) -> DeferredOn<'with, Parent>
where
    'view: 'with,
```

## collection_list

Every collection the database holds at this view's snapshot or at the head, exported into the arena.

```rust
pub fn collection_list<'arena>(
    &self,
    arena: &'arena mut Arena,
) -> Completion::Answer<CollectionList<'arena>>
```

Calls `ustore_collection_list`.

## collection_drop

Removes the contents of a collection, or the collection itself together with its name, which only the head does, since collections are created and dropped nowhere else.

```rust
pub fn collection_drop(
    &self,
    collection: CollectionID,
    mode: DropMode,
) -> Completion::Answer<CollectionDrop>
```

Calls `ustore_collection_drop`.

## clear

Empties every collection at once, as [`On::collection_drop`](#collection_drop) empties one: every pair, keeping the collections and their names; every collection with its name; or every value, keeping the keys where the engine can.

```rust
pub fn clear(&self, mode: DropMode) -> Completion::Answer<Clear>
```

The RAM and RocksDB engines refuse to drop the collections while a snapshot is open, with
[`Status::InvalidArgument`](https://www.unum.cloud/docs/ustore/rust/errors.md#InvalidArgument), since the snapshot belongs to its holder.

Calls `ustore_database_clear`.

## compact

Reclaims the space overwritten and removed data still takes: RocksDB and LevelDB flush and compact their trees, and the RAM engine frees the versions no reader needs and rewrites its image.

```rust
pub fn compact<'config>(
    &self,
    config: impl Into<CompactConfig<'config>>,
) -> Completion::Answer<Compact<'config>>
where
    Completion: Accepts<CompactConfig<'config>>,
```

The work runs one collection at a time, and `progress` counts the bytes of the collections compacted where the
engine measures them, as RocksDB does, and one unit per collection elsewhere. A cancelled compaction stops
between collections, keeping what it compacted.

Calls `ustore_database_compact`.

## flush

Makes every commit that returned before this call durable, as if each had asked for [`Durability::Flushed`](https://www.unum.cloud/docs/ustore/rust/reads-and-writes.md#Flushed).

```rust
pub fn flush(&self) -> Completion::Answer<Flush>
```

LevelDB syncs only its current log, so a commit in a log it already
rotated stays unsynced until its compaction lands.

Calls `ustore_database_flush`.

## stage

Stages the writes of this view's transaction as the first phase of a two-phase commit, reporting the stamp the transaction reads at.

```rust
pub fn stage(&self) -> Completion::Answer<Stage>
```

## commit

Commits the writes of this view's transaction, reporting the commit's position in commit order.

```rust
pub fn commit(&self, durability: Durability) -> Completion::Answer<Commit>
```

## rollback

Withdraws a stage of this view's transaction, releasing whatever it claimed, while keeping the reads and writes to stage again.

```rust
pub fn rollback(&self) -> Completion::Answer<Rollback>
```

## reset

Discards the reads and writes of this view's transaction and reopens it on the newest state, keeping its handle.

```rust
pub fn reset(&self) -> Completion::Answer<Reset>
```

## save

Writes the snapshot this view reads out as a new database of the same engine, which that engine's open then serves, holding exactly the collections and names the snapshot records, whatever changed since.

```rust
pub fn save<'config, Path: AsRef<str>>(
    &self,
    config: impl Into<SaveConfig<'config, Path>>,
) -> Completion::Answer<Save<'config, Path>>
where
    Completion: Accepts<SaveConfig<'config, Path>>,
```

RocksDB and LevelDB create `path`, while the RAM engine writes its image into the existing directory `path`
names. `progress` counts the bytes of the keys and values saved, and a save it cancels removes what it wrote,
as a failed one does.

Calls `ustore_snapshot_save`.

## docs_write

Writes whole documents or values into fields inside them, where [`On::docs_remove`](#docs_remove) removes documents and a merge with a JSON `null` removes a field, and hands what it wrote back.

```rust
pub fn docs_write<'collections, Documents: Writes>(
    &self,
    collections: impl Into<Collections<'collections>>,
    documents: Documents,
    modification: Modification,
    durability: Durability,
) -> Completion::Answer<DocsWrite<'collections, Documents>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Documents>,
```

The batch is one of:

- borrowed [`DocumentEntry`](https://www.unum.cloud/docs/ustore/rust/documents.md#DocumentEntry) values of one format, which is [`Json`](https://www.unum.cloud/docs/ustore/rust/platform-notes.md#Json) for the text the engine parses and a
[`WritableScalar`](https://www.unum.cloud/docs/ustore/rust/documents.md#WritableScalar) or [`Text`](https://www.unum.cloud/docs/ustore/rust/platform-notes.md#Text) for a document that is one scalar;

- [`KeyedBy`](https://www.unum.cloud/docs/ustore/rust/documents.md#KeyedBy) documents, carrying their keys under a field of their own;

- borrowed [`FieldEntry`](https://www.unum.cloud/docs/ustore/rust/documents.md#FieldEntry) values of one format, writing into fields of existing documents;

- the owned forms a deferred write needs: keys beside a `stringtape::CharsTape` of JSON texts, keys and a tape
of paths beside a tape of JSON values, or a tape of JSON texts keyed by a field.

A transaction flushes at its commit, so [`Durability::Flushed`](https://www.unum.cloud/docs/ustore/rust/reads-and-writes.md#Flushed) is refused inside one.

Calls `ustore_docs_write`.

## docs_remove

Removes a batch of whole documents, whether or not the collections hold them, and hands the keys back.

```rust
pub fn docs_remove<'collections, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    durability: Durability,
) -> Completion::Answer<DocsRemove<'collections, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys>,
```

Calls `ustore_docs_remove`.

## docs_remove_range

Removes every document of one collection from `range.start`, inclusive, to `range.end`, exclusive, in one atomic call.

```rust
pub fn docs_remove_range(
    &self,
    collection: CollectionID,
    range: Range<Key>,
    durability: Durability,
) -> Completion::Answer<DocsRemoveRange>
```

## docs_scan

Lists up to `wanted` document keys of one collection's `range` into the arena, keeping those whose document the filter of `matching` admits and the keys its predicate admits.

```rust
pub fn docs_scan<'config, 'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<DocsScanConfig<'config>>,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsScan<'arena, 'config>>
where
    Completion: Accepts<DocsScanConfig<'config>>,
```

Calls `ustore_docs_scan`.

## docs_sample

Draws up to `wanted` document keys uniformly at random from one collection into the arena.

```rust
pub fn docs_sample<'arena>(
    &self,
    collection: CollectionID,
    config: impl Into<DocsSampleConfig>,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsSample<'arena>>
```

## docs_measure

Estimates the documents and the space a range of keys takes in one collection, through the arena its bounds land in.

```rust
pub fn docs_measure<'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsMeasure<'arena>>
```

## docs_read

Reads whole documents or fields inside them into the arena in `format`, [`Json`](https://www.unum.cloud/docs/ustore/rust/platform-notes.md#Json) or [`Text`](https://www.unum.cloud/docs/ustore/rust/platform-notes.md#Text), reporting a missing document or field as absent.

```rust
pub fn docs_read<'arena, 'collections, Targets: Addresses, Format: ReadFormat>(
    &self,
    collections: impl Into<Collections<'collections>>,
    targets: Targets,
    format: Format,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsRead<'arena, 'collections, Targets>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Targets>,
```

The batch is keys of whole documents, borrowed [`FieldAddress`](https://www.unum.cloud/docs/ustore/rust/documents.md#FieldAddress) values, or owned keys beside a
`stringtape::CharsTape` of paths, a path per key, which a deferred read needs.

Calls `ustore_docs_read`.

## docs_gist

Lists the unique paths to the leaves of the documents under [`keys`](https://www.unum.cloud/docs/ustore/rust/scans.md#keys) into the arena.

```rust
pub fn docs_gist<'arena, 'collections, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsGist<'arena, 'collections, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys>,
```

Calls `ustore_docs_gist`.

## docs_gather

Reads [`columns`](https://www.unum.cloud/docs/ustore/rust/documents.md#columns) of the documents under [`keys`](https://www.unum.cloud/docs/ustore/rust/scans.md#keys) into typed columns in the arena, a row per key.

```rust
pub fn docs_gather<'arena, 'collections, Keys: AsRef<[Key]>, Requested>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    config: impl Into<DocsGatherConfig<Requested>>,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsGather<'arena, 'collections, Keys, Requested>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Requested>,
    DocsGather<'arena, 'collections, Keys, Requested>: Calling,
```

The answered [`Columns`](https://www.unum.cloud/docs/ustore/rust/documents.md#Columns) hold the requested columns, borrowed or owned, while a deferred gather needs owned
keys and owned columns, whose paths are owned or `'static`.

Calls `ustore_docs_gather`.

## docs_cursor

Opens a walk over the keys of one documents collection's `range`, compiling what `matching` names once, whose predicate lives as long as the cursor.

```rust
pub fn docs_cursor(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<DocsCursorConfig<'view>>,
) -> Result<DocsCursor<'view>>
```

Calls `ustore_docs_cursor_init`.

## graph_write_edges

Inserts edges between existing or new vertices, keeping an edge the graph already holds, and hands the edges back.

```rust
pub fn graph_write_edges<'collections, Edges: AsRef<[Edge]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    edges: Edges,
    durability: Durability,
) -> Completion::Answer<GraphWriteEdges<'collections, Edges>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Edges>,
```

A transaction flushes at its commit, so [`Durability::Flushed`](https://www.unum.cloud/docs/ustore/rust/reads-and-writes.md#Flushed) is refused inside one.

Calls `ustore_graph_write_edges`.

## graph_remove_edges

Removes edges by source, target and identifier, whether or not the graph holds them, and hands the edges back.

```rust
pub fn graph_remove_edges<'collections, Edges: AsRef<[Edge]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    edges: Edges,
    durability: Durability,
) -> Completion::Answer<GraphRemoveEdges<'collections, Edges>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Edges>,
```

Calls `ustore_graph_remove_edges`.

## graph_write_vertices

Inserts vertices without edges, keeping every vertex the graph already holds as it is, and hands the vertices back.

```rust
pub fn graph_write_vertices<'collections, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    vertices: Keys,
    durability: Durability,
) -> Completion::Answer<GraphWriteVertices<'collections, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys>,
```

Calls `ustore_graph_write_vertices`.

## graph_remove_vertices

Removes vertices together with every edge they play `roles` in, which only a joining graph needs, and hands the vertices back.

```rust
pub fn graph_remove_vertices<'inputs, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'inputs>>,
    vertices: Keys,
    roles: Roles<'inputs>,
    durability: Durability,
) -> Completion::Answer<GraphRemoveVertices<'inputs, Keys>>
where
    Completion: Accepts<Collections<'inputs>> + Accepts<Keys> + Accepts<Roles<'inputs>>,
```

Calls `ustore_graph_remove_vertices`.

## graph_remove_vertices_range

Removes every vertex of one graph collection from `range.start`, inclusive, to `range.end`, exclusive, together with every edge it plays `role` in, in one atomic call.

```rust
pub fn graph_remove_vertices_range(
    &self,
    collection: CollectionID,
    range: Range<Key>,
    role: Role,
    durability: Durability,
) -> Completion::Answer<GraphRemoveVerticesRange>
```

## graph_degrees

The degree of every vertex in `roles`, exported into the arena without a single edge.

```rust
pub fn graph_degrees<'arena, 'inputs, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'inputs>>,
    vertices: Keys,
    roles: Roles<'inputs>,
    arena: &'arena mut Arena,
) -> Completion::Answer<GraphDegrees<'arena, 'inputs, Keys>>
where
    Completion: Accepts<Collections<'inputs>> + Accepts<Keys> + Accepts<Roles<'inputs>>,
```

Calls `ustore_graph_read_edges`.

## graph_read_edges

The degree and the edges of every vertex in `roles`, exported into the arena as [`Neighborhoods`](https://www.unum.cloud/docs/ustore/rust/graphs.md#Neighborhoods).

```rust
pub fn graph_read_edges<'arena, 'inputs, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'inputs>>,
    vertices: Keys,
    roles: Roles<'inputs>,
    arena: &'arena mut Arena,
) -> Completion::Answer<GraphReadEdges<'arena, 'inputs, Keys>>
where
    Completion: Accepts<Collections<'inputs>> + Accepts<Keys> + Accepts<Roles<'inputs>>,
```

Calls `ustore_graph_read_edges`.

## graph_scan_vertices

Lists up to `wanted` vertices of one graph collection's `range` into the arena, those without edges included, keeping those the predicate of its `matching` admits, while [`On::graph_read_edges`](#graph_read_edges) reads their edges.

```rust
pub fn graph_scan_vertices<'config, 'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<GraphScanVerticesConfig<'config>>,
    arena: &'arena mut Arena,
) -> Completion::Answer<GraphScanVertices<'arena, 'config>>
where
    Completion: Accepts<GraphScanVerticesConfig<'config>>,
```

Calls `ustore_graph_scan_vertices`.

## graph_sample_vertices

Draws up to `wanted` vertices uniformly at random from one graph collection into the arena.

```rust
pub fn graph_sample_vertices<'arena>(
    &self,
    collection: CollectionID,
    config: impl Into<GraphSampleVerticesConfig>,
    arena: &'arena mut Arena,
) -> Completion::Answer<GraphSampleVertices<'arena>>
```

Calls `ustore_graph_sample_vertices`.

## graph_measure_vertices

Estimates the vertices and the space a range of them takes in one graph collection, through the arena its bounds land in.

```rust
pub fn graph_measure_vertices<'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    arena: &'arena mut Arena,
) -> Completion::Answer<GraphMeasureVertices<'arena>>
```

Calls `ustore_graph_measure_vertices`.

## graph_vertices_cursor

Opens a walk over the vertices of one graph collection's `range`, whose predicate lives as long as the cursor.

```rust
pub fn graph_vertices_cursor(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<GraphVerticesCursorConfig<'view>>,
) -> Result<GraphVerticesCursor<'view>>
```

Calls `ustore_graph_vertices_cursor_init`.

## pages_import

Replaces whole pages with parsed markup, one per key, minting a key for every element.

```rust
pub fn pages_import<'collections, 'config, 'texts, Keys: AsRef<[Key]>, Markups: AsRef<[&'texts str]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    markups: Markups,
    config: impl Into<PagesImportConfig<'config>>,
    durability: Durability,
) -> Completion::Answer<PagesImport<'collections, 'config, Keys, Markups>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Markups> + Accepts<PagesImportConfig<'config>>,
```

Calls `ustore_pages_import`.

## pages_insert

Parses one fragment per task into elements under a parent after an anchor of the page [`keys`](https://www.unum.cloud/docs/ustore/rust/scans.md#keys) names, and hands back the key every first element ended up with, given or minted, from the arena.

```rust
pub fn pages_insert<'arena, 'collections, 'config, 'texts, Keys: AsRef<[Key]>, Fragments: AsRef<[&'texts str]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    fragments: Fragments,
    config: impl Into<PagesInsertConfig<'config>>,
    arena: &'arena mut Arena,
    durability: Durability,
) -> Completion::Answer<PagesInsert<'arena, 'collections, 'config, Keys, Fragments>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Fragments> + Accepts<PagesInsertConfig<'config>>,
```

Calls `ustore_pages_insert`.

## pages_remove

Removes one element per task with its subtree, where the Nil element [`Key::default`](https://www.unum.cloud/docs/ustore/rust/collections.md#Key) removes the whole page.

```rust
pub fn pages_remove<'collections, Keys: AsRef<[Key]>, Elements: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    elements: Elements,
    durability: Durability,
) -> Completion::Answer<PagesRemove<'collections, Keys, Elements>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Elements>,
```

Calls `ustore_pages_remove`.

## pages_move

Moves one element per task with its subtree under a parent after an anchor, keeping its key, where empty `parents` stand for the root and empty `anchors` for the front.

```rust
pub fn pages_move<'collections, Keys, Elements, Parents, Anchors>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    elements: Elements,
    parents: Parents,
    anchors: Anchors,
    durability: Durability,
) -> Completion::Answer<PagesMove<'collections, Keys, Elements, Parents, Anchors>>
where
    Keys: AsRef<[Key]>,
    Elements: AsRef<[Key]>,
    Parents: AsRef<[Key]>,
    Anchors: AsRef<[Key]>,
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Elements> + Accepts<Parents> + Accepts<Anchors>,
```

Calls `ustore_pages_move`.

## pages_splice

Replaces `lengths` bytes of the text of one element per task from `starts` on with `texts`, where a zero length only inserts and an empty text only removes.

```rust
pub fn pages_splice<'collections, 'texts, Keys, Elements, Starts, Lengths, Texts>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    elements: Elements,
    starts: Starts,
    lengths: Lengths,
    texts: Texts,
    durability: Durability,
) -> Completion::Answer<PagesSplice<'collections, Keys, Elements, Starts, Lengths, Texts>>
where
    Keys: AsRef<[Key]>,
    Elements: AsRef<[Key]>,
    Starts: AsRef<[u64]>,
    Lengths: AsRef<[u64]>,
    Texts: AsRef<[&'texts str]>,
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Elements> + Accepts<Starts> + Accepts<Lengths> + Accepts<Texts>,
```

Calls `ustore_pages_splice`.

## pages_set_attributes

Sets one attribute of one element per task, adding the ones it lacks.

```rust
pub fn pages_set_attributes<'collections, 'texts, Keys, Elements, Fields, Texts>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    elements: Elements,
    fields: Fields,
    values: Texts,
    durability: Durability,
) -> Completion::Answer<PagesSetAttributes<'collections, Keys, Elements, Fields, Texts>>
where
    Keys: AsRef<[Key]>,
    Elements: AsRef<[Key]>,
    Fields: AsRef<[&'texts str]>,
    Texts: AsRef<[&'texts str]>,
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Elements> + Accepts<Fields> + Accepts<Texts>,
```

Calls `ustore_pages_set_attributes`.

## pages_remove_attributes

Removes one attribute of one element per task.

```rust
pub fn pages_remove_attributes<'collections, 'texts, Keys, Elements, Fields>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    elements: Elements,
    fields: Fields,
    durability: Durability,
) -> Completion::Answer<PagesRemoveAttributes<'collections, Keys, Elements, Fields>>
where
    Keys: AsRef<[Key]>,
    Elements: AsRef<[Key]>,
    Fields: AsRef<[&'texts str]>,
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<Elements> + Accepts<Fields>,
```

Calls `ustore_pages_remove_attributes`.

## pages_read

Reads whole pages, or chosen elements of them, as markup into the arena.

```rust
pub fn pages_read<'arena, 'collections, 'config, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    keys: Keys,
    config: impl Into<PagesReadConfig<'config>>,
    arena: &'arena mut Arena,
) -> Completion::Answer<PagesRead<'arena, 'collections, 'config, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Keys> + Accepts<PagesReadConfig<'config>>,
```

Calls `ustore_pages_read`.

## pages_scan

Lists up to `wanted` page keys of one collection's `range` into the arena, keeping those its `matching` admits, while [`On::pages_read`](#pages_read) renders them.

```rust
pub fn pages_scan<'config, 'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<PagesScanConfig<'config>>,
    arena: &'arena mut Arena,
) -> Completion::Answer<PagesScan<'arena, 'config>>
where
    Completion: Accepts<PagesScanConfig<'config>>,
```

Calls `ustore_pages_scan`.

## pages_sample

Draws up to `wanted` page keys uniformly at random from one pages collection into the arena.

```rust
pub fn pages_sample<'arena>(
    &self,
    collection: CollectionID,
    config: impl Into<PagesSampleConfig>,
    arena: &'arena mut Arena,
) -> Completion::Answer<PagesSample<'arena>>
```

Calls `ustore_pages_sample`.

## pages_measure

Estimates the pages and the space a range of page keys takes in one collection, through the arena its bounds land in.

```rust
pub fn pages_measure<'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    arena: &'arena mut Arena,
) -> Completion::Answer<PagesMeasure<'arena>>
```

Calls `ustore_pages_measure`.

## pages_cursor

Opens a walk over the keys of one pages collection's `range`, compiling its filter once, whose predicate lives as long as the cursor.

```rust
pub fn pages_cursor(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    config: impl Into<PagesCursorConfig<'view>>,
) -> Result<PagesCursor<'view>>
```

Calls `ustore_pages_cursor_init`.

## strings_write

Upserts a batch of strings and the keys they map onto, one key per string.

```rust
pub fn strings_write<'collections, Strs: Texts, Keys: AsRef<[Key]>>(
    &self,
    collections: impl Into<Collections<'collections>>,
    strings: Strs,
    keys: Keys,
    durability: Durability,
) -> Completion::Answer<StringsWrite<'collections, Strs, Keys>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Strs> + Accepts<Keys>,
```

The strings are a borrowed `&[&str]`, or an owned `stringtape::CharsTape`, which a deferred
write needs beside owned keys, and the call hands both back. A bare [`CollectionID`](https://www.unum.cloud/docs/ustore/rust/collections.md#CollectionID) gives
every string the same collection.

Calls `ustore_strings_write`.

## strings_remove

Removes a batch of strings with their keys, whether or not the database holds them, and hands the strings back.

```rust
pub fn strings_remove<'collections, Strs: Texts>(
    &self,
    collections: impl Into<Collections<'collections>>,
    strings: Strs,
    durability: Durability,
) -> Completion::Answer<StringsRemove<'collections, Strs>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Strs>,
```

Calls `ustore_strings_remove`.

## strings_read

Reads the keys a batch of strings map onto into the arena, one collection per string or one for all of them.

```rust
pub fn strings_read<'arena, 'collections, Strs: Texts>(
    &self,
    collections: impl Into<Collections<'collections>>,
    strings: Strs,
    arena: &'arena mut Arena,
) -> Completion::Answer<StringsRead<'arena, 'collections, Strs>>
where
    Completion: Accepts<Collections<'collections>> + Accepts<Strs>,
```

Calls `ustore_strings_read`.

## strings_scan

Lists up to `wanted` strings of one collection's `range` into the arena, keeping those its `matching` admits.

```rust
pub fn strings_scan<'config, 'arena, 'text>(
    &self,
    collection: CollectionID,
    range: impl Into<TextRange<'text>>,
    config: impl Into<StringsScanConfig<'config>>,
    arena: &'arena mut Arena,
) -> Completion::Answer<StringsScan<'arena, 'text, 'config>>
where
    Completion: Accepts<TextRange<'text>> + Accepts<StringsScanConfig<'config>>,
```

Weighted patterns write one BM25 score per string beside them.

Calls `ustore_strings_scan`.

## strings_sample

Draws up to `wanted` strings uniformly at random from one collection into the arena.

```rust
pub fn strings_sample<'arena>(
    &self,
    collection: CollectionID,
    config: impl Into<StringsSampleConfig>,
    arena: &'arena mut Arena,
) -> Completion::Answer<StringsSample<'arena>>
```

Calls `ustore_strings_sample`.

## strings_measure

Estimates the strings and the space between two strings of one collection, through the arena its bounds land in.

```rust
pub fn strings_measure<'arena, 'text>(
    &self,
    collection: CollectionID,
    range: Range<&'text str>,
    arena: &'arena mut Arena,
) -> Completion::Answer<StringsMeasure<'arena, 'text>>
where
    Completion: Accepts<Range<&'text str>>,
```

Calls `ustore_strings_measure`.

## collection_find

The collection `name` addresses and the modality it holds, which [`crate::Database::collection_create`](https://www.unum.cloud/docs/ustore/rust/quickstart.md#collection_create) bound, resolved through the arena.

```rust
pub fn collection_find<'arena, Name: AsRef<str>>(
    &self,
    name: Name,
    arena: &'arena mut Arena,
) -> Completion::Answer<CollectionFind<'arena, Name>>
where
    Completion: Accepts<Name>,
```

Collections are created and dropped only at the head, so names are read at the view's snapshot, or at the
head for a transaction or the head itself, and never join a transaction's conflicts.

Calls `ustore_collection_find`.

## collection_names

Lists up to `wanted` collection names under `prefix` into the arena, in the order of their text, from `start` on where one is given.

```rust
pub fn collection_names<'arena, Name: AsRef<str>>(
    &self,
    prefix: Name,
    start: Option<Name>,
    wanted: usize,
    arena: &'arena mut Arena,
) -> Completion::Answer<CollectionNames<'arena, Name>>
where
    Completion: Accepts<Name>,
```

An engine lists its collections in an order of its own, so the names are sorted here. A listing
describes the database rather than a transaction, so it reads the view's snapshot or the head.

Calls `ustore_collection_list`.

## Residency

Where an [`Arena`](#Arena)'s outputs live.

```rust
pub enum Residency
```

- `Ram` = `1`: Host pages, which the calling thread reads in place.
- `Vram` = `2`: One device's memory, which only that device's code reads.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`

## Transport

How the NVMe engine moves bytes between its files and memory.

```rust
pub enum Transport
```

- `Automatic` = `0`: io_uring where the kernel offers it, Linux AIO where it offers only that, and blocking calls elsewhere.
- `Blocking` = `1`: Positioned reads and writes that block the polling thread, which every platform has.
- `LinuxUring` = `2`: io_uring on unbuffered files, refused where the kernel creates no ring.
- `LinuxAio` = `3`: Linux AIO on unbuffered files.
- `LinuxSpdk` = `4`: SPDK's user-space driver on NVMe devices the process owns.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Default`, `Hash`, `Display`, `FromStr`

## Wait

A [`Deferred`](https://www.unum.cloud/docs/ustore/rust/errors.md#Deferred) being awaited: every poll reads its status, and one not yet final asks to be polled again.

```rust
pub struct Wait<Verb: Calling>(_);
```

The C library has no wake-up, so an executor re-polls it while other tasks run, spinning only when nothing else is
ready; [`Deferred::wait`](#wait) blocks without spinning.

Rust-only; every poll calls `ustore_outcome_status`, and the final one `ustore_outcome_wait`, which returns at once.

Implements: `Future`

## gpu_devices

Every GPU this process can drive, NVIDIA devices first, then AMD, each at the ordinal [`Executor::for_vram`](#for_vram) names it by; empty on a machine without GPUs or their runtimes.

```rust
pub fn gpu_devices() -> Result<Vec<GPUDevice>>
```

Calls `ustore_gpu_devices`.

