# Retrieval and Streaming

> USearch for Zig

`get` lands every vector stored under a key in the arena, one packed row per entry in insertion order, as the scalar you name; an absent key yields no rows.

```zig
const vectors = try index.get(key, .f32, &arena);
for (0..vectors.rows) |row| consume(try vectors.row(f32, row));
```

`DenseVectors.stride` is the byte pitch of each row and `columns` its dimensions, as the call reported them, which is how a sub-byte kind like `.u1x8` is read without arithmetic on its packing.
`row` refuses an element type other than the kind the rows were written as with `Error.InvalidArgument`, rather than reinterpreting them.

A cursor walks the index contents, reading each shard's publication watermark as it enters that shard, so an entry once passed is never revisited.
Without start keys it yields every entry as stored; with them, the starts' own entries first, then the entries those link to breadth-first, each once.
Each pull lands up to `wanted` keys in the arena, and the keys each links to when `links` is true; the vectors themselves come from `get`.

```zig
var cursor = try usearch.DenseCursor.init(index, &.{});
defer cursor.deinit();

while (true) {
    const batch = try index.on(executor).cursorNext(cursor, 1024, true, &arena);
    if (batch.written == 0) break; // exhausted
    consume(try batch.keys(), try batch.links(0));
}
```

A search stream is a resumable best-first traversal, so callers that post-filter aggressively pull until satisfied instead of guessing the "k" upfront.
It keeps walk state rather than a thread, so any number may stay open on one executor, and every pull is an ordinary verb naming the index again, so it runs on whichever receiver pulls.

```zig
var stream = try usearch.DenseSearchStream.init(index, try .ofRow(f32, &query), .{});
defer stream.deinit();

while (true) {
    const found = try (try index.on(executor).searchStreamNext(stream, 16, &arena)).query(0);
    if (found.keys.len == 0) break; // drained
    for (found.keys, found.scores) |key, distance| std.debug.print("{f} at {d}\n", .{ key, distance });
}
```

A drained walk answers an empty query, as the C interface does, so a loop ends on the first pull that lands nothing.

### Sampling

`sample` draws keys around `focus`, or across the whole index, each hanging from a shown or earlier draw and placed in three dimensions beside the `shown` keys already on screen, so a view grows one connected sample as it zooms.
Equal seeds, shown keys and focus draw equally, and a larger `wanted` draws a superset.

```zig
const draws = try index.on(executor).sample(256, &arena, .{ .shown = shown, .shown_coordinates = places, .focus = near, .seed = 42 });
for (try draws.keys(), try draws.entryOrdinals(), 0..) |key, entry_ordinal, position| {
    const parent = try draws.parents.query(position); // empty for a root
    const point = try draws.coordinates.row(f32, position);
    _ = .{ key, entry_ordinal, parent, point };
}
```

`const usearch = @import("usearch");`

`const DenseVectors = @import("usearch").DenseVectors;`

`const DenseCursorBatch = @import("usearch").DenseCursorBatch;`

`const DenseDraws = @import("usearch").DenseDraws;`

`const DenseCursor = @import("usearch").DenseCursor;`

`const DenseSearchStream = @import("usearch").DenseSearchStream;`

## DenseSampleConfig

