# Reads and Writes

> UStore for Mojo

### Binary Values

A cursor walks one collection page by page, every pull resuming past the last key the pull before it handed out:

```mojo
var cursor = db.on(executor).cursor(people, Key(0))  # walks on the kind of executor it was opened on
var page = cursor.next(executor, arena, 1000)        # keys and their values, zero once exhausted
```

`db.changes_cursor(collection, since)` opens a feed of the changes committed after a stamp, and `db.ingest(collection)` lands every appended row as one commit of its own.

`from ustore import Values, Measures, Pulled, …`

## LengthsView

A strided run of lengths or positions, `ustore_lengths_view_t`.

```mojo
comptime LengthsView[origin: ImmOrigin = ImmUntrackedOrigin]: AnyStruct[StridedView[UInt64, origin]] = StridedView[UInt64, origin]
```

## Values

What a read wrote into the arena it borrows: an Apache Arrow binary array of one value per task, a missing key reading as an unset presence bit and an empty value.

```mojo
struct Values[origin: MutOrigin]
```

- `origin` (comptime): The arena the values live in, which this result borrows.

- `Written` = `ValuesWritten`
- `arena` `Pointer[Arena, origin]`: The arena holding the values.
- `generation` `Int`: The arena's call the values came from.
- `written` `ValuesWritten`: The views the engine wrote.
- `count` `Int`: Tasks the read carried.

Conforms to: `Answer`, `Deinitable`, `Movable`, `Sized`

## __init__

```mojo
def __init__(out self, arena: Int, generation: Int, written: ValuesWritten, count: Int)
```

## __len__

The tasks the read carried.

```mojo
def __len__(self) -> Int
```

## present

Whether task `index` found its value.

```mojo
def present(self, index: Int) -> Bool
```

## lengths

The length of every value.

```mojo
def lengths(ref self) -> Span[UInt64, origin_of(self)]
```

## values

The values, empty for a missing key or when the read skipped the bytes.

```mojo
def values(self) -> Tape[origin]
```

## Measures

The bounds a measure estimated into the arena it borrows, one per range.

```mojo
struct Measures[origin: MutOrigin]
```

- `origin` (comptime): The arena the bounds live in, which this result borrows.

- `Written` = `MeasuresWritten`
- `arena` `Pointer[Arena, origin]`: The arena holding the bounds.
- `generation` `Int`: The arena's call the bounds came from.
- `written` `MeasuresWritten`: The views the engine wrote.
- `count` `Int`: Ranges measured.

Conforms to: `Answer`, `Deinitable`, `Movable`, `Sized`

## __init__

```mojo
def __init__(out self, arena: Int, generation: Int, written: MeasuresWritten, count: Int)
```

## __len__

The ranges measured.

```mojo
def __len__(self) -> Int
```

## min_cardinalities

The lower bound on the entries in every range.

```mojo
def min_cardinalities(ref self) -> Span[UInt64, origin_of(self)]
```

## max_cardinalities

The upper bound on the entries in every range.

```mojo
def max_cardinalities(ref self) -> Span[UInt64, origin_of(self)]
```

## min_value_bytes

The lower bound on the bytes of values in every range.

```mojo
def min_value_bytes(ref self) -> Span[UInt64, origin_of(self)]
```

## max_value_bytes

The upper bound on the bytes of values in every range.

```mojo
def max_value_bytes(ref self) -> Span[UInt64, origin_of(self)]
```

## min_space_usages

The lower bound on the disk space every range takes.

```mojo
def min_space_usages(ref self) -> Span[UInt64, origin_of(self)]
```

## max_space_usages

The upper bound on the disk space every range takes.

```mojo
def max_space_usages(ref self) -> Span[UInt64, origin_of(self)]
```

## Pulled

One page of a cursor's walk, read in place from the arena the pull borrows.

```mojo
struct Pulled[origin: MutOrigin]
```

- `origin` (comptime): The arena the page lives in, which this result borrows.

- `Written` = `PulledWritten`
- `arena` `Pointer[Arena, origin]`: The arena holding the page.
- `generation` `Int`: The arena's call the page came from.
- `written` `PulledWritten`: The views the engine wrote.

