# Collections

> UStore for Rust

### Keys

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.

```rust
let [ada, grace, kent] = [1u64, 2, 3].map(Key::from);
assert!(ada < grace && grace.next() == kent);
println!("{kent}"); // 00000000-0000-0000-0000-000000000003
```

### Collections & Names

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.

```rust
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.

```rust
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.

`use ustore::Collection;`

`use ustore::ArenaDescription;`

`use ustore::CollectionID;`

`use ustore::Collections;`

`use ustore::CompactConfig;`

`use ustore::Description;`

`use ustore::DropMode;`

`use ustore::Key;`

`use ustore::Modality;`

`use ustore::UUID;`

`use ustore::Names;`

`use ustore::db::CollectionList;`

`use ustore::db::CollectionDrop;`

`use ustore::db::Clear;`

`use ustore::db::Compact;`

`use ustore::db::Flush;`

`use ustore::strings::CollectionFind;`

`use ustore::strings::CollectionNames;`

`use ustore::*;`

## Collection

A collection addressed by its name, which reads and writes through one view of its `Parent`, the head of a [`Database`](https://www.unum.cloud/docs/ustore/rust/quickstart.md#Database) or a [`Transaction`](https://www.unum.cloud/docs/ustore/rust/transactions.md#Transaction).

```rust
pub struct Collection<'view, Parent = Database>
```

Every verb goes through a view of one modality: [`Collection::blobs`](#blobs), [`Collection::docs`](#docs) or
[`Collection::graph`](#graph). A call with no arena to pass reads through a one-off arena and hands back what it read
copied out of it, while a batch read borrows the [`Arena`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#Arena) it is given. Writes land [`Durability::Buffered`](https://www.unum.cloud/docs/ustore/rust/reads-and-writes.md#Buffered).

Implements: `Debug`

## blobs

The binary values of the collection, as `db['posters'].blobs` addresses them.

```rust
pub fn blobs(&mut self) -> Blobs<'_, 'view, Parent>
```

## docs

The JSON documents of the collection, as `db['movies'].docs` addresses them.

```rust
pub fn docs(&mut self) -> Docs<'_, 'view, Parent>
```

## graph

The edges of the collection, as `db['similar'].graph` addresses them.

```rust
pub fn graph(&mut self) -> Graph<'_, 'view, Parent>
```

## sample

Draws up to `wanted` keys of a blobs collection uniformly at random into `arena`, each with its value read through the same view.

```rust
pub fn sample<'arena>(&mut self, wanted: usize, arena: &'arena mut Arena) -> Result<Sample<'arena>>
```

## export_arrow

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

```rust
pub fn export_arrow(&mut self) -> Result<ArrowArrayStream>
```

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_arrow

Writes every batch of `stream` through the writes of the collection's modality, answering the rows written.

```rust
pub fn import_arrow(&mut self, stream: ArrowArrayStream, durability: Durability) -> Result<usize>
```

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_arrow

Lands every batch of `stream` as one commit of its own at the head, answering the rows landed.

```rust
pub fn ingest_arrow(
    &mut self,
    stream: ArrowArrayStream,
    order: IngestOrder,
    durability: Durability,
) -> Result<usize>
```

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.

## ArenaDescription

Where an [`Arena`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#Arena)'s outputs live, as [`Arena::describe`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#describe) reports it.

```rust
pub struct ArenaDescription
```

- `residency` `Residency`: [`Residency::Ram`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#Ram) for host pages, [`Residency::Vram`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#Vram) for one device's memory.
- `device` `Option<u32>`: The device's ordinal, as [`gpu_devices`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#gpu_devices) lists it; [`None`](https://www.unum.cloud/docs/ustore/rust/transactions.md#None) for host pages.

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

## CollectionID

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

```rust
pub struct CollectionID(pub UUID);
```

The nil UUID names none.

- `0` `UUID`

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `Hash`, `Default`, `From<[UUID](https://www.unum.cloud/docs/ustore/rust/documents.md#UUID)>`, `From<[u8; 16]>`, `From<u128>`, `From<u64>`, `Display`, `Debug`, `From<[CollectionID](#CollectionID)>`

## Collections

The collections a batch addresses: one for every task, or one per task.

```rust
pub enum Collections<'collections>
```

The ABI carries a collection per task, so a batch may span as many collections as it has entries;
[`Collections::Every`](https://www.unum.cloud/docs/ustore/rust/graphs.md#Every) is the common case, and every verb takes a bare [`CollectionID`](#CollectionID) as one.

- `Every` = `(<a data-ref="CollectionID">CollectionID</a>)`: Every task of the batch addresses the same collection.
- `Each` = `(&amp;'collections [<a data-ref="CollectionID">CollectionID</a>])`: The task at each position addresses the collection at the same position.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`, `From<[CollectionID](#CollectionID)>`, `From<&'collections [[CollectionID](#CollectionID)]>`

## CompactConfig

How a compaction reports; see [`On::compact`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#compact).

```rust
pub struct CompactConfig<'config>
```

- `progress` `Option<&'config mut ProgressCallback<'config>>`: Reports the work done and stops between collections wherever it says to.

Implements: `From<Option<&'config mut dyn FnMut(usize, usize) -> ControlFlow<()> + Send>>`

## Description

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

```rust
pub struct Description
```

- `engine` `Engine`: The engine serving the database.
- `isolation` `Isolation`: How transactions see each other: what the RAM engine was started with, and [`Isolation::Snapshot`](https://www.unum.cloud/docs/ustore/rust/snapshots.md#Snapshot) elsewhere.
- `keys` `usize`: Keys across every collection.
- `memory_bytes` `u64`: Bytes of memory the engine holds for the data.
- `disk_bytes` `u64`: Bytes the files of the database take on disk.

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

## supports_*

Whether the engine supports transactions.

```rust
pub fn supports_transactions(self) -> bool
```

- `supports_transactions`
- `supports_snapshots`

## DropMode

What dropping a collection or clearing a database removes, as `ustore_drop_mode_t` spells it.

```rust
pub enum DropMode
```

- `Collection` = `0`: The collection together with its name and every pair it holds.
- `Pairs` = `1`: Every key and value, keeping the collection.
- `Values` = `2`: Every value, keeping the keys.

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

## Key

The identifier of a value within one collection.

```rust
pub struct Key(pub UUID);
```

- `0` `UUID`

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `Hash`, `Default`, `From<[UUID](https://www.unum.cloud/docs/ustore/rust/documents.md#UUID)>`, `From<[u8; 16]>`, `From<u128>`, `From<u64>`, `Display`, `Debug`, `From<[Key](#Key)>`

## next

The key right after this one in their order, where a scan resuming past it starts; the last key wraps to the first.

```rust
pub fn next(self) -> Key
```

## Modality

What a collection holds, which an engine records beside its name and refuses the verbs of another modality by.

```rust
pub enum Modality
```

- `Blobs` = `1`: Binary values.
- `Docs` = `2`: JSON documents.
- `Graph` = `3`: Vertices and their edges, which only the graph verbs reach.
- `Strings` = `4`: Values keyed by strings.
- `Pages` = `5`: Ordered documents.

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

## UUID

Sixteen bytes naming one thing everywhere, ordered and hashed as their bytes, and printed in the canonical thirty-six character form.

```rust
pub struct UUID(pub [u8; 16]);
```

An integer spells as its 128-bit big-endian bytes, as Python's `uuid.UUID(int=...)` does, so identifiers made from
integers order as the integers.

- `0` `[u8; 16]`

Implements: `[ColumnFormat](https://www.unum.cloud/docs/ustore/rust/documents.md#ColumnFormat)`, `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `Hash`, `Default`, `From<[u8; 16]>`, `From<u128>`, `From<u64>`, `Display`, `Debug`, `From<[UUID](https://www.unum.cloud/docs/ustore/rust/documents.md#UUID)>`, `[Scalar](https://www.unum.cloud/docs/ustore/rust/documents.md#Scalar)`

## Names

The names of collections one listing found, in the order of their text.

```rust
pub struct Names<'arena>
```

The run borrows the arena it was exported into, and every name in it was checked for UTF-8 once,
when the listing returned.

Implements: `Clone`, `Debug`, `Default`, `IntoIterator`

## len

How many names the listing kept, never above the count it wanted.

```rust
pub fn len(&self) -> usize
```

## is_empty

Whether the listing kept nothing.

```rust
pub fn is_empty(&self) -> bool
```

## get

The name at `index`, or [`None`](https://www.unum.cloud/docs/ustore/rust/transactions.md#None) past the end of the listing.

```rust
pub fn get(&self, index: usize) -> Option<&'arena str>
```

## iter

Every name the listing kept, in the order of its text.

```rust
pub fn iter(&self) -> Copied<Iter<'_, &'arena str>>
```

## CollectionList

A listing of the collections a view sees; see [`On::collection_list`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#collection_list).

```rust
pub struct CollectionList<'arena>
```

Implements: `Debug`

## CollectionDrop

A removal of the contents of a collection, or of the collection with its name; see [`On::collection_drop`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#collection_drop).

```rust
pub struct CollectionDrop
```

Implements: `Debug`

## Clear

An emptying of every collection at once; see [`On::clear`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#clear).

```rust
pub struct Clear
```

Implements: `Debug`

## Compact

A compaction of every collection; see [`On::compact`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#compact).

```rust
pub struct Compact<'progress>
```

Implements: `Debug`

## Flush

A flush of every commit that returned; see [`On::flush`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#flush).

```rust
pub struct Flush;
```

Implements: `Debug`

## CollectionFind

A lookup of a collection by its name; see [`On::collection_find`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#collection_find).

```rust
pub struct CollectionFind<'arena, Name>
```

Implements: `Debug`

## CollectionNames

A listing of collection names; see [`On::collection_names`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#collection_names).

```rust
pub struct CollectionNames<'arena, Name>
```

Implements: `Debug`

## key_unknown

The key that stands for no key, every bit of it set.

```rust
pub const fn key_unknown() -> Key
```

