Rust · Batches and Arenas

Batches and Arenas

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::*; 1.0.0-rc.1 · d6d40961

§ 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.

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.

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:

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.

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.

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.

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.

API

Types

DeferredOnA view whose verbs defer their calls on an executor, each answering a Deferred once submitted.
db.rs:2892 ↗
pub type DeferredOn<'view, Parent = Database> = On<'view, Parent, Deferring>;
ProgressCallbackA 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 and publishes nothing.
db.rs:3523 ↗
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.

StructArenaMemory the library writes every output whose length scales with a call into, reused across calls.3
db.rs:1531 ↗
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
newMakes an arena of host pages for calls on the calling thread.
db.rs:1539 ↗
pub fn new() -> Result<Self>

Calls ustore_arena_init.

new_inMakes an arena where executor computes, serving the calls of its residency.
db.rs:1546 ↗
pub fn new_in(executor: &Executor) -> Result<Self>

Calls ustore_arena_init.

describeWhere the outputs live, as the executor that made the arena decided.
db.rs:1569 ↗
pub fn describe(&self) -> Result<ArenaDescription>

Calls ustore_arena_describe.

StructBlockingThe completion of an On, whose verbs return once their call is final and answer what it produced.
db.rs:3660 ↗
pub struct Blocking;

Implements

Clone, Copy, Debug
EnumCPUClassThe CPU generation a database confines its waits, atomics and string kernels to, where None takes what the CPU offers.
db.rs:2161 ↗
pub enum CPUClass

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

Values

Serial1Portable kernels that run on any CPU.
IntelHaswell2x86 cores from Intel Haswell on.
IntelSierra3x86 efficiency cores from Intel Sierra Forest on.
IntelSkylake4x86 server cores from Intel Skylake on.
IntelIcelake5x86 server cores from Intel Ice Lake on.
AWSG26Arm cores from AWS Graviton 2 on.
AppleM27Arm cores from Apple M2 on.
AWSG58Arm server cores from AWS Graviton 5 on.
AlibabaC9309RISC-V cores with RVV, Zawrs and Zacas, from Alibaba's C930 on.
Monoversioned10The one class of a monoversioned build.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Hash, Display, FromStr
StructDeferredA 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.2
db.rs:3762 ↗
pub struct Deferred<Verb: Calling>

Deferred::status polls without blocking, and Deferred::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, .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
statusErr(Status::Deferred) until the call is final, then its final status, read without blocking.
db.rs:3770 ↗
pub fn status(&self) -> Result<(), Status>

Calls ustore_outcome_status.

waitBlocks until the call is final, then hands back what it produced.
db.rs:3778 ↗
pub fn wait(self) -> Result<Verb::Output>

Calls ustore_outcome_wait.

StructDeferringThe completion of a DeferredOn, whose verbs return once their call is submitted and answer a Deferred.
db.rs:3665 ↗
pub struct Deferring;

Implements

Clone, Copy, Debug
StructExecutorThe threads that run calls, shared by any number of databases and views.5
db.rs:3871 ↗
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. Dropping the executor drains it.

Implements

Debug, Send, Sync, Drop
for_ramSpawns 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.
db.rs:3890 ↗
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. 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_poolCreates 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.
db.rs:3916 ↗
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_nvmeSpawns 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 opens on it to move bytes as io says.
db.rs:3937 ↗
pub fn for_nvme(threads: usize, io: &IOOptions, deferred_limit: usize) -> Result<Self>

Calls ustore_executor_for_nvme.

for_vramOpens one submission stream on device, a GPUDevice::ordinal 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.
db.rs:3963 ↗
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 for an ordinal no device carries. NVMEOptions::compactions 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.

drainWaits for every call submitted before the drain began, then leaves the threads in mood whenever they next go idle.
db.rs:3998 ↗
pub fn drain(&self, mood: Mood) -> Result<()>
EnumGPUClassThe generation of a GPU, as ustore_gpu_class_t spells it, like "nvidia-hopper".
db.rs:2034 ↗
pub enum GPUClass

Values

NvidiaAmpere1Ampere-class NVIDIA and every NVIDIA GPU without a class of its own - A100, A10 & RTX 30.
NvidiaAda2Ada-class NVIDIA - L4, L40S & RTX 40.
NvidiaHopper3Hopper-class NVIDIA - H100 & H200.
NvidiaBlackwell4Blackwell-class NVIDIA - B200, B300 & GB300.
NvidiaBlackwellRTX5Consumer Blackwell NVIDIA - RTX 50, RTX PRO 6000 & DGX Spark.
AmdCDNA36CDNA3 AMD - MI300X & MI325X.
AmdCDNA47CDNA4 AMD - MI350X & MI355X.
AmdCDNA58CDNA5 AMD - MI400.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Hash, Display, FromStr
StructGPUDeviceOne GPU this process can drive, as gpu_devices lists it.
db.rs:2092 ↗
pub struct GPUDevice