Conforms to: `Answer`, `Deinitable`, `Movable`, `Sized`

## __init__

```mojo
def __init__(out self, arena: Int, generation: Int, written: PulledWritten, count: Int)
```

## __len__

The keys pulled, zero once the walk is exhausted.

```mojo
def __len__(self) -> Int
```

## keys

The keys of the page in their order.

```mojo
def keys(ref self) -> Span[Key, origin_of(self)]
```

## values

Their values, empty when the pull skipped them.

```mojo
def values(self) -> Tape[origin]
```

## BlobsReadConfig

The ranges a read takes of each value, and whether it copies the bytes.

```mojo
struct BlobsReadConfig[offsets_origin: ImmOrigin = ImmUntrackedOrigin, limits_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `offsets_origin` (comptime): The borrowed start offsets.
- `limits_origin` (comptime): The borrowed byte limits.

- `offsets` `StridedView[UInt64, offsets_origin]`: Byte offset into each value the read starts at; zeroed reads whole values.
- `limits` `StridedView[UInt64, limits_origin]`: Bytes to read of each value from its offset; zeroed reads the rest.
- `values` `Bool`: Whether the bytes come too, or only presences and lengths.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    offsets: StridedView[UInt64, offsets_origin] = StridedView(),
    limits: StridedView[UInt64, limits_origin] = StridedView(),
    values: Bool = True
)
```

## BlobsScanConfig

The bounds, order and filters of a scan over keys.

```mojo
struct BlobsScanConfig[end_origin: ImmOrigin = ImmUntrackedOrigin, patterns_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `end_origin` (comptime): The borrowed end keys.
- `patterns_origin` (comptime): The borrowed patterns.

- `end_keys` `StridedView[Key, end_origin]`: Key every scan stops before, exclusive; zeroed bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start keys.
- `mode` `ScanMode`: In what order the keys come.
- `patterns` `Patterns[patterns_origin]`: Patterns the value of every listed key matches; empty lists every key.
- `predicate` `Predicate`: The caller's verdict on the listed keys.
- `progress` `Progress`: Reports the scans finished, and stops the call where it says to.
- `scores` `Bool`: Whether one score per listed key comes too, when the patterns carry weights.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    end_keys: StridedView[Key, end_origin] = StridedView(),
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    patterns: Patterns[patterns_origin] = Patterns(),
    predicate: Predicate = Predicate(),
    progress: Progress = Progress(),
    scores: Bool = False
)
```

## StridedView

A borrowed strided run of fixed-width elements, one per task, where a zero stride repeats the first.

```mojo
struct StridedView[T: Copyable, origin: ImmOrigin = ImmUntrackedOrigin]
```

- `T` (comptime): The element, laid out as the ABI declares it.
- `origin` (comptime): The borrowed elements, which the view keeps alive for as long as it is used.

