# Scans

> UStore for C++

`#include <ustore/blobs_range.hpp>`

## blobs_page_t

What one pull of a cursor hands over inside the arena it was given: the keys, and the values of the keys.

```cpp
struct blobs_page_t
```

- `keys` `std::span<ustore_key_t const>`
- `values` `sz::strings_view_t`

## match_t

What a scan or a cursor narrows its keys by, each part zeroed to keep every key: patterns over the values of blobs and strings, a JSONPath or XPath filter over documents and pages, and a predicate over the keys.

```cpp
struct match_t
```

- `patterns` `ustore_patterns_t`
- `filter` `ustore_bytes_view_t`
- `predicate` `ustore_predicate_t`

## size_range_t

Lower and upper bounds of an estimate.

```cpp
struct size_range_t
```

- `min` `std::size_t`
- `max` `std::size_t`

## size_estimates_t

Estimates of how many entries a key range holds and how much space they take.

```cpp
struct size_estimates_t
```

- `cardinality` `size_range_t`
- `bytes_in_values` `size_range_t`
- `bytes_on_disk` `size_range_t`

## keys_range_t

The keys of a collection slice, counted by streaming or sampled at random.

```cpp
struct keys_range_t
```

- `members` `blobs_range_t`

## pairs_range_t

The key-value pairs of a collection slice, counted by streaming.

```cpp
struct pairs_range_t
```

- `members` `blobs_range_t`

## keys_cursor

Owns a walk over the keys of one collection from its open until its destruction, which every pull resumes past the last key the pull before it handed out, at the view its receiver read at the open.

```cpp
template <typename handle_type_,
          typename init_type_,
          typename next_type_,
          void(*)(init_type_ *) init_,
          void(*)(next_type_ *) next_,
          void(*)(handle_type_) free_>
class keys_cursor
```

The explicit form of the streams below: every pull takes the caller's arena, which holds the page until its next call, so a binding hands the cursor any arena it keeps. It moves but never copies. One template serves the cursors of blobs, documents, pages and graph vertices, each spelled by its C handle and calls.

## keys_cursor

```cpp
keys_cursor() noexcept=default;
```

```cpp
keys_cursor(keys_cursor const &)=delete;
```

```cpp
keys_cursor(keys_cursor && other) noexcept;
```

## operator=

```cpp
keys_cursor & operator=(keys_cursor const &)=delete;
```

```cpp
keys_cursor & operator=(keys_cursor && other) noexcept;
```

## ~keys_cursor

```cpp
~keys_cursor() noexcept;
```

## next

Pulls up to `wanted` keys into `arena`, fewer once the walk nears its end and none past it.

```cpp
expected<std::span<ustore_key_t const>> next(
    std::size_t wanted,
    arena_t & arena) noexcept;
```

## next_pairs

Pulls up to `wanted` keys with their values into `arena` in one call, the other fields of `options`, such as the encoding pages render in, taken as they are.

```cpp
requires requires(next_type_ next) { next.values; }
expected<blobs_page_t> next_pairs(
    std::size_t wanted,
    arena_t & arena,
    next_type_ options = {}) noexcept;
```

## make