Fields

ordinalusizeThe ordinal Executor::for_vram names the device by, its position in gpu_devices.
vendorGPUVendorThe vendor whose runtime drives the device.
vendor_ordinalu32The device's ordinal in its vendor's runtime, as nvidia-smi or rocm-smi list it.
gpu_classGPUClassThe class of the device.
compute_unitsu32Streaming multiprocessors or compute units.
memory_bytesu64Device memory in bytes.
nameStringThe vendor's own name for the device.

Implements

Clone, StructuralPartialEq, PartialEq, Eq, Debug, Hash
EnumGPUVendorThe vendor whose runtime drives a GPU, as ustore_gpu_vendor_t spells it, like "amd".
db.rs:1994 ↗
pub enum GPUVendor

Values

Nvidia1NVIDIA, through the CUDA driver.
Amd2AMD, through the HIP runtime.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Hash, Display, FromStr
EnumGdsHow an executor of Executor::for_vram moves bytes between the drives and its device through GPUDirect Storage, as ustore_gds_t spells it.
db.rs:1955 ↗
pub enum Gds

Values

Automatic0Direct transfers where the nvidia_fs driver is loaded, and cuFile's compatibility mode elsewhere.
Direct1Direct transfers, refused with Status::Device where the driver is absent.
Compatibility2cuFile's compatibility mode, which bounces through host pages it manages.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Default, Hash, Display, FromStr
StructIOOptionsHow the threads of an executor of Executor::for_nvme move bytes between the drives and memory, where every zero size or count keeps the engine's default.
db.rs:2465 ↗
pub struct IOOptions

Fields

transportTransportHow bytes move between the files and memory.
shared_io_channelsusizeI/O channels the threads outside the executor share.
queue_depthusizeSubmissions a channel holds at once.
request_buffer_bytesu64Bytes of each request buffer of a channel.
request_buffers_countusizeRequest buffers of each channel.
stream_buffer_bytesu64Bytes of each streaming buffer of a channel.
stream_buffers_countusizeStreaming buffers of each channel.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Default, Hash
EnumMoodWhat the threads of an Executor do once it goes idle, as ustore_mood_t spells it.
db.rs:1485 ↗
pub enum Mood

Values

Parked0Parked, so the next call pays a wake-up.
Spinning1Spinning, trading power for the next call's latency.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Hash, Display, FromStr
StructOnThe one view a call addresses: the head of a Database, a Transaction, or a Snapshot, which is its Parent, with the executor its calls run on and how they complete.63
db.rs:2873 ↗
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, on that executor. The same verb of a DeferredOn, which On::deferred makes, returns once its call is submitted and answers a Deferred.

Implements

Debug, Clone, Copy
writeUpserts a batch of values, where an empty value is still a value and On::remove removes keys.
db.rs:468 ↗
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 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 gives every entry the same one. A transaction flushes at its commit, so Durability::Flushed is refused inside one.

Calls ustore_blobs_write.

removeRemoves a batch of keys with their values, whether or not the database holds them, and hands the keys back.
db.rs:488 ↗
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_rangeRemoves every key of one collection from range.start, inclusive, to range.end, exclusive, with its value, in one atomic call.
db.rs:507 ↗
pub fn remove_range(
    &self,
    collection: CollectionID,
    range: Range<Key>,
    durability: Durability,
) -> Completion::Answer<RemoveRange>
readReads a batch of keys into the arena, one collection per key or one for all of them, and hands back the Values.
db.rs:527 ↗
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_slicesReads the same byte range of every value of a batch into the arena, as On::read reads whole values, where a range past the end of a value reads empty and one running past it stops there.
db.rs:551 ↗
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>,
scanLists up to wanted keys of one collection's range into the arena, keeping those its matching admits, while a Cursor walks one with its values.
db.rs:588 ↗
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.

sampleDraws up to wanted keys uniformly at random from one collection into the arena.
db.rs:623 ↗
pub fn sample<'arena>(
    &self,
    collection: CollectionID,
    config: impl Into<BlobsSampleConfig>,
    arena: &'arena mut Arena,
) -> Completion::Answer<Sample<'arena>>

Calls ustore_blobs_sample.

measureEstimates the keys and the space a range of keys takes in one collection, through the arena its bounds land in.
db.rs:641 ↗
pub fn measure<'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    arena: &'arena mut Arena,
) -> Completion::Answer<Measure<'arena>>

Calls ustore_blobs_measure.

cursorOpens 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.
db.rs:670 ↗
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.

