# Scans

> UStore for Mojo

`from ustore import BlobsCursorConfig, BlobsCursor, ScanMode, …`

## KeysView

A strided run of keys, `ustore_keys_view_t`.

```mojo
comptime KeysView[origin: ImmOrigin = ImmUntrackedOrigin]: AnyStruct[StridedView[Key, origin]] = StridedView[Key, origin]
```

## BlobsCursorConfig

The bound, order and filters of a walk over one collection.

```mojo
struct BlobsCursorConfig[patterns_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `patterns_origin` (comptime): The borrowed patterns, compiled once when the walk opens.

- `end_key` `Optional[Key]`: Key the walk stops before, exclusive; absent bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start key.
- `patterns` `Patterns[patterns_origin]`: Patterns every value the walk hands out matches; empty walks every key.
- `predicate` `Predicate`: The caller's verdict on the keys of every page.

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

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    end_key: Optional[Key] = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    patterns: Patterns[patterns_origin] = Patterns(),
    predicate: Predicate = Predicate()
)
```

## BlobsCursor

A walk over the keys of one collection, every pull resuming past the last key 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 BlobsCursor
```

- `library` `Library`: The loaded engine.
- `database` `Address`: The `ustore_database_t` it walks.
- `address` `Address`: The `ustore_blobs_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_blobs_cursor_free`.

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

## next

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

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

- `executor`: The executor the pull runs on, of the kind the walk was opened for.
- `arena` (mut): The arena to rewind and refill, which the result borrows.
- `wanted`: Most keys the page holds; a page of fewer exhausts the walk.
- `values`: Whether the values of the page's keys come too.
- `progress`: Reports the pull, and may cancel it before the cursor advances.

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.

## ScanMode

In what order a scan hands its keys over, `ustore_scan_mode_t`.

```mojo
struct ScanMode
```

- `ORDERED` = `ScanMode(Int32(0))`: In order, each once, and only while present.
- `UNORDERED` = `ScanMode(Int32(1))`: Possibly out of order, deleted or repeated, with no merge across partitions.
- `code` `c_int`: The raw `ustore_scan_mode_t` value the ABI exchanges.

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

## ScanDirection

Which way a scan, a cursor or a measure walks from its start key, `ustore_scan_direction_t`.

```mojo
struct ScanDirection
```

- `ASCENDING` = `ScanDirection(Int32(0))`: Up from the start, smallest key first.
- `DESCENDING` = `ScanDirection(Int32(1))`: Down from the start, largest key first.
- `code` `c_int`: The raw `ustore_scan_direction_t` value the ABI exchanges.

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

## ChangeKind

What one committed change did to its key, `ustore_change_kind_t`.

```mojo
struct ChangeKind
```

- `WRITE` = `ChangeKind(Int32(0))`: Wrote the whole value.
- `REMOVAL` = `ChangeKind(Int32(1))`: Removed the key.
- `CHANGE` = `ChangeKind(Int32(2))`: Changed part of the value.
- `code` `c_int`: The raw `ustore_change_kind_t` value the ABI exchanges.

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

## Admission

Whether a predicate keeps a listed key or passes over it, `ustore_admission_t`.

```mojo
struct Admission
```

- `REJECT` = `Admission(Int32(0))`: Pass over the key.
- `ADMIT` = `Admission(Int32(1))`: Keep the key.
- `code` `c_int`: The raw `ustore_admission_t` value the ABI exchanges.

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

## PredicateCost

How costly one predicate call is, which decides where in a scan it is asked, `ustore_predicate_cost_t`.

```mojo
struct PredicateCost
```

- `CHEAP` = `PredicateCost(Int32(0))`: Asked once per page of listed keys, before patterns or filters read any value.
- `EXPENSIVE` = `PredicateCost(Int32(1))`: Asked once per page about the keys patterns and filters kept.
- `code` `c_int`: The raw `ustore_predicate_cost_t` value the ABI exchanges.

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

## Predicate

The caller's verdict on the keys a scan lists, `ustore_predicate_t`, asked on the calling side in pages of keys, never concurrently with itself within one call.

```mojo
struct Predicate
```

- `callback` `Address`: The handler's C entry point; `NULL_ADDRESS` admits every key.
- `state` `Address`: Forwarded into every call; it must outlive the scan.
- `cost` `PredicateCost`: Where in a scan the handler is asked.

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

## __init__

No handler: every key is admitted.

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

## of

Asks `handler` about every page of listed keys, which writes one admission per key.

```mojo
def of[T: AnyType, origin: MutOrigin, //, handler: def(Span[Key, MutAnyOrigin], Span[Admission, MutAnyOrigin], Pointer[T, MutAnyOrigin]) thin -> None](
    state: Pointer[T, origin],
    cost: PredicateCost = PredicateCost.CHEAP
) -> Self
```

- `T` (comptime): What `state` points at, inferred from it.
- `origin` (comptime): The state's origin, inferred with it.
- `handler` (comptime): Called with the page's keys, their admissions to write, and `state`.
- `state`: Forwarded into every call; it must outlive the scan.
- `cost`: Where in a scan the handler is asked.

## Changes

The changes one pull of a feed yielded, oldest first, read in place from the arena it borrows.

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

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

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

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

## __init__

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

## __len__

The changes yielded, zero at the newest commit.

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

## keys

The key of every change.

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

## stamps

The stamp every change was committed at.

```mojo
def stamps(ref self) -> Span[Stamp, origin_of(self)]
```

## kinds

What every change did.

```mojo
def kinds(ref self) -> Span[ChangeKind, origin_of(self)]
```

## values

The bytes every change carries, empty for a removal or when the pull skipped them.

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

## ChangesCursor

A feed of the changes committed to one collection after a stamp, oldest first, freed when it goes out of scope. It pins its stamp and holds its database open until then.

```mojo
struct ChangesCursor
```

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

Conforms to: `Deinitable`, `Movable`

## __init__

Adopts a feed the engine just opened.

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

## __deinit__

Frees the feed, releasing its stamp. Calls `ustore_changes_cursor_free`.

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

## next

Pulls up to `wanted` next changes, with their values when asked. Calls `ustore_changes_cursor_next`.

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

- `executor`: The executor the pull runs on.
- `arena` (mut): The arena to rewind and refill, which the result borrows.
- `wanted`: Most changes the pull yields.
- `values`: Whether the bytes every change carries come too.

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

## DocsScanConfig

The bounds, order and filter of a scan over document keys.

```mojo
struct DocsScanConfig[end_origin: ImmOrigin = ImmUntrackedOrigin, filter_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `end_origin` (comptime): The borrowed end keys.
- `filter_origin` (comptime): The borrowed filter.

- `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.
- `filter` `BytesView[filter_origin]`: A JSONPath, or a bare root filter such as "?@.age>30", every listed document matches; zeroed 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.

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,
    filter: BytesView[filter_origin] = BytesView(),
    predicate: Predicate = Predicate(),
    progress: Progress = Progress()
)
```

## DocsCursorConfig

The bound, order and filter of a walk over one collection, the filter copied when the walk opens.

```mojo
struct DocsCursorConfig[filter_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `filter_origin` (comptime): The borrowed filter.

- `end_key` `Optional[Key]`: Key the walk stops before, exclusive; absent bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start key.
- `filter` `BytesView[filter_origin]`: A JSONPath or bare root filter every document the walk hands out matches; zeroed walks every key.
- `predicate` `Predicate`: The caller's verdict on the keys of every page.

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

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    end_key: Optional[Key] = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    filter: BytesView[filter_origin] = BytesView(),
    predicate: Predicate = Predicate()
)
```

## DocsCursor

A walk over the document keys of one collection, every pull resuming past the last key 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 DocsCursor
```

- `library` `Library`: The loaded engine.
- `database` `Address`: The `ustore_database_t` it walks.
- `address` `Address`: The `ustore_docs_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_docs_cursor_free`.

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

## next

Pulls the next page of up to `wanted` keys, with the whole documents when asked. Calls `ustore_docs_cursor_next`.

```mojo
def next(
    self,
    executor: Executor,
    mut arena: Arena,
    wanted: Int,
    values: Bool = True,
    progress: Progress = Progress()
) -> Pulled[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.

## GraphCursorConfig

The bound, order and verdict of a walk over the vertices of one collection.

```mojo
struct GraphCursorConfig
```

- `end_key` `Optional[Key]`: Vertex the walk stops before, exclusive; absent bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start key.
- `predicate` `Predicate`: The caller's verdict on the keys of every page.

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

## __init__

Unbounded, ascending, admitting every vertex.

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

## EffectiveKeys

The key every inserted element ended up with, minted or given, read in place from the arena an insert borrows.

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

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

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

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

## __init__

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

## __len__

The insertions the call carried.

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

## keys

The key of every inserted element.

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

## PagesCursorConfig

The bound, order and filter of a walk over one collection's pages, the filter copied when it opens.

```mojo
struct PagesCursorConfig[filter_origin: ImmOrigin = ImmUntrackedOrigin]
```

- `filter_origin` (comptime): The borrowed filter.

- `end_key` `Optional[Key]`: Key the walk stops before, exclusive; absent bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start key.
- `filter` `BytesView[filter_origin]`: A path in StringZilla's XPath subset every page the walk hands out holds a node of; zeroed walks every page.
- `predicate` `Predicate`: The caller's verdict on the keys of every page.

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

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    end_key: Optional[Key] = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    filter: BytesView[filter_origin] = BytesView(),
    predicate: Predicate = Predicate()
)
```

## PagesCursor

A walk over the page keys of one collection, every pull resuming past the last key 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 PagesCursor
```

- `library` `Library`: The loaded engine.
- `database` `Address`: The `ustore_database_t` it walks.
- `address` `Address`: The `ustore_pages_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_pages_cursor_free`.

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

## next

Pulls the next page of up to `wanted` keys, with the whole pages rendered when asked. Calls `ustore_pages_cursor_next`.

```mojo
def next(
    self,
    executor: Executor,
    mut arena: Arena,
    wanted: Int,
    values: Bool = True,
    outputs_encoding: PageEncoding = PageEncoding.XML,
    progress: Progress = Progress()
) -> Pulled[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.

## StringKeys

The keys a batch of strings map onto, read in place from the arena a strings read borrows.

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

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

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

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

## __init__

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

## __len__

The strings the read carried.

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

## present

Whether string `index` is present.

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

## keys

The key every string maps onto, nil for a missing one.

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

## PatternKind

What the strings of [`Patterns`](#Patterns) are matched as, `ustore_pattern_kind_t`.

```mojo
struct PatternKind
```

- `REGEX` = `PatternKind(Int32(0))`: Regular expressions, of which a listed value matches at least one somewhere.
- `SUBSTRINGS` = `PatternKind(Int32(1))`: Literal substrings, of which a listed value holds at least one.
- `code` `c_int`: The raw `ustore_pattern_kind_t` value the ABI exchanges.

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

## CaseSensitivity

Whether patterns compare bytes as they are or after Unicode case folding, `ustore_case_sensitivity_t`.

```mojo
struct CaseSensitivity
```

- `CASED` = `CaseSensitivity(Int32(0))`: Bytes as they are.
- `UNCASED` = `CaseSensitivity(Int32(1))`: Full Unicode case folding of both the patterns and the values.
- `code` `c_int`: The raw `ustore_case_sensitivity_t` value the ABI exchanges.

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

## Patterns

Patterns a scan keeps the values or strings matching, compiled once per call or per cursor.

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

- `origin` (comptime): The borrowed patterns and weights, kept alive for as long as these are used.

- `patterns` `StringsView[origin]`: The patterns; an empty batch matches everything.
- `kind` `PatternKind`: What the patterns are matched as.
- `sensitivity` `CaseSensitivity`: Whether matching folds case.
- `weights` `Optional[Pointer[Float32, origin]]`: One weight per substring pattern, which turns on scores; absent scores nothing.

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

## __init__

Matches everything.

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

```mojo
def __init__(
    out self,
    patterns: StringsView[origin],
    kind: PatternKind = PatternKind.REGEX,
    sensitivity: CaseSensitivity = CaseSensitivity.CASED
)
```

Matches `patterns` as `kind`, scoring nothing.

## arguments

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

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

