# Scans

> UStore for C

`ustore_blobs_scan` exports up to `wanted` keys per task, starting from `start_keys[index]`, or from the smallest key after it, and exports no values:

```c
ustore_key_t start = {0};
ustore_length_t const* offsets = NULL;
ustore_key_t const* found = NULL;
ustore_blobs_scan(&(ustore_blobs_scan_t){
    .database = database,
    .outcome = &outcome,
    .count = 1,
    .collections = {&values, 0},
    .start_keys = {&start, sizeof(ustore_key_t)},
    .offsets = &offsets,
    .keys = &found,
    .arena = arena,
    .wanted = 100,
});
```

Start keys with `NULL` data start every scan at the first key in its `direction`, and `end_keys` stop it before a key, where zeroed ones bound nothing.
`ustore_scan_ascending_k` walks the keys in `[start, end)` smallest first, and `ustore_scan_descending_k` those in `(end, start]` largest first.
The next ascending page starts from the key right after the last exported one, its 16 bytes incremented as one big-endian integer, a descending one from the key right before it, and a `ustore_blobs_read` of the found keys fetches their values.
`ustore_blobs_sample` draws up to `wanted` keys uniformly at random, and `ustore_blobs_measure` bounds the cardinality, value bytes and disk usage of a range of keys from below and above, taking the same start, end and direction as a scan.
Every other modality samples and measures through its own `_sample` and `_measure` verbs, where the strings modality samples strings and measures ranges of them.
`ustore_scan_unordered_k` is reserved for scans that may hand keys over out of order, and no engine acts on it yet.

### Cursors

A cursor walks the keys of one collection in pages, every pull resuming past the last key the pull before it handed out, and reads their values in the same call when `values` asks for them:

```c
ustore_blobs_cursor_t cursor = NULL;
ustore_blobs_cursor_init(&(ustore_blobs_cursor_init_t){
    .cursor = &cursor,
    .database = database,
    .outcome = &outcome,
    .collection = values,
});

ustore_size_t const wanted = 256;
ustore_size_t written = wanted, walked = 0;
ustore_key_t const* keys = NULL;
ustore_strings_view_t values = {0};
while (outcome.status == ustore_status_success_k && written == wanted) {
    ustore_blobs_cursor_next(&(ustore_blobs_cursor_next_t){
        .database = database,
        .outcome = &outcome,
        .cursor = cursor,
        .keys = &keys,
        .values = &values,
        .written = &written,
        .arena = arena,
        .wanted = wanted,
    });
    walked += written;
}
ustore_blobs_cursor_free(cursor);
```

`ustore_blobs_cursor_init` reads nothing, and its `view` and `start_key` choose what the walk sees and where it starts, the head and the first key when zeroed, while an `end_key` stops it before a key and `direction` walks it down from its start.
A cursor keeps only the key its next pull starts at, so a key written behind it is never handed out and one written ahead of it is, while `ustore_blobs_scan` stays the batched listing of many ranges.
A page shorter than `wanted` exhausts the walk for good: every later pull writes zero keys without reading, even after writes ahead of where it stopped.
A pull that fails or is cancelled leaves the cursor where it was, and a pull at the head lists and reads at two moments, so a key removed between them reads as an empty value.
The cursor holds its database open, and the transaction or snapshot it reads through, until `ustore_blobs_cursor_free`, so the caller may free those handles first.
It serves one pull at a time, and a second pull naming it finishes `ustore_status_contended_k`.
`ustore_strings_cursor_init` opens the same walk over the strings of one `prefix` from an optional `start_string` to an optional `end_string`, copying all three, and its pulls write the strings and their values as tapes.

`ustore_changes_cursor_init` opens a feed of the changes committed to one collection after `since_stamp`, oldest first, pinning that stamp as a snapshot does.
Every `ustore_changes_cursor_next` resumes past the last change the pull before it handed out, writing the key, the commit stamp and the `ustore_change_kind_t` of every change and, when asked, the bytes every change carries, where a range removal comes as the removal of every key it removed.
A key changed twice comes twice, once per commit, an empty pull reached the newest commit, and later pulls see later commits.
Versions already dropped refuse the init with `ustore_status_write_conflict_k`, and LevelDB, which keeps no stamps, with `ustore_status_unsupported_k`.