containsWhich of keys one collection holds, exporting no value.
db.rs:704 ↗
pub fn contains<'arena>(
    &self,
    collection: CollectionID,
    keys: &[Key],
    arena: &'arena mut Arena,
) -> Result<Bitmap<'arena>>
onThis view with every call through it running on executor, after the calls submitted there before it.
db.rs:2896 ↗
pub fn on<'with>(self, executor: &'with Executor) -> On<'with, Parent, Completion>
where
    'view: 'with,
deferredThis view with every verb through it deferred on executor, answering a Deferred once submitted.
db.rs:2907 ↗
pub fn deferred<'with>(self, executor: &'with Executor) -> DeferredOn<'with, Parent>
where
    'view: 'with,
collection_listEvery collection the database holds at this view's snapshot or at the head, exported into the arena.
db.rs:2958 ↗
pub fn collection_list<'arena>(
    &self,
    arena: &'arena mut Arena,
) -> Completion::Answer<CollectionList<'arena>>

Calls ustore_collection_list.

collection_dropRemoves 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.
db.rs:2973 ↗
pub fn collection_drop(
    &self,
    collection: CollectionID,
    mode: DropMode,
) -> Completion::Answer<CollectionDrop>

Calls ustore_collection_drop.

clearEmpties every collection at once, as On::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.
db.rs:2985 ↗
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, since the snapshot belongs to its holder.

Calls ustore_database_clear.

compactReclaims 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.
db.rs:2997 ↗
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.

flushMakes every commit that returned before this call durable, as if each had asked for Durability::Flushed.
db.rs:3012 ↗
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.

stageStages the writes of this view's transaction as the first phase of a two-phase commit, reporting the stamp the transaction reads at.
db.rs:4097 ↗
pub fn stage(&self) -> Completion::Answer<Stage>
commitCommits the writes of this view's transaction, reporting the commit's position in commit order.
db.rs:4105 ↗
pub fn commit(&self, durability: Durability) -> Completion::Answer<Commit>
rollbackWithdraws a stage of this view's transaction, releasing whatever it claimed, while keeping the reads and writes to stage again.
db.rs:4115 ↗
pub fn rollback(&self) -> Completion::Answer<Rollback>
resetDiscards the reads and writes of this view's transaction and reopens it on the newest state, keeping its handle.
db.rs:4121 ↗
pub fn reset(&self) -> Completion::Answer<Reset>
saveWrites 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.
db.rs:4342 ↗
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_writeWrites whole documents or values into fields inside them, where On::docs_remove removes documents and a merge with a JSON null removes a field, and hands what it wrote back.
db.rs:1374 ↗
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 values of one format, which is Json for the text the engine parses and a WritableScalar or Text for a document that is one scalar;
  • KeyedBy documents, carrying their keys under a field of their own;
  • borrowed 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 is refused inside one.

Calls ustore_docs_write.

docs_removeRemoves a batch of whole documents, whether or not the collections hold them, and hands the keys back.
db.rs:1396 ↗
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_rangeRemoves every document of one collection from range.start, inclusive, to range.end, exclusive, in one atomic call.
db.rs:1415 ↗
pub fn docs_remove_range(
    &self,
    collection: CollectionID,
    range: Range<Key>,
    durability: Durability,
) -> Completion::Answer<DocsRemoveRange>
docs_scanLists 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.
db.rs:1435 ↗
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_sampleDraws up to wanted document keys uniformly at random from one collection into the arena.
db.rs:1467 ↗
pub fn docs_sample<'arena>(
    &self,
    collection: CollectionID,
    config: impl Into<DocsSampleConfig>,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsSample<'arena>>
docs_measureEstimates the documents and the space a range of keys takes in one collection, through the arena its bounds land in.
db.rs:1484 ↗
pub fn docs_measure<'arena>(
    &self,
    collection: CollectionID,
    range: impl Into<KeyRange>,
    arena: &'arena mut Arena,
) -> Completion::Answer<DocsMeasure<'arena>>
docs_readReads whole documents or fields inside them into the arena in format, Json or Text, reporting a missing document or field as absent.
db.rs:1508 ↗
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 values, or owned keys beside a stringtape::CharsTape of paths, a path per key, which a deferred read needs.

Calls ustore_docs_read.

docs_gistLists the unique paths to the leaves of the documents under keys into the arena.
db.rs:1534 ↗
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_gatherReads columns of the documents under keys into typed columns in the arena, a row per key.
db.rs:1559 ↗
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 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_cursorOpens a walk over the keys of one documents collection's range, compiling what matching names once, whose predicate lives as long as the cursor.
db.rs:2915 ↗
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_edgesInserts edges between existing or new vertices, keeping an edge the graph already holds, and hands the edges back.
db.rs:553 ↗
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 is refused inside one.

Calls ustore_graph_write_edges.

