A Key is a UUID, sixteen bytes ordered as their bytes, and converts from [u8; 16], from a UUID, or from a u64 or u128 spelled big-endian, so keys made from integers order as the integers. Key::next is the key right after one in their order, where a scan resumes past it, and key_unknown is the key that stands for no key, every bit of it set.
A CollectionID is a UUIDv7 minted when a collection is created, and the nil one names none, as a database holds no collection until one is created.
A batch of keys is anything that reads as &[Key]: an array, a Vec, or a borrow of either.
Collections are created under a name and the modality they hold, resolved by name once and addressed by identifier from then on, and dropping one forgets its name.
Each engine keeps the names in the system collection _names and every collection’s modality and name in _collections, which no identifier reaches, so a name starting with _ is refused with Status::InvalidArgument.
A name is read through a view as a value is, so a watching transaction conflicts with a concurrent create or drop of a name it resolved, while a listing describes the database and reads the view’s snapshot or the head.
use ustore::DropMode;let people = database.collection_create("people", Modality::Blobs)?;let (same, modality) = database.head().collection_find("people", &mut arena)?;let every = database.head().collection_list(&mut arena)?;for name in database.head().collection_names("pe", None, 100, &mut arena)?.iter() { println!("{name}");}database.collection_drop(people, DropMode::Collection)?;
A database holds no collection until one is created, and Database::collection_drop empties a collection of its pairs or values with DropMode::Pairs or DropMode::Values, or drops it whole with DropMode::Collection.
Walks paginate rather than hold an iterator over concurrent state: a cursor resumes past the last key it handed out, a scan from Key::next of the last key it found, and a name walk from a name.
The ABI carries a collection per task, so a batch spans as many collections as it has entries.
Every batch verb takes a Collections, and a bare CollectionID converts into Collections::Every, which is the common case written the short way.
use ustore::Collections;let spanned = [people, places];let entries = [Entry::new(ada, b"Ada"), Entry::new(ada, b"Kent")];database.head().write(spanned.as_slice(), &entries, Durability::Buffered)?;let values = database.head().read(Collections::Each(&spanned), &[ada, ada], &mut arena)?;database.head().write(people, &entries, Durability::Buffered)?; // one for all of them
A Collections::Each whose length is not the length of the batch is refused with Status::InvalidArgument before the call crosses the boundary.
API
StructCollectionA collection addressed by its name, which reads and writes through one view of its Parent, the head of a Database or a Transaction.7
export_arrowThe whole collection as one Arrow stream through the view, whose batches outlive the stream; a head view reads a snapshot the stream holds until dropped.
Every pull runs the cursor of the collection's modality into an arena of its own, which the exporters of
c/ustore/arrow.h hand out as the batch's columns, and which the batch frees once released.
import_arrowWrites every batch of stream through the writes of the collection's modality, answering the rows written.
The converters of c/ustore/arrow.h read every batch's columns in place, and the last write pays
durability. The call takes the stream over and releases it, even on failure.
ingest_arrowLands every batch of stream as one commit of its own at the head, answering the rows landed.
Appends every batch to one ingest of ustore_ingest_init, which ustore_ingest_finish lands. The call takes
the stream over and releases it, even on failure.
StructArenaDescriptionWhere an Arena's outputs live, as Arena::describe reports it.
StructCollectionIDThe identifier of a collection: a UUIDv7 its create mints once and never reuses, so it stays the same across restarts and never names two collections.
The ABI carries a collection per task, so a batch may span as many collections as it has entries;
Collections::Every is the common case, and every verb takes a bare CollectionID as one.
Values
Every
(<a data-ref="CollectionID">CollectionID</a>)
Every task of the batch addresses the same collection.
StructDescriptionWhat an open database reports about itself, as ustore_database_describe answers it, where every size is the engine's estimate, and zero where the engine keeps none.1