Opens a walk over the keys of `collection` from `start`, at the view [`receiver`](https://www.unum.cloud/docs/ustore/cpp/quickstart.md#receiver) reads, keeping the keys `match` admits, compiled once here.

```cpp
expected<keys_cursor> make(
    receiver_t receiver,
    ustore_collection_id_t collection,
    ustore_key_t start = smallest_key_k,
    match_t const & match = {}) noexcept;
```

## keys_stream_t

A stream over the keys of one collection that pulls them in pages through the scan of its modality, each page resuming past the last key of the one before it.

```cpp
class keys_stream_t
```

It keeps the arena holding the page in hand, so it moves but never copies, and prefers [`seek`](#seek) to being rebuilt. As shorthand for a range-based loop, which has no place for an arena, it owns that one arena for its lifetime. A page short of the read-ahead ends the stream, and a default-constructed stream is at the end.

## keys_stream_t

```cpp
keys_stream_t() noexcept=default;
```

```cpp
keys_stream_t(keys_stream_t &&) noexcept=default;
```

```cpp
keys_stream_t(keys_stream_t const &)=delete;
```

## operator=

```cpp
keys_stream_t & operator=(keys_stream_t &&) noexcept=default;
```

```cpp
keys_stream_t & operator=(keys_stream_t const &)=delete;
```

## seek

Restarts the stream at `key`.

```cpp
status_t seek(ustore_key_t key) noexcept;
```

## *

Advances like `advance`, but a failed pull ends the stream since a reference carries no status.

```cpp
keys_stream_t & operator++() noexcept;
```

## seek_to_next_*_to_next_batch

Pulls the page after the one in hand, which [`keys_batch`](#keys_batch) exposes.

```cpp
status_t seek_to_next__to_next_batch() noexcept;
```

## keys_batch

Exposes the whole page in hand, passed keys included, for use with [`seek_to_next_batch`](#seek_to_next_batch).

```cpp
std::span<ustore_key_t const> keys_batch() noexcept;
```

## *

```cpp
bool operator==(keys_stream_t const & other) const noexcept;
```

- `operator==`: other `keys_stream_t &`
- `operator==`: other `pairs_stream_t &`

## make

Opens a stream over the keys of `collection`, which holds `modality`, from `start`, pulling `read_ahead` of them a page into an arena of its own, made where the executor of [`receiver`](https://www.unum.cloud/docs/ustore/cpp/quickstart.md#receiver) computes.

```cpp
expected<keys_stream_t> make(
    receiver_t receiver,
    ustore_collection_id_t collection,
    ustore_key_t start,
    std::size_t read_ahead = default_read_ahead_k,
    ustore_modality_t modality = ustore_modality_blobs_k) noexcept;
```

## pairs_stream_t

A stream over the keys and values of one collection that pulls both in pages from a cursor, in one call per page.

```cpp
class pairs_stream_t
```

As shorthand for a range-based loop, which has no place for an arena, it owns that one arena for its lifetime, where `blobs_cursor_t` takes the caller's per pull. A default-constructed stream is at the end.

## pairs_stream_t

```cpp
pairs_stream_t() noexcept=default;
```

```cpp
pairs_stream_t(pairs_stream_t &&) noexcept=default;
```

```cpp
pairs_stream_t(pairs_stream_t const &)=delete;
```

## operator=

```cpp
pairs_stream_t & operator=(pairs_stream_t &&) noexcept=default;
```

```cpp
pairs_stream_t & operator=(pairs_stream_t const &)=delete;
```

## seek

Restarts the stream at `key`, through a cursor opened there.

```cpp
status_t seek(ustore_key_t key) noexcept;
```

## keys_batch

Exposes the keys of the whole page in hand, passed keys included, for use with [`seek_to_next_batch`](#seek_to_next_batch).

```cpp
std::span<ustore_key_t const> keys_batch() noexcept;
```

## make

Opens a stream over the pairs of `collection` from `start`, pulling `read_ahead` of them a page into an arena of its own, made where the executor of [`receiver`](https://www.unum.cloud/docs/ustore/cpp/quickstart.md#receiver) computes.

```cpp
expected<pairs_stream_t> make(
    receiver_t receiver,
    ustore_collection_id_t collection,
    ustore_key_t start,
    std::size_t read_ahead = default_read_ahead_k) noexcept;
```

## predicate_of

The predicate the ABI asks through `callable`, called as `callable(keys, admissions)` over spans once per page, at `cost`; `callable` must outlive the scan or the cursor given it.

```cpp
template <typename callable_type_>
ustore_predicate_t predicate_of(
    callable_type_ & callable,
    ustore_predicate_cost_t cost = ustore_predicate_cheap_k) noexcept;
```

## narrow

Copies what `match` narrows by into the arguments `call` takes, as far as they take each part.

```cpp
template <typename call_type_>
void narrow(call_type_ & call, match_t const & match) noexcept;
```

## scan_keys_through

Scans up to `wanted` keys of `collection` from `start` into `arena` through `scan_`, the scan of one modality keyed by UUIDs, at the view [`receiver`](https://www.unum.cloud/docs/ustore/cpp/quickstart.md#receiver) reads, keeping the keys `match` admits, and writing one BM25 score per key into `scores` when it is not null and the patterns carry weights.

```cpp
template <typename scan_type_, void(*)(scan_type_ *) scan_>
expected<std::span<ustore_key_t const>> scan_keys_through(
    receiver_t receiver,
    ustore_collection_id_t collection,
    ustore_key_t start,
    std::size_t wanted,
    arena_t & arena,
    match_t const & match = {},
    float const **scores = nullptr) noexcept;
```

## scan_keys

Scans up to `wanted` keys of `collection`, which holds `modality`, from `start` into `arena` through the scan of that modality: the documents, the vertices, the pages or the keys of blobs.

```cpp
expected<std::span<ustore_key_t const>> scan_keys(
    receiver_t receiver,
    ustore_modality_t modality,
    ustore_collection_id_t collection,
    ustore_key_t start,
    std::size_t wanted,
    arena_t & arena) noexcept;
```