- `data` `Optional[Pointer[T, origin]]`: The first element; absent for a zeroed view.
- `stride` `Int`: Bytes between consecutive elements; zero repeats the first.
- `count` `Int`: Elements the view holds: one for a repeated element, zero for a zeroed view.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`, `Sized`

## __init__

A zeroed view, which stands for the input's default.

```mojo
def __init__(out self)
```

## __len__

The elements the view holds.

```mojo
def __len__(self) -> Int
```

## tasks

The tasks the view can serve: its elements, minus one for a repeated element, which fits any batch.

```mojo
def tasks(self) -> Int
```

## of

Borrows elements packed one after another.

```mojo
def of[items_origin: ImmOrigin, //](items: Span[T, items_origin]) -> StridedView[T, items_origin]
```

## repeating

Borrows one element, repeated for every task.

```mojo
def repeating[item_origin: ImmOrigin, //](ref[origin] item: T) -> StridedView[T, item_origin]
```

## *

The C layout, erased only inside a verb so the borrow lives through the call.

```mojo
def arguments(self) -> StridedArguments
```

## Durability

How durable the writes a call publishes are once it finishes, `ustore_durability_t`.

```mojo
struct Durability
```

- `BUFFERED` = `Durability(Int32(0))`: Visible, and on disk as the engine's buffers fill.
- `FLUSHED` = `Durability(Int32(1))`: On disk.
- `code` `c_int`: The raw `ustore_durability_t` value the ABI exchanges.

Conforms to: `Copyable`, `Deinitable`, `Equatable`, `ImplicitlyCopyable`, `Movable`, `RegisterPassable`, `TrivialRegisterPassable`

## IngestOrder

In what order an ingest's rows arrive, `ustore_ingest_order_t`.

```mojo
struct IngestOrder
```

- `SORTED` = `IngestOrder(Int32(0))`: Keys strictly ascend across every append.
- `UNSORTED` = `IngestOrder(Int32(1))`: Keys arrive in any order and may repeat, the last row of a key winning.
- `code` `c_int`: The raw `ustore_ingest_order_t` value the ABI exchanges.

Conforms to: `Copyable`, `Deinitable`, `Equatable`, `ImplicitlyCopyable`, `Movable`, `RegisterPassable`, `TrivialRegisterPassable`

## Ingest

An ingest under way into one collection, landing every row appended as one commit of its own, freed when it goes out of scope. Its calls run on the calling thread, one at a time.

```mojo
struct Ingest
```

- `library` `Library`: The loaded engine.
- `address` `Address`: The `ustore_ingest_t`.

Conforms to: `Deinitable`, `Movable`

## __init__

Adopts an ingest the engine just opened.

```mojo
def __init__(out self, *, library: Library, address: Int)
```

## __deinit__

Frees the ingest, dropping every row of an unfinished one. Calls `ustore_ingest_free`.

```mojo
def __deinit__(deinit self)
```

## append

Hands the ingest one batch of rows, copied before the call returns. Calls `ustore_ingest_append`.

```mojo
def append[keys_origin: ImmOrigin, values_origin: ImmOrigin, sources_origin: ImmOrigin, targets_origin: ImmOrigin, edges_origin: ImmOrigin, //](
    self,
    keys: StridedView[Key, keys_origin] = StridedView(),
    values: StringsView[values_origin] = StringsView(),
    sources: StridedView[Key, sources_origin] = StridedView(),
    targets: StridedView[Key, targets_origin] = StridedView(),
    edges: StridedView[Key, edges_origin] = StridedView()
)
```

Blobs, documents and pages take [`keys`](https://www.unum.cloud/docs/ustore/mojo/scans.md#keys) and [`values`](https://www.unum.cloud/docs/ustore/mojo/scans.md#values), strings take their strings as [`values`](https://www.unum.cloud/docs/ustore/mojo/scans.md#values) and
the keys they map onto as [`keys`](https://www.unum.cloud/docs/ustore/mojo/scans.md#keys), and edges take `sources`, `targets` and optionally [`edges`](https://www.unum.cloud/docs/ustore/mojo/graphs.md#edges).

Raises: [`Error`](https://www.unum.cloud/docs/ustore/mojo/errors.md#Error) if a view the modality needs is missing, or a key breaks a sorted order.

## finish

Lands every row appended as one commit, answering its stamp. Calls `ustore_ingest_finish`.

```mojo
def finish(self, durability: Durability = Durability.BUFFERED) -> Stamp
```

Raises: [`Error`](https://www.unum.cloud/docs/ustore/mojo/errors.md#Error) if the collection was dropped meanwhile.

## StringRuns

The strings a scan or a sample listed into the arena it borrows, run after run, one run per task.

```mojo
struct StringRuns[origin: MutOrigin]
```

- `origin` (comptime): The arena the strings live in, which this result borrows.

- `Written` = `StringRunsWritten`
- `arena` `Pointer[Arena, origin]`: The arena holding the strings.
- `generation` `Int`: The arena's call the strings came from.
- `written` `StringRunsWritten`: The views the engine wrote.
- `count` `Int`: Runs, one per task.

Conforms to: `Answer`, `Deinitable`, `Movable`, `Sized`

## __init__

```mojo
def __init__(out self, arena: Int, generation: Int, written: StringRunsWritten, count: Int)
```

## __len__

The runs, one per task.

```mojo
def __len__(self) -> Int
```

## offsets

The runs' boundaries in strings, one more of them than runs.

```mojo
def offsets(ref self) -> Span[UInt64, origin_of(self)]
```

## strings

Every run's strings end to end; run `i` spans entries `offsets()[i]` up to `offsets()[i + 1]`.

```mojo
def strings(self) -> Tape[origin]
```

## scores

One score per listed string, empty unless weighted patterns asked for them.

```mojo
def scores(ref self) -> Span[Float32, origin_of(self)]
```

## StringsPulled

One page of a strings cursor's walk, read in place from the arena the pull borrows.

```mojo
struct StringsPulled[origin: MutOrigin]
```

- `origin` (comptime): The arena the page lives in, which this result borrows.

- `Written` = `StringsPulledWritten`
- `arena` `Pointer[Arena, origin]`: The arena holding the page.
- `generation` `Int`: The arena's call the page came from.
- `written` `StringsPulledWritten`: The views the engine wrote.

Conforms to: `Answer`, `Deinitable`, `Movable`, `Sized`

## __init__

```mojo
def __init__(out self, arena: Int, generation: Int, written: StringsPulledWritten, count: Int)
```

## __len__

The strings pulled, zero once the walk is exhausted.

```mojo
def __len__(self) -> Int
```

## strings

The strings of the page in the order of their text.

```mojo
def strings(self) -> Tape[origin]
```

## keys

The keys of the page's strings, empty when the pull skipped them.

```mojo
def keys(ref self) -> Span[Key, origin_of(self)]
```

## StringsScanConfig

The bounds, order and filters of a prefix scan.

```mojo
struct StringsScanConfig[start_origin: ImmOrigin = ImmUntrackedOrigin, end_origin: ImmOrigin = ImmUntrackedOrigin, patterns_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `start_origin` (comptime): The borrowed start strings.
- `end_origin` (comptime): The borrowed end strings.
- `patterns_origin` (comptime): The borrowed patterns.

- `start_strings` `StringsView[start_origin]`: String every scan starts from, inclusive; zeroed starts at the first string in the direction.
- `end_strings` `StringsView[end_origin]`: String every scan stops before, exclusive; empty or zeroed bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start string.
- `mode` `ScanMode`: In what order the strings come.
- `patterns` `Patterns[patterns_origin]`: Patterns every listed string matches; empty lists every string.
- `predicate` `Predicate`: The caller's verdict on the keys the listed strings map onto.
- `progress` `Progress`: Reports the scans finished, and stops the call where it says to.
- `scores` `Bool`: Whether one score per listed string comes too, when the patterns carry weights.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    start_strings: StringsView[start_origin] = StringsView(),
    end_strings: StringsView[end_origin] = StringsView(),
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    patterns: Patterns[patterns_origin] = Patterns(),
    predicate: Predicate = Predicate(),
    progress: Progress = Progress(),
    scores: Bool = False
)
```

## StringsCursorConfig

The bounds, order and filters of a walk over one prefix, every string copied when the walk opens.

```mojo
struct StringsCursorConfig[start_origin: ImmOrigin = ImmUntrackedOrigin, end_origin: ImmOrigin = ImmUntrackedOrigin, patterns_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `start_origin` (comptime): The borrowed start string.
- `end_origin` (comptime): The borrowed end string.
- `patterns_origin` (comptime): The borrowed patterns.

- `start_string` `BytesView[start_origin]`: String the walk starts from, inclusive; zeroed starts at the first string of the prefix.
- `end_string` `BytesView[end_origin]`: String the walk stops before, exclusive; zeroed bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start string.
- `patterns` `Patterns[patterns_origin]`: Patterns every string the walk hands out matches; empty walks every string.
- `predicate` `Predicate`: The caller's verdict on the keys of the strings of every page.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    start_string: BytesView[start_origin] = BytesView(),
    end_string: BytesView[end_origin] = BytesView(),
    direction: ScanDirection = ScanDirection.ASCENDING,
    patterns: Patterns[patterns_origin] = Patterns(),
    predicate: Predicate = Predicate()
)
```

## StringsCursor

A walk over the strings of one prefix, every pull resuming past the last string the pull before it handed out, freed when it goes out of scope. It holds its database open, and the transaction or snapshot it reads through.

```mojo
struct StringsCursor
```

- `library` `Library`: The loaded engine.
- `database` `Address`: The `ustore_database_t` it walks.
- `address` `Address`: The `ustore_strings_cursor_t`.

Conforms to: `Deinitable`, `Movable`

## __init__

Adopts a cursor the engine just opened.

```mojo
def __init__(out self, *, library: Library, database: Int, address: Int)
```

## __deinit__

Frees the cursor and the holds it kept. Calls `ustore_strings_cursor_free`.

```mojo
def __deinit__(deinit self)
```

## next

Pulls the next page of up to `wanted` strings, with their keys when asked. Calls `ustore_strings_cursor_next`.

```mojo
def next(
    self,
    executor: Executor,
    mut arena: Arena,
    wanted: Int,
    values: Bool = True,
    progress: Progress = Progress()
) -> StringsPulled[origin_of(arena)]
```

Raises: [`Error`](https://www.unum.cloud/docs/ustore/mojo/errors.md#Error) with [`CANCELLED`](https://www.unum.cloud/docs/ustore/mojo/errors.md#CANCELLED) when `progress` stops the pull, which leaves the cursor where it was.

## StringsView

A borrowed ragged batch of byte strings laid out as Apache Arrow lays one out: the bytes end to end, and one more offset than strings around them.

```mojo
struct StringsView[origin: ImmOrigin = ImmUntrackedOrigin]
```

- `origin` (comptime): The borrowed bytes and offsets, which the view keeps alive for as long as it is used.

- `data` `Optional[Pointer[UInt8, origin]]`: The first byte, which every offset counts from; absent for a zeroed view.
- `offsets` `Address`: The strings' boundaries, one more of them than strings, as `layout` sizes them.
- `layout` `c_int`: `0` for 32-bit offsets, `1` for 64-bit offsets.
- `count` `Int`: Strings in the batch, or zero for a zeroed view.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`, `Sized`

## __init__

A zeroed view, which stands for the input's default.

```mojo
def __init__(out self)
```

## __len__

The strings in the batch.

```mojo
def __len__(self) -> Int
```

## tasks

The tasks the batch can serve, one per string.

```mojo
def tasks(self) -> Int
```

## of

Borrows an Apache Arrow `Binary` tape: string `i` spans `offsets[i]` up to `offsets[i + 1]`.

```mojo
def of[bytes_origin: ImmOrigin, offsets_origin: ImmOrigin, //](
    bytes: Span[UInt8, bytes_origin],
    offsets: Span[UInt32, offsets_origin]
) -> StringsView[origin_of(bytes_origin, offsets_origin)]
```

```mojo
def of[bytes_origin: ImmOrigin, offsets_origin: ImmOrigin, //](
    bytes: Span[UInt8, bytes_origin],
    offsets: Span[UInt64, offsets_origin]
) -> StringsView[origin_of(bytes_origin, offsets_origin)]
```

Borrows an Apache Arrow `LargeBinary` tape, the same with 64-bit offsets.

## Tape

A ragged run of byte strings a call wrote into the arena it borrows, read in place.

```mojo
struct Tape[origin: MutOrigin]
```

- `origin` (comptime): The arena the strings live in, which this result borrows.

- `arena` `Pointer[Arena, origin]`: The arena holding the strings.
- `generation` `Int`: The arena's call these strings came from, so a read after a later call is refused.
- `view` `StringsViewArguments`: The bytes and offsets, as the engine wrote them.
- `count` `Int`: Strings in the tape.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`, `Sized`

## __getitem__

One string's bytes, borrowed from the arena.

```mojo
def __getitem__(ref self, index: Int) -> Span[UInt8, origin_of(self)]
```

Raises: [`Error`](https://www.unum.cloud/docs/ustore/mojo/errors.md#Error) with [`INVALID_ARGUMENT`](https://www.unum.cloud/docs/ustore/mojo/errors.md#INVALID_ARGUMENT) once a later call rewound the arena, or [`DEVICE`](https://www.unum.cloud/docs/ustore/mojo/errors.md#DEVICE) over device memory.

## __len__

The strings in the tape.

```mojo
def __len__(self) -> Int
```