`#include <ustore/types.h>`

`#include <ustore/db.h>`

`#include <ustore/blobs.h>`

`#include <ustore/docs.h>`

`#include <ustore/pages.h>`

## ustore_pattern_kind_t

What the strings of a `[ustore_patterns_t](#ustore_patterns_t)` are matched as.

```c
enum ustore_pattern_kind_t
```

- `ustore_pattern_regex_k` = `0`: Regular expressions, of which a listed value matches at least one somewhere.
- `ustore_pattern_substrings_k` = `1`: Literal substrings, of which a listed value holds at least one, found together through Aho-Corasick.

Spellings: ```
char const * ustore_pattern_kind_name(ustore_pattern_kind_t kind);
```

```
ustore_pattern_kind_t ustore_pattern_kind_from_name(
    ustore_bytes_view_t name);
```

## ustore_case_sensitivity_t

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

```c
enum ustore_case_sensitivity_t
```

- `ustore_cased_k` = `0`: Bytes as they are.
- `ustore_uncased_k` = `1`: Full Unicode case folding of both the patterns and the values.

Spellings: ```
char const * ustore_case_sensitivity_name(
    ustore_case_sensitivity_t sensitivity);
```

```
ustore_case_sensitivity_t ustore_case_sensitivity_from_name(
    ustore_bytes_view_t name);
```

## ustore_patterns_t

Patterns a scan keeps the values or strings matching, shared by every task of the call and compiled once per call or once per cursor.

```c
struct ustore_patterns_t
```

A zeroed structure matches everything. Patterns that fail to compile refuse the call with [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k), carrying StringZilla's message.

- `patterns` `ustore_strings_view_t`: The patterns, where a zeroed view matches everything.
- `count` `ustore_size_t`: Number of strings in `patterns`.
- `kind` `ustore_pattern_kind_t`: What the patterns are matched as.
- `sensitivity` `ustore_case_sensitivity_t`: Whether matching folds case.
- `weights` `float const *`: Optional weight of every substring pattern, which turns on BM25 scores; refused with regexes.

## ustore_admission_t

Whether a predicate keeps a listed key or passes over it, numbered as USearch numbers its admissions.

```c
enum ustore_admission_t
```

- `ustore_reject_k` = `0`: Pass over the key.
- `ustore_admit_k` = `1`: Keep the key among the listed ones.

## ustore_predicate_callback_t

Admits or rejects `count` listed keys at once, never zero, writing one admission per key into `admissions`, a buffer the library owns for the call.

```c
typedef void(*) ustore_predicate_callback_t(ustore_key_t const *keys, ustore_admission_t *admissions, ustore_size_t count, void *state);
```

Runs on the thread running the call, never concurrently with itself within one call.

## ustore_predicate_cost_t

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

```c
enum ustore_predicate_cost_t
```

- `ustore_predicate_cheap_k` = `0`: Asked once per page of listed keys, before patterns or filters read any value, so it narrows those reads.
- `ustore_predicate_expensive_k` = `1`: Asked once per page about the keys patterns and filters kept, for handlers that pay per call, such as a lookup in an external database.

Spellings: ```
char const * ustore_predicate_cost_name(ustore_predicate_cost_t cost);
```

```
ustore_predicate_cost_t ustore_predicate_cost_from_name(
    ustore_bytes_view_t name);
```

## ustore_predicate_t

The caller's verdict on the keys a scan lists, always asked on the host, as a scan on a device executor lists its pages there too.

```c
struct ustore_predicate_t
```

- `callback` `ustore_predicate_callback_t`: The optional handler, where `NULL` admits every key.
- `state` `void *`: Opaque pointer passed to every `callback` call.
- `cost` `ustore_predicate_cost_t`: Where in a scan `callback` is asked.

## ustore_scan_mode_t

In what order a scan hands its keys over.