graph_remove_edgesRemoves edges by source, target and identifier, whether or not the graph holds them, and hands the edges back.
db.rs:573 ↗
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_verticesInserts vertices without edges, keeping every vertex the graph already holds as it is, and hands the vertices back.
db.rs:594 ↗
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_verticesRemoves vertices together with every edge they play roles in, which only a joining graph needs, and hands the vertices back.
db.rs:615 ↗
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_rangeRemoves 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.
db.rs:636 ↗
pub fn graph_remove_vertices_range(
    &self,
    collection: CollectionID,
    range: Range<Key>,
    role: Role,
    durability: Durability,
) -> Completion::Answer<GraphRemoveVerticesRange>
graph_degreesThe degree of every vertex in roles, exported into the arena without a single edge.
db.rs:657 ↗
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_edgesThe degree and the edges of every vertex in roles, exported into the arena as Neighborhoods.
db.rs:680 ↗
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_verticesLists 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 reads their edges.
db.rs:707 ↗
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_verticesDraws up to wanted vertices uniformly at random from one graph collection into the arena.
db.rs:741 ↗
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_verticesEstimates the vertices and the space a range of them takes in one graph collection, through the arena its bounds land in.
db.rs:760 ↗
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_cursorOpens a walk over the vertices of one graph collection's range, whose predicate lives as long as the cursor.
db.rs:1770 ↗
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_importReplaces whole pages with parsed markup, one per key, minting a key for every element.
db.rs:506 ↗
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_insertParses one fragment per task into elements under a parent after an anchor of the page keys names, and hands back the key every first element ended up with, given or minted, from the arena.
db.rs:535 ↗
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_removeRemoves one element per task with its subtree, where the Nil element Key::default removes the whole page.
db.rs:566 ↗
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_moveMoves 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.
db.rs:589 ↗
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_spliceReplaces 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.
db.rs:624 ↗
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_attributesSets one attribute of one element per task, adding the ones it lacks.
db.rs:662 ↗
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_attributesRemoves one attribute of one element per task.
db.rs:693 ↗
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_readReads whole pages, or chosen elements of them, as markup into the arena.
db.rs:722 ↗
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_scanLists up to wanted page keys of one collection's range into the arena, keeping those its matching admits, while On::pages_read renders them.
db.rs:747 ↗
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_sampleDraws up to wanted page keys uniformly at random from one pages collection into the arena.
db.rs:781 ↗
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_measureEstimates the pages and the space a range of page keys takes in one collection, through the arena its bounds land in.
db.rs:800 ↗
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_cursorOpens a walk over the keys of one pages collection's range, compiling its filter once, whose predicate lives as long as the cursor.
db.rs:1451 ↗
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_writeUpserts a batch of strings and the keys they map onto, one key per string.
db.rs:468 ↗
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 gives every string the same collection.

Calls ustore_strings_write.

strings_removeRemoves a batch of strings with their keys, whether or not the database holds them, and hands the strings back.
db.rs:491 ↗
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_readReads the keys a batch of strings map onto into the arena, one collection per string or one for all of them.
db.rs:514 ↗
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_scanLists up to wanted strings of one collection's range into the arena, keeping those its matching admits.
db.rs:538 ↗
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_sampleDraws up to wanted strings uniformly at random from one collection into the arena.
db.rs:572 ↗
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_measureEstimates the strings and the space between two strings of one collection, through the arena its bounds land in.
db.rs:592 ↗
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_findThe collection name addresses and the modality it holds, which crate::Database::collection_create bound, resolved through the arena.
db.rs:976 ↗
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_namesLists up to wanted collection names under prefix into the arena, in the order of their text, from start on where one is given.
db.rs:1002 ↗
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.

EnumResidencyWhere an Arena's outputs live.
db.rs:1609 ↗
pub enum Residency

Values

Ram1Host pages, which the calling thread reads in place.
Vram2One device's memory, which only that device's code reads.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Hash
EnumTransportHow the NVMe engine moves bytes between its files and memory.
db.rs:2230 ↗
pub enum Transport

Values

Automatic0io_uring where the kernel offers it, Linux AIO where it offers only that, and blocking calls elsewhere.
Blocking1Positioned reads and writes that block the polling thread, which every platform has.
LinuxUring2io_uring on unbuffered files, refused where the kernel creates no ring.
LinuxAio3Linux AIO on unbuffered files.
LinuxSpdk4SPDK's user-space driver on NVMe devices the process owns.

Implements

Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Default, Hash, Display, FromStr
StructWaitA Deferred being awaited: every poll reads its status, and one not yet final asks to be polled again.
db.rs:3831 ↗
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 blocks without spinning.

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

Implements

Future

Functions

gpu_devicesEvery GPU this process can drive, NVIDIA devices first, then AMD, each at the ordinal Executor::for_vram names it by; empty on a machine without GPUs or their runtimes.
db.rs:2113 ↗
pub fn gpu_devices() -> Result<Vec<GPUDevice>>

Calls ustore_gpu_devices.