Optional settings of [`DenseIndex.sample`](https://www.unum.cloud/docs/usearch/zig/metrics.md#sample).

```zig
pub const DenseSampleConfig = struct
```

- `shown` `[]const Key`: The keys already shown: never drawn again, and the paths reach toward them.
- `shown_coordinates` `[]const [3]f32`: Where each `shown` key sits, one point apiece.
- `focus` `[]const Key`: The keys to look around; empty looks around the whole index.
- `seed` `u64`: Equal seeds, shown keys and focus over an unchanged index draw equally.
- `expansion_factor` `usize`: The breadth of the candidates of the walks behind the draws; zero derives.
- `progress` `ProgressCallback`
- `progress_steps` `usize`: Reports the call makes at most, the last at completion; zero derives to ten.
- `stats` `?*DenseTraversalStats`

## DenseSearchStreamInitConfig

Optional settings of [`DenseSearchStream.init`](#init).

```zig
pub const DenseSearchStreamInitConfig = struct
```

- `expansion_factor` `usize`: The breadth of the candidates the walk explores; zero derives.
- `diagnostics` `?*Outcome`: Where the call's final outcome, its static message included, is copied; null copies nothing.

## DenseGet

One [`DenseIndex.get`](https://www.unum.cloud/docs/usearch/zig/metrics.md#get), as a [`Deferred`](https://www.unum.cloud/docs/usearch/zig/executors.md#Deferred) holds it.

```zig
pub const DenseGet = struct
```

- `key` `Key`
- `scalar` `Scalar`
- `stamp` `Arena.Stamp`: The call the borrowed arena serves, which every view over the outputs carries.
- `vectors` `usearch_rows_view_t`
- `written` `usize`
- `outcome` `Outcome`

## DenseSample

One [`DenseIndex.sample`](https://www.unum.cloud/docs/usearch/zig/metrics.md#sample), as a [`Deferred`](https://www.unum.cloud/docs/usearch/zig/executors.md#Deferred) holds it.

```zig
pub const DenseSample = struct
```

- `wanted` `usize`
- `config` `DenseSampleConfig`
- `stamp` `Arena.Stamp`: The call the borrowed arena serves, which every view over the outputs carries.
- `keys` `usearch_keys_view_t`
- `entry_ordinals` `?[*]const usize`
- `parents` `usearch_matches_view_t`
- `coordinates` `usearch_rows_view_t`
- `written` `usize`
- `outcome` `Outcome`

## DenseCursorNext

One [`DenseIndex.cursorNext`](https://www.unum.cloud/docs/usearch/zig/metrics.md#cursorNext), as a [`Deferred`](https://www.unum.cloud/docs/usearch/zig/executors.md#Deferred) holds it.

```zig
pub const DenseCursorNext = struct
```

- `cursor` `DenseCursor`
- `wanted` `usize`
- `links` `bool`
- `stamp` `Arena.Stamp`: The call the borrowed arena serves, which every view over the outputs carries.
- `keys` `usearch_keys_view_t`
- `linked` `usearch_keys_tape_view_t`
- `written` `usize`
- `outcome` `Outcome`

## DenseSearchStreamNext

One [`DenseIndex.searchStreamNext`](https://www.unum.cloud/docs/usearch/zig/metrics.md#searchStreamNext), as a [`Deferred`](https://www.unum.cloud/docs/usearch/zig/executors.md#Deferred) holds it.

```zig
pub const DenseSearchStreamNext = struct
```

- `stream` `DenseSearchStream`
- `wanted` `usize`
- `stamp` `Arena.Stamp`: The call the borrowed arena serves, which every view over the outputs carries.
- `matches` `usearch_matches_view_t`
- `outcome` `Outcome`

## DenseVectors

Rows a call wrote packed into an arena - [`get`](https://www.unum.cloud/docs/usearch/zig/metrics.md#get) one per entry under the key, [`attend`](https://www.unum.cloud/docs/usearch/zig/metrics.md#attend) one per query, a cursor pull one per entry - `stride` bytes apiece, which sub-byte kinds round up to whole bytes.

```zig
pub const DenseVectors = struct
```

Mirrors `usearch_rows_view_t`.

It reads the arena, so every read is refused once that arena serves another call or is freed.

- `stamp` `Arena.Stamp`
- `data` `?[*]const u8`
- `rows` `usize`: Rows written.
- `stride` `usize`: Bytes per row, as the call reported them.
- `columns` `usize`: Dimensions per row, as the call reported them.
- `scalar` `Scalar`: The scalar type the rows were written as.

## row

One row as a run of `Element`, the type the rows were written as; any other type and a `position` past `rows` are refused with [`Error.InvalidArgument`](https://www.unum.cloud/docs/usearch/zig/errors.md#InvalidArgument), a stale view with [`Error.Uninitialized`](https://www.unum.cloud/docs/usearch/zig/errors.md#Uninitialized), and device memory with [`Error.Device`](https://www.unum.cloud/docs/usearch/zig/errors.md#Device).

```zig
pub fn row(
    self: DenseVectors,
    comptime Element: type,
    position: usize,
) Error![]const Element
```

## bytes

Every row, back to back, refused as [`row`](#row) refuses a stale view or device memory.

```zig
pub fn bytes(self: DenseVectors) Error![]const u8
```

## residency

Where the rows live, which the host reads only as `.ram` or `.nvme`.

```zig
pub fn residency(self: DenseVectors) Residency
```

## DenseCursorBatch

One batch a [`DenseCursor`](#DenseCursor) pull wrote into an arena: the keys, and the keys each links to where asked for; the vectors themselves come from [`DenseIndex.get`](https://www.unum.cloud/docs/usearch/zig/metrics.md#get).

```zig
pub const DenseCursorBatch = struct
```

It reads the arena, so every read is refused once that arena serves another call or is freed.

- `stamp` `Arena.Stamp`
- `data` `?[*]const Key`
- `written` `usize`: Entries the pull wrote; zero once the walk is exhausted.
- `linked` `?usearch_keys_tape_view_t`: The keys each entry links to, or null where the pull exported keys alone.

## keys

The keys, refusing a stale view with [`Error.Uninitialized`](https://www.unum.cloud/docs/usearch/zig/errors.md#Uninitialized) and device memory with [`Error.Device`](https://www.unum.cloud/docs/usearch/zig/errors.md#Device).

```zig
pub fn keys(self: DenseCursorBatch) Error![]const Key
```

## links

The keys one entry links to, refusing a `position` past `written` or a pull that exported no links with [`Error.InvalidArgument`](https://www.unum.cloud/docs/usearch/zig/errors.md#InvalidArgument), and a stale view or device memory as [`keys`](#keys) does.

```zig
pub fn links(
    self: DenseCursorBatch,
    position: usize,
) Error![]const Key
```

## DenseDraws

The draws [`DenseIndex.sample`](https://www.unum.cloud/docs/usearch/zig/metrics.md#sample) wrote in an arena, one per draw: its key, which of that key's entries it is, the shown or earlier draw it hangs from, and where it is placed.

```zig
pub const DenseDraws = struct
```

It reads the arena, so every read is refused once that arena serves another call or is freed.

- `stamp` `Arena.Stamp`
- `written` `usize`: Draws written; fewer than `wanted` only once the region is exhausted.
- `keys_data` `?[*]const Key`
- `entry_ordinals_data` `?[*]const usize`
- `parents` `Matches`: Each draw's parent and its distance, as a one-column run per draw; a root holds none.
- `coordinates` `DenseVectors`: Where each draw is placed, one row of three [`f32`](https://www.unum.cloud/docs/usearch/zig/inputs-and-outputs.md#f32) apiece.

## keys

The keys drawn, refusing a stale view with [`Error.Uninitialized`](https://www.unum.cloud/docs/usearch/zig/errors.md#Uninitialized) and device memory with [`Error.Device`](https://www.unum.cloud/docs/usearch/zig/errors.md#Device).

```zig
pub fn keys(self: DenseDraws) Error![]const Key
```

## entryOrdinals

Which of its key's entries each draw is, in the order [`get`](https://www.unum.cloud/docs/usearch/zig/metrics.md#get) writes them, refused as [`keys`](#keys) is.

```zig
pub fn entryOrdinals(self: DenseDraws) Error![]const usize
```

## DenseCursor

A sequential walk over the index contents - export, migration, and visualization feed off it.

```zig
pub const DenseCursor = struct
```

Every pull names the index again, through [`DenseIndex.cursorNext`](https://www.unum.cloud/docs/usearch/zig/metrics.md#cursorNext), so free the cursor
before the index. Mirrors `usearch_dense_cursor_t`.

- `handle` `?*anyopaque`: The opaque `usearch_dense_cursor_t` the ABI hands back.

## init

Opens a walk over the current contents; each shard's publication watermark is read as the walk enters it, so an entry once passed is never revisited.

```zig
pub fn init(
    index: DenseIndex,
    starts: []const Key,
) Error!DenseCursor
```

Without `starts` it yields every
entry as stored; with them, the start keys' own entries first in order, then the entries
those link to breadth-first, each once. Calls `usearch_dense_cursor_init`.

## deinit

Releases the cursor, waiting for every deferred pull naming it.

```zig
pub fn deinit(self: *DenseCursor) void
```

Calls `usearch_dense_cursor_free`.

## DenseSearchStream

A resumable nearest-neighbor stream over one query.

```zig
pub const DenseSearchStream = struct
```

Best-first traversal is naturally pausable, so the stream keeps a live frontier and visited
set and yields matches lazily - callers that post-filter aggressively pull until satisfied
instead of guessing "k" upfront. It keeps walk state rather than a thread, and every pull names
the index again through [`DenseIndex.searchStreamNext`](https://www.unum.cloud/docs/usearch/zig/metrics.md#searchStreamNext), so free the stream before the index.
Mirrors `usearch_dense_search_stream_t`.

- `handle` `?*anyopaque`: The opaque `usearch_dense_search_stream_t` the ABI hands back.

## init

Opens a stream for one query row, refusing a run of several with [`Error.ShapeMismatch`](https://www.unum.cloud/docs/usearch/zig/errors.md#ShapeMismatch).

```zig
pub fn init(
    index: DenseIndex,
    query: RowsView,
    config: DenseSearchStreamInitConfig,
) Error!DenseSearchStream
```

Calls `usearch_dense_search_stream_init`.

## deinit

Releases the stream and the walk state it keeps, waiting for every deferred pull naming it.

```zig
pub fn deinit(self: *DenseSearchStream) void
```

Calls `usearch_dense_search_stream_free`.

