pub type DeferredOn<'view, Parent = Database> = On<'view, Parent, Deferring>; § 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 aDeferred.
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.
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.
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
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, SendnewMakes an arena of host pages for calls on the calling thread.
new_inMakes an arena where executor computes, serving the calls of its residency.
describeWhere the outputs live, as the executor that made the arena decided.
StructBlockingThe completion of an On, whose verbs return once their call is final and answer what it produced.
EnumCPUClassThe CPU generation a database confines its waits, atomics and string kernels to, where None takes what the CPU offers.
pub enum CPUClass Prints and parses its stable name, like "intel-icelake".
Values
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, FromStrStructDeferredA 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
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, IntoFuturestatusErr(Status::Deferred) until the call is final, then its final status, read without blocking.
waitBlocks until the call is final, then hands back what it produced.
StructDeferringThe completion of a DeferredOn, whose verbs return once their call is submitted and answer a Deferred.
StructExecutorThe threads that run calls, shared by any number of databases and views.5
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, Dropfor_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.
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.
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.
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.
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.
pub fn drain(&self, mood: Mood) -> Result<()> EnumGPUClassThe generation of a GPU, as ustore_gpu_class_t spells it, like "nvidia-hopper".
pub enum GPUClass Values
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, FromStrStructGPUDeviceOne GPU this process can drive, as gpu_devices lists it.
pub struct GPUDevice Fields
ordinal | usize | The ordinal Executor::for_vram names the device by, its position in 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, HashEnumGPUVendorThe vendor whose runtime drives a GPU, as ustore_gpu_vendor_t spells it, like "amd".
pub enum GPUVendor Values
Nvidia | 1 | NVIDIA, through the CUDA driver. |
|---|---|---|
Amd | 2 | AMD, through the HIP runtime. |
Implements
Clone, Copy, StructuralPartialEq, PartialEq, Eq, Debug, Hash, Display, FromStrEnumGdsHow an executor of Executor::for_vram moves bytes between the drives and its device through GPUDirect Storage, as ustore_gds_t spells it.
pub enum Gds Values
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 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, FromStrStructIOOptionsHow 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.
pub struct IOOptions Fields
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, HashEnumMoodWhat the threads of an Executor do once it goes idle, as ustore_mood_t spells it.
pub enum Mood Values
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, FromStrStructOnThe 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
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, CopywriteUpserts a batch of values, where an empty value is still a value and On::remove removes keys.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
pub fn stage(&self) -> Completion::Answer<Stage> commitCommits the writes of this view's transaction, reporting the commit's position in commit order.
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.
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.
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.
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.
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
DocumentEntryvalues of one format, which isJsonfor the text the engine parses and aWritableScalarorTextfor a document that is one scalar; KeyedBydocuments, carrying their keys under a field of their own;- borrowed
FieldEntryvalues of one format, writing into fields of existing documents; - the owned forms a deferred write needs: keys beside a
stringtape::CharsTapeof 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
pub enum Residency Values
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, HashEnumTransportHow the NVMe engine moves bytes between its files and memory.
pub enum Transport Values
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, FromStrStructWaitA Deferred being awaited: every poll reads its status, and one not yet final asks to be polled again.
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