```c
enum ustore_scan_mode_t
```

- `ustore_scan_ordered_k` = `0`: Keys come in order, each once, and only while present.
- `ustore_scan_unordered_k` = `1`: Keys may come out of order, deleted or repeated, as each partition or run is walked on its own with no merge across them, so a page of fewer than all keys cannot resume where it ended.

Spellings: ```
char const * ustore_scan_mode_name(ustore_scan_mode_t scan_mode);
```

```
ustore_scan_mode_t ustore_scan_mode_from_name(ustore_bytes_view_t name);
```

## ustore_scan_direction_t

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

```c
enum ustore_scan_direction_t
```

- `ustore_scan_ascending_k` = `0`: Up from the start key, inclusive, to the end key, exclusive, smallest key first.
- `ustore_scan_descending_k` = `1`: Down from the start key, inclusive, to the end key, exclusive, largest key first.

Spellings: ```
char const * ustore_scan_direction_name(
    ustore_scan_direction_t scan_direction);
```

```
ustore_scan_direction_t ustore_scan_direction_from_name(
    ustore_bytes_view_t name);
```

## ustore_change_kind_t

What one committed change did to its key.

```c
enum ustore_change_kind_t
```

- `ustore_change_write_k` = `0`: Wrote the whole value.
- `ustore_change_removal_k` = `1`: Removed the key.
- `ustore_change_change_k` = `2`: Changed part of the value, as a document patch or a page edit does.

Spellings: ```
char const * ustore_change_kind_name(ustore_change_kind_t change_kind);
```

```
ustore_change_kind_t ustore_change_kind_from_name(
    ustore_bytes_view_t name);
```

## ustore_changes_cursor_t

An opaque feed of the changes committed to one collection after a stamp, oldest first.

```c
typedef struct ustore_changes_cursor_handle_t * ustore_changes_cursor_t;
```

It pins the stamp it reads from the way a snapshot does, so no compaction drops a version above it, and every pull resumes past the last change the pull before it handed out. Nothing reads ahead of the caller: a pull costs what it hands out. It serves one pull at a time and holds its database open until [`ustore_changes_cursor_free`](#ustore_changes_cursor_free).

## ustore_blobs_cursor_t

An opaque handle to a walk over the keys of one collection, which every pull resumes past the last key the pull before it handed out.

```c
typedef struct ustore_blobs_cursor_handle_t * ustore_blobs_cursor_t;
```

It keeps only the key its next pull starts at, so a key written behind the walk is never handed out and one written ahead of it is, while [`ustore_blobs_scan`](#ustore_blobs_scan) stays the batched listing of many ranges. It holds its database open, and the transaction or snapshot it reads through, until [`ustore_blobs_cursor_free`](#ustore_blobs_cursor_free). A cursor serves one pull at a time, so a second pull naming it finishes [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k).

## ustore_docs_cursor_t

An opaque handle to a walk over the document keys of one collection, which every pull resumes past the last key the pull before it handed out, as `[ustore_blobs_cursor_t](#ustore_blobs_cursor_t)` walks.

```c
typedef struct ustore_docs_cursor_handle_t * ustore_docs_cursor_t;
```

It holds its database open, and the transaction or snapshot it reads through, until [`ustore_docs_cursor_free`](#ustore_docs_cursor_free), and serves one pull at a time, so a second pull naming it finishes [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k).

## ustore_pages_cursor_t

An opaque handle to a walk over the page keys of one collection, which every pull resumes past the last key the pull before it handed out, as `[ustore_blobs_cursor_t](#ustore_blobs_cursor_t)` walks.

```c
typedef struct ustore_pages_cursor_handle_t * ustore_pages_cursor_t;
```

It holds its database open, and the transaction or snapshot it reads through, until [`ustore_pages_cursor_free`](#ustore_pages_cursor_free), and serves one pull at a time, so a second pull naming it finishes [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k).

## ustore_changes_cursor_init

Opens a feed of one collection's changes committed after a stamp, reading nothing yet.

```c
void ustore_changes_cursor_init(
    ustore_changes_cursor_init_t *arguments);
```

[`ustore_status_write_conflict_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_write_conflict_k) means the versions after `since_stamp` are already gone, as no pin kept them, which a starved snapshot reader is refused with too. The RAM engine also refuses a stamp below the head unless an open feed already pins one at or below it, while NVMe and RocksDB serve any stamp their history still holds.

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `collection`: The collection whose changes the cursor yields.
- `since_stamp`: Changes committed after this stamp are yielded, oldest first.
- `cursor`: Output for the new cursor, which pins `since_stamp` until [`ustore_changes_cursor_free`](#ustore_changes_cursor_free), or `NULL` on failure.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor` output is `NULL`.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL`.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The executor's deferred table is full, or a callback blocks on the executor running it.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) The collection does not exist or was dropped meanwhile.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device, or the engine keeps no stamps, as LevelDB does.

## ustore_changes_cursor_next

Pulls the next changes of a feed, oldest first, and their values when asked.

```c
void ustore_changes_cursor_next(
    ustore_changes_cursor_next_t *arguments);
```

A pull yields every change committed after the last one it handed out, up to `wanted`; a key changed twice comes twice, once per commit, and the changes of one commit come by key. A range removal comes as the removal of every key it covered.

- `cursor`: The feed to advance, which a pull that fails leaves where it was.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `wanted`: Most changes the pull yields, where fewer reach the newest commit.
- `count`: Output for the changes yielded, zero at the newest commit or on failure.
- `keys`: Output for the keys of the changes, oldest change first, inside `arena`.
- `stamps`: Output for the stamp every change was committed at, inside `arena`.
- `kinds`: Output for what every change did, inside `arena`.
- `values`: Optional output for the bytes every change carries as a tape inside `arena`, empty for a removal; `NULL` skips them.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor`, the `arena` or an output is `NULL`.
- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the cursor serves another call, the executor's deferred table is full, or a callback blocks on the executor running it.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) The collection was dropped meanwhile.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_changes_cursor_free

Waits until every deferred call naming the feed finishes, then frees it, releasing the stamp it pinned and the hold it kept on its database.

```c
void ustore_changes_cursor_free(ustore_changes_cursor_t cursor);
```

- `cursor` (inout): The feed to be freed; `NULL` is safe.

## ustore_blobs_scan

Scans a batch of key ranges.

```c
void ustore_blobs_scan(ustore_blobs_scan_t *arguments);
```

- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, a callback blocks on the executor running it, or an NVMe value keeps changing size across reads.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device, where no engine serves the call yet, or on one matching no values, as AMD devices do, given `patterns`.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of scans.
- `collections`: Collections to scan.
- `start_keys`: Inclusive start of every scan, `NULL` data starting at the first key in `direction`.
- `end_keys`: Key every scan stops before, exclusive, or a zeroed view for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `patterns`: Optional patterns the value of every listed key matches, shared by every scan; zeroed lists every key.
- `predicate`: Optional verdict on the listed keys, asked on the host once per page as its `cost` says.
- `offsets`: Output for `count` plus one offsets into `keys`, the last one closing the final scan, inside `arena`.
- `keys`: Output for the found keys, scan after scan, inside `arena`.
- `scores`: Optional output for one BM25 score per listed key when `patterns` carry weights, inside `arena`; `NULL` skips them.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys every scan returns.
- `mode`: In what order the keys come.
- `progress`: Optional callback reporting the scans finished.
- `progress_state`: Opaque pointer passed to `progress`.

Statuses: [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) means the `arena`, `collections` or an output is missing, the `mode`, `direction`, a pattern kind, a case sensitivity or a predicate cost is unknown, the `patterns` do not compile, the `view` was made by neither view constructor or belongs to another engine, a watching scan goes through a staged transaction, or a collection holds another modality.

## ustore_blobs_cursor_init

Opens a walk over the keys of one collection, reading nothing until its first pull.

```c
void ustore_blobs_cursor_init(ustore_blobs_cursor_init_t *arguments);
```

- `cursor`: Output for the new cursor, which the caller frees with [`ustore_blobs_cursor_free`](#ustore_blobs_cursor_free); `NULL` on failure.
- `database`: An open database.
- `executor`: Executor of the kind every pull runs on, which picks the side the walk computes on, where `NULL` walks on host executors; a pull on another kind of executor reports [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k).
- `outcome`: Output for the outcome, final on return.
- `view`: What the walk sees, where `NULL` is the head, read pull by pull.
- `collection`: Collection to walk, which holds keys rather than strings.
- `start_key`: Key the walk starts from, inclusive.
- `end_key`: Key the walk stops before, exclusive, or `NULL` for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `patterns`: Optional patterns every value the walk hands out matches, compiled here once; zeroed walks every key.
- `predicate`: Optional verdict on the keys of every page, asked as its `cost` says; host executors only.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor` output is `NULL`, the `view` was made by neither view constructor or reads another database, the `direction`, a pattern kind, a case sensitivity or a predicate cost is unknown, or the `patterns` do not compile.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL`.

## ustore_blobs_cursor_next

Pulls the next page of a walk, and the values of its keys when asked.

```c
void ustore_blobs_cursor_next(ustore_blobs_cursor_next_t *arguments);
```

- `database`: The database the cursor was opened on.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `cursor`: The cursor to advance, which a pull that fails or is cancelled leaves where it was.
- `keys`: Output for the keys of the page in their order, inside `arena`.
- `values`: Optional output for their values as a tape inside `arena`, so a walk reads without a second call, where a key removed at the head between the listing and the read of one pull reads as an empty value; `NULL` skips them.
- `written`: Output for the keys written, zero once the walk is exhausted; zeroed on failure.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys the page holds, where a page of fewer exhausts the walk.
- `progress`: Optional callback reporting the one pull, which may cancel it before the cursor advances.
- `progress_state`: Opaque pointer passed to `progress`.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor`, the `arena` or the `written` output is `NULL`, the cursor walks another database, a watching pull goes through a staged transaction, or the collection holds another modality.
- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes, a cursor opened for a device is pulled on host threads, or a host cursor is pulled on a device.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena, the cursor or the transaction it reads through serves another call, the executor's deferred table is full, a callback blocks on the executor running it, or an NVMe value keeps changing size across reads.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The pulling executor's device loaded no bundle of the library's kernels and the walk has `patterns`.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) The collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_*_cursor_free

Waits until every deferred call naming the cursor finishes, then frees it, giving back the holds it kept on its database and on the transaction or snapshot it reads through.

```c
void ustore_blobs_cursor_free(ustore_blobs_cursor_t cursor);
```

- `ustore_blobs_cursor_free`: cursor `ustore_blobs_cursor_t`
- `ustore_docs_cursor_free`: cursor `ustore_docs_cursor_t`
- `ustore_pages_cursor_free`: cursor `ustore_pages_cursor_t`

- `cursor` (inout): The cursor to be freed; `NULL` is safe.

## ustore_blobs_sample

Samples keys from a batch of collections.

```c
void ustore_blobs_sample(ustore_blobs_sample_t *arguments);
```

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of samples.
- `collections`: Collections to sample.
- `offsets`: Output for `count` plus one offsets into `keys`, the last one closing the final sample, inside `arena`.
- `keys`: Output for the sampled keys, sample after sample, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys every sample draws.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `arena`, `collections` or an output is missing, the `view` was made by neither view constructor or belongs to another engine, a watching sample goes through a staged transaction, or a collection holds another modality.
- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, a callback blocks on the executor running it, or an NVMe value keeps changing size across reads.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device, where no engine serves the call yet.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_blobs_measure

Estimates the entries and the space inside a batch of key ranges.

```c
void ustore_blobs_measure(ustore_blobs_measure_t *arguments);
```

- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, or a callback blocks on the executor running it.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device, where no engine serves the call yet.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of measured ranges.
- `collections`: Collections to measure.
- `start_keys`: Inclusive start of every range, `NULL` data starting at the first key in `direction`.
- `end_keys`: Key every range stops before, exclusive, or a zeroed view for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `min_cardinalities`: Optional output for the lower bound on the entries in every range, inside `arena`.
- `max_cardinalities`: Optional output for the upper bound on the entries in every range, inside `arena`.
- `min_value_bytes`: Optional output for the lower bound on the bytes of values in every range, inside `arena`.
- `max_value_bytes`: Optional output for the upper bound on the bytes of values in every range, inside `arena`.
- `min_space_usages`: Optional output for the lower bound on the disk space every range takes, inside `arena`.
- `max_space_usages`: Optional output for the upper bound on the disk space every range takes, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.

Statuses: [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) means the `arena` or the `collections` are missing, the `direction` is unknown, the `view` was made by neither view constructor or belongs to another engine, a watching measure goes through a staged transaction, or a collection holds another modality.

## ustore_docs_scan

Scans a batch of document key ranges.

```c
void ustore_docs_scan(ustore_docs_scan_t *arguments);
```

- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, a callback blocks on the executor running it, or an NVMe value keeps changing size across reads.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor's device loaded no bundle of the library's kernels and a `filter` is given.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_malformed_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_malformed_k) A document the `filter` reads does not parse.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of scans.
- `collections`: Collections to scan.
- `start_keys`: Inclusive start of every scan, `NULL` data starting at the first key in `direction`.
- `end_keys`: Key every scan stops before, exclusive, or a zeroed view for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `filter`: Optional JSONPath, or a bare root filter such as ``?
- `predicate`: Optional verdict on the listed keys, asked on the host once per page as its `cost` says.
- `offsets`: Output for `count` plus one offsets into `keys`, the last one closing the final scan, inside `arena`.
- `keys`: Output for the found keys, scan after scan, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys every scan returns.
- `mode`: In what order the keys come.
- `progress`: Optional callback reporting the scans finished.
- `progress_state`: Opaque pointer passed to `progress`.

Statuses: [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) means the `arena`, `collections` or an output is missing, the `mode`, `direction` or a predicate cost is unknown, the `filter` does not compile, the `view` was made by neither view constructor or belongs to another engine, a watching scan goes through a staged transaction, or a collection holds another modality.

## ustore_docs_cursor_init

Opens a walk over the document keys of one collection, compiling its filter once and reading nothing until its first pull.

```c
void ustore_docs_cursor_init(ustore_docs_cursor_init_t *arguments);
```

- `cursor`: Output for the new cursor, which the caller frees with [`ustore_docs_cursor_free`](#ustore_docs_cursor_free); `NULL` on failure.
- `database`: An open database.
- `executor`: Executor of the kind every pull runs on, which picks the side the walk computes on, where `NULL` walks on host executors; a pull on another kind of executor reports [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k).
- `outcome`: Output for the outcome, final on return.
- `view`: What the walk sees, where `NULL` is the head, read pull by pull.
- `collection`: Docs collection to walk.
- `start_key`: Key the walk starts from, inclusive.
- `end_key`: Key the walk stops before, exclusive, or `NULL` for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `filter`: Optional JSONPath or bare root filter every document the walk hands out matches, copied and compiled here once; a zeroed view walks every key.
- `predicate`: Optional verdict on the keys of every page, asked as its `cost` says; host executors only.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor` output is `NULL`, the `view` was made by neither view constructor or reads another database, a predicate cost is unknown, or the `filter` does not compile.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL`.

## ustore_docs_cursor_next

Pulls the next page of a walk, and the documents of its keys when asked.

```c
void ustore_docs_cursor_next(ustore_docs_cursor_next_t *arguments);
```

- `database`: The database the cursor was opened on.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `cursor`: The cursor to advance, which a pull that fails or is cancelled leaves where it was.
- `keys`: Output for the keys of the page in their order, inside `arena`.
- `values`: Optional output for the whole documents as a tape inside `arena`, where a key removed at the head between the listing and the read of one pull reads as an empty document; `NULL` skips them.
- `written`: Output for the keys written, zero once the walk is exhausted; zeroed on failure.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys the page holds, where a page of fewer exhausts the walk.
- `progress`: Optional callback reporting the one pull, which may cancel it before the cursor advances.
- `progress_state`: Opaque pointer passed to `progress`.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor`, the `arena` or the `written` output is `NULL`, the cursor walks another database, a watching pull goes through a staged transaction, or the collection holds another modality.
- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes, a cursor opened for a device is pulled on host threads, or a host cursor is pulled on a device.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena, the cursor or the transaction it reads through serves another call, the executor's deferred table is full, a callback blocks on the executor running it, or an NVMe value keeps changing size across reads.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The pulling executor's device loaded no bundle of the library's kernels and the walk has a `filter`.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) The collection does not exist or was dropped meanwhile.
- [`ustore_status_malformed_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_malformed_k) A document the filter reads does not parse.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_docs_sample

Samples document keys from a batch of collections.

```c
void ustore_docs_sample(ustore_docs_sample_t *arguments);
```

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of samples.
- `collections`: Collections to sample.
- `offsets`: Output for `count` plus one offsets into `keys`, the last one closing the final sample, inside `arena`.
- `keys`: Output for the sampled keys, sample after sample, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys every sample draws.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `arena`, `collections` or an output is missing, the `view` was made by neither view constructor or belongs to another engine, a watching sample goes through a staged transaction, or a collection holds another modality.
- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, a callback blocks on the executor running it, or an NVMe value keeps changing size across reads.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_docs_measure

Estimates the documents and the space inside a batch of key ranges.

```c
void ustore_docs_measure(ustore_docs_measure_t *arguments);
```

[`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) means the `arena` or the `collections` are missing, the `direction` is unknown, the `view` was made by neither view constructor or belongs to another engine, a watching measure goes through a staged transaction, or a collection holds another modality.

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of measured ranges.
- `collections`: Collections to measure.
- `start_keys`: Inclusive start of every range, `NULL` data starting at the first key in `direction`.
- `end_keys`: Key every range stops before, exclusive, or a zeroed view for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `min_cardinalities`: Optional output for the lower bound on the documents in every range, inside `arena`.
- `max_cardinalities`: Optional output for the upper bound on the documents in every range, inside `arena`.
- `min_value_bytes`: Optional output for the lower bound on the value bytes in every range, inside `arena`.
- `max_value_bytes`: Optional output for the upper bound on the value bytes in every range, inside `arena`.
- `min_space_usages`: Optional output for the lower bound on the disk space every range takes, inside `arena`.
- `max_space_usages`: Optional output for the upper bound on the disk space every range takes, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.

Statuses: - [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, or a callback blocks on the executor running it.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_pages_cursor_init

Opens a walk over the page keys of one collection, compiling its filter once and reading nothing until its first pull.

```c
void ustore_pages_cursor_init(ustore_pages_cursor_init_t *arguments);
```

- `cursor`: Output for the new cursor, which the caller frees with [`ustore_pages_cursor_free`](#ustore_pages_cursor_free); `NULL` on failure.
- `database`: An open database.
- `executor`: Executor of the kind every pull runs on, which picks the side the walk computes on, where `NULL` walks on host executors; a pull on another kind of executor reports [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k).
- `outcome`: Output for the outcome, final on return.
- `view`: What the walk sees, where `NULL` is the head, read pull by pull.
- `collection`: Pages collection to walk.
- `start_key`: Key the walk starts from, inclusive.
- `end_key`: Key the walk stops before, exclusive, or `NULL` for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `filter`: Optional path in StringZilla's XPath subset every page the walk hands out holds a node of, copied and compiled here once; a zeroed view walks every page.
- `predicate`: Optional verdict on the keys of every page, asked as its `cost` says; host executors only.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor` output is `NULL`, the `view` was made by neither view constructor or reads another database, a predicate cost is unknown, or the `filter` does not compile.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL`.

## ustore_pages_cursor_next

Pulls the next page of a walk, and the pages of its keys when asked.

```c
void ustore_pages_cursor_next(ustore_pages_cursor_next_t *arguments);
```

- `database`: The database the cursor was opened on.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `cursor`: The cursor to advance, which a pull that fails or is cancelled leaves where it was.
- `keys`: Output for the keys of the page in their order, inside `arena`.
- `values`: Optional output for the whole pages rendered as a tape inside `arena`, where a key removed at the head between the listing and the read of one pull renders empty; `NULL` skips them.
- `written`: Output for the keys written, zero once the walk is exhausted; zeroed on failure.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys the page holds, where a page of fewer exhausts the walk.
- `outputs_encoding`: Encoding the renderings of `values` are converted into.
- `progress`: Optional callback reporting the one pull, which may cancel it before the cursor advances.
- `progress_state`: Opaque pointer passed to `progress`.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `cursor`, the `arena` or the `written` output is `NULL`, the `outputs_encoding` is unknown, the cursor walks another database, a watching pull goes through a staged transaction, or the collection holds another modality.
- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes, a cursor opened for a device is pulled on host threads, or a host cursor is pulled on a device.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena, the cursor or the transaction it reads through serves another call, the executor's deferred table is full, a callback blocks on the executor running it, or an NVMe value keeps changing size across reads.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The `outputs_encoding` is HTML, Markdown or JSON, or the pulling executor's device loaded no bundle of the library's kernels and the walk has a `filter`.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) The collection does not exist or was dropped meanwhile.
- [`ustore_status_malformed_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_malformed_k) A stored page does not decode.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_pages_sample

Samples page keys from a batch of collections.

```c
void ustore_pages_sample(ustore_pages_sample_t *arguments);
```

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of samples.
- `collections`: Collections to sample.
- `offsets`: Output in `arena` for `count` plus one offsets into `keys`, the last closing them.
- `keys`: Output for the sampled keys, sample after sample, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most keys every sample draws.

Statuses: - [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `arena`, `collections` or an output is missing, the `view` was made by neither view constructor or belongs to another engine, a watching sample goes through a staged transaction, or a collection holds another modality.
- [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, or a callback blocks on the executor running it.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

## ustore_pages_measure

Estimates the pages and the space inside a batch of key ranges.

```c
void ustore_pages_measure(ustore_pages_measure_t *arguments);
```

[`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) means the `arena` or the `collections` are missing, the `direction` is unknown, the `view` was made by neither view constructor or belongs to another engine, a watching measure goes through a staged transaction, or a collection holds another modality.

- `database`: An open database.
- `executor`: Executor that runs the call, where `NULL` runs it on the calling thread.
- `outcome`: Output for the outcome, final once its status leaves [`ustore_status_deferred_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_deferred_k).
- `completion`: Whether the call returns final, the default, or once submitted.
- `view`: What the call sees, where `NULL` is the head.
- `count`: Number of measured ranges.
- `collections`: Collections to measure.
- `start_keys`: Inclusive start of every range, `NULL` data starting at the first key in `direction`.
- `end_keys`: Key every range stops before, exclusive, or a zeroed view for no bound.
- `direction`: Ascending, the default, or descending from the start key.
- `min_cardinalities`: Optional output for the lower bound on the pages in every range, inside `arena`.
- `max_cardinalities`: Optional output for the upper bound on the pages in every range, inside `arena`.
- `min_value_bytes`: Optional output for the lower bound on the value bytes in every range, inside `arena`.
- `max_value_bytes`: Optional output for the upper bound on the value bytes in every range, inside `arena`.
- `min_space_usages`: Optional output for the lower bound on the disk space every range takes, inside `arena`.
- `max_space_usages`: Optional output for the upper bound on the disk space every range takes, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.

Statuses: - [`ustore_status_device_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_device_k) The arena lives where another executor computes.
- [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The arena or the transaction the `view` reads through serves another call, the executor's deferred table is full, or a callback blocks on the executor running it.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL` or an NVMe transfer was cancelled.
- [`ustore_status_unsupported_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_unsupported_k) The executor computes on a device.
- [`ustore_status_not_found_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_not_found_k) A collection does not exist or was dropped meanwhile.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) Every shared NVMe channel is taken.

