# Graphs

> UStore for C

A graph collection stores edges as triplets of a source, a target and an edge identifier, indexed from both ends.
The graph calls address a collection created with `ustore_modality_graph_k`, which the in-memory engine keeps apart from every collection of values.
Several edges between the same two vertices need distinct edge identifiers, and an edge without one gets `ustore_edge_id_default_k`.

- `ustore_graph_write_edges` adds edges together with their vertices.
- `ustore_graph_write_vertices` adds vertices without edges.
- `ustore_graph_read_edges` exports the degree and the edges of every requested vertex in the requested role.
- `ustore_graph_remove_edges` removes edges and keeps their vertices.
- `ustore_graph_remove_vertices` removes vertices together with all their edges.
- `ustore_graph_scan_vertices` lists the vertices, those without edges included, as `ustore_blobs_scan` lists keys; a missing vertex reads with the degree `ustore_vertex_degree_missing_k`.

```c
typedef struct triplet_t {
    ustore_key_t source;
    ustore_key_t target;
    ustore_key_t edge;
} triplet_t;

ustore_collection_id_t graph = {0};
ustore_collection_create(&(ustore_collection_create_t){
    .database = database,
    .outcome = &outcome,
    .modality = ustore_modality_graph_k,
    .collection = &graph,
});

triplet_t const triplets[2] = {
    {{.uuid.bytes[15] = 1}, {.uuid.bytes[15] = 2}, {.uuid.bytes[15] = 9}},
    {{.uuid.bytes[15] = 2}, {.uuid.bytes[15] = 3}, {.uuid.bytes[15] = 10}},
};
ustore_graph_write_edges(&(ustore_graph_write_edges_t){
    .database = database,
    .outcome = &outcome,
    .count = 2,
    .collections = {&graph, 0},
    .edges = {&triplets[0].edge, sizeof(triplet_t)},
    .sources = {&triplets[0].source, sizeof(triplet_t)},
    .targets = {&triplets[0].target, sizeof(triplet_t)},
});

ustore_key_t vertex = {.uuid.bytes[15] = 2};
ustore_vertex_role_t const role = ustore_vertex_role_any_k;
ustore_vertex_degree_t const* degrees = NULL;
ustore_length_t const* edges_offsets = NULL;
ustore_key_t const* edges = NULL;
ustore_graph_read_edges(&(ustore_graph_read_edges_t){
    .database = database,
    .outcome = &outcome,
    .count = 1,
    .collections = {&graph, 0},
    .vertices = {&vertex, sizeof(ustore_key_t)},
    .roles = {&role, 0},
    .degrees_per_vertex = &degrees,
    .edges_offsets = &edges_offsets,
    .edges_per_vertex = &edges,
    .arena = arena,
});
```

Every found edge takes three keys of `edges`: its source, its target and its identifier.
The edges of vertex `i` span from edge `edges_offsets[i]` up to edge `edges_offsets[i + 1]`, so a missing vertex spans none, and `edges_offsets` is required whenever `edges_per_vertex` is asked for.
Outgoing edges come first, sorted by target, then incoming edges, sorted by source, and a missing vertex has the degree `ustore_vertex_degree_missing_k`.
Roles matter only in directed graphs, where `ustore_vertex_role_source_k` and `ustore_vertex_role_target_k` select one direction, and roles with `NULL` data stand for `ustore_vertex_role_any_k`.

`#include <ustore/graph.h>`

## ustore_vertex_role_t

The role a vertex plays in an edge, where undirected graphs use [`ustore_vertex_role_any_k`](#ustore_vertex_role_any_k).

```c
enum ustore_vertex_role_t
```

In a joining graph the members of each collection must stay either sources or targets.

- `ustore_vertex_role_unknown_k` = `0`: No role.
- `ustore_vertex_role_source_k` = `1`: The vertex an edge leaves.
- `ustore_vertex_role_target_k` = `2`: The vertex an edge enters.
- `ustore_vertex_role_any_k` = `3`: Either end of an edge.

Spellings: ```
char const * ustore_vertex_role_name(ustore_vertex_role_t vertex_role);
```

```
ustore_vertex_role_t ustore_vertex_role_from_name(
    ustore_bytes_view_t name);
```

## ustore_vertex_roles_view_t

A strided run of roles, one per task, where `NULL` data stands for [`ustore_vertex_role_any_k`](#ustore_vertex_role_any_k).

```c
struct ustore_vertex_roles_view_t
```

- `data` `ustore_vertex_role_t const *`: First role of the run.
- `stride` `ustore_size_t`: Bytes between consecutive roles, where zero repeats the first one.

## ustore_vertex_degree_t

The number of edges a vertex connects to.

```c
typedef uint32_t ustore_vertex_degree_t;
```

## ustore_graph_vertices_cursor_t

An opaque handle to a walk over the vertex keys of one collection, which every pull resumes past the last key the pull before it handed out, as `[ustore_blobs_cursor_t](https://www.unum.cloud/docs/ustore/c/scans.md#ustore_blobs_cursor_t)` walks.

```c
typedef struct ustore_graph_vertices_cursor_handle_t * ustore_graph_vertices_cursor_t;
```

It holds its database open, and the transaction or snapshot it reads through, until [`ustore_graph_vertices_cursor_free`](#ustore_graph_vertices_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_graph_read_edges

Reads the edges connected to a batch of vertices.

```c
void ustore_graph_read_edges(ustore_graph_read_edges_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_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 stored value is no vertex.
- [`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 vertices.
- `collections`: Graph collections.
- `vertices`: Vertices whose edges are read.
- `roles`: Roles the vertices play in the wanted edges.
- `degrees_per_vertex`: Output for the degree of every vertex, with [`ustore_vertex_degree_missing_k`](#ustore_vertex_degree_missing_k) for missing ones, inside `arena`.
- `edges_offsets`: Optional output for `count` plus one offsets into `edges_per_vertex`, counted in edges, where a missing vertex spans none, inside `arena`; required with `edges_per_vertex`.
- `edges_per_vertex`: Optional output for the tape of edges, three keys per edge, 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`, `collections`, `vertices` or degrees output is missing, the edges are asked without their offsets, the `view` was made by neither view constructor or belongs to another engine, a watching read goes through a staged transaction, or a collection holds another modality.

## ustore_graph_write_edges

Writes a batch of edges between existing or new vertices.

```c
void ustore_graph_write_edges(ustore_graph_write_edges_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.
- `transaction`: Transaction the edits join, where `NULL` writes to the head.
- `count`: Number of edges.
- `collections`: Graph collections.
- `edges`: Identifiers of the edges, where `NULL` data gives each [`ustore_edge_id_default_k`](#ustore_edge_id_default_k).
- `sources`: Sources of the edges.
- `targets`: Targets of the edges.
- `durability`: How durable the edits are once the call finishes at the head; a transaction's commit decides its own.
- `watch`: Whether the `transaction` records the vertices it reads and writes for conflicts.

Statuses: - [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The `transaction` 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_read_only_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_read_only_k) The database was opened read-only.
- [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `collections`, `sources` or `targets` are missing, the `transaction` belongs to another engine or is staged, the `durability` or `watch` is unknown, a flushed write names a `transaction`, [`ustore_watch_none_k`](https://www.unum.cloud/docs/ustore/c/transactions.md#ustore_watch_none_k) comes without one on RocksDB and LevelDB, or a collection holds another modality.
- [`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_malformed_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_malformed_k) A stored value is no vertex, or a vertex outgrows what its NVMe collection admits.
- [`ustore_status_write_conflict_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_write_conflict_k) Concurrent commits kept conflicting, or a staged RocksDB transaction holds a vertex.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) The changes outgrow the NVMe transaction's buffer, or every shared NVMe channel is taken.

## ustore_graph_remove_edges

Removes a batch of edges.

```c
void ustore_graph_remove_edges(ustore_graph_remove_edges_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.
- `transaction`: Transaction the edits join, where `NULL` writes to the head.
- `count`: Number of edges.
- `collections`: Graph collections.
- `edges`: Identifiers of the edges, where `NULL` data gives each [`ustore_edge_id_default_k`](#ustore_edge_id_default_k).
- `sources`: Sources of the edges.
- `targets`: Targets of the edges.
- `durability`: How durable the edits are once the call finishes at the head; a transaction's commit decides its own.
- `watch`: Whether the `transaction` records the vertices it reads and writes for conflicts.

Statuses: - [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The `transaction` 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_read_only_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_read_only_k) The database was opened read-only.
- [`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) The `collections`, `sources` or `targets` are missing, the `transaction` belongs to another engine or is staged, the `durability` or `watch` is unknown, a flushed remove names a `transaction`, [`ustore_watch_none_k`](https://www.unum.cloud/docs/ustore/c/transactions.md#ustore_watch_none_k) comes without one on RocksDB and LevelDB, or a collection holds another modality.
- [`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_malformed_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_malformed_k) A stored value is no vertex, or a vertex outgrows what its NVMe collection admits.
- [`ustore_status_write_conflict_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_write_conflict_k) Concurrent commits kept conflicting, or a staged RocksDB transaction holds a vertex.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) The changes outgrow the NVMe transaction's buffer, or every shared NVMe channel is taken.

## ustore_graph_write_vertices

Writes a batch of vertices without edges, keeping those already present.

```c
void ustore_graph_write_vertices(
    ustore_graph_write_vertices_t *arguments);
```

[`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) means the `collections` or `vertices` are missing, the `transaction` belongs to another engine or is staged, the `durability` or `watch` is unknown, a flushed write names a `transaction`, [`ustore_watch_none_k`](https://www.unum.cloud/docs/ustore/c/transactions.md#ustore_watch_none_k) comes without one on RocksDB and LevelDB, or a collection holds another modality.

- [`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_malformed_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_malformed_k) A vertex outgrows what its NVMe collection admits.
- [`ustore_status_write_conflict_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_write_conflict_k) Concurrent commits kept conflicting, or a staged RocksDB transaction holds a vertex.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) The changes outgrow the NVMe transaction's buffer, or 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.
- `transaction`: Transaction the edits join, where `NULL` writes to the head.
- `count`: Number of vertices.
- `collections`: Graph collections.
- `vertices`: Vertices to insert unless present.
- `durability`: How durable the edits are once the call finishes at the head; a transaction's commit decides its own.
- `watch`: Whether the `transaction` records the vertices it reads and writes for conflicts.

Statuses: - [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The `transaction` 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_read_only_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_read_only_k) The database was opened read-only.

## ustore_graph_remove_vertices

Removes a batch of vertices together with every edge they belong to.

```c
void ustore_graph_remove_vertices(
    ustore_graph_remove_vertices_t *arguments);
```

[`ustore_status_invalid_argument_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_invalid_argument_k) means the `collections` or `vertices` are missing, the `transaction` belongs to another engine or is staged, the `durability` or `watch` is unknown, a flushed remove names a `transaction`, [`ustore_watch_none_k`](https://www.unum.cloud/docs/ustore/c/transactions.md#ustore_watch_none_k) comes without one on RocksDB and LevelDB, or a collection holds another modality.

- [`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_malformed_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_malformed_k) A stored value is no vertex, or a vertex outgrows what its NVMe collection admits.
- [`ustore_status_write_conflict_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_write_conflict_k) Concurrent commits kept conflicting, or a staged RocksDB transaction holds a vertex.
- [`ustore_status_capacity_exhausted_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_capacity_exhausted_k) The changes outgrow the NVMe transaction's buffer, or 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.
- `transaction`: Transaction the edits join, where `NULL` writes to the head.
- `count`: Number of vertices.
- `collections`: Graph collections.
- `vertices`: Vertices to remove, or the inclusive starts of ranges when `end_vertices` is given.
- `end_vertices`: Exclusive ends of the ranges of vertices to remove with their edges, or a zeroed view to remove `vertices` alone.
- `roles`: Roles of the vertices, needed only by joining graphs.
- `durability`: How durable the edits are once the call finishes at the head; a transaction's commit decides its own.
- `watch`: Whether the `transaction` records the vertices it reads and writes for conflicts.

Statuses: - [`ustore_status_contended_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_contended_k) The `transaction` 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_read_only_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_read_only_k) The database was opened read-only.

## ustore_graph_scan_vertices

Scans a batch of vertex ranges.

```c
void ustore_graph_scan_vertices(
    ustore_graph_scan_vertices_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_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`: Graph collections.
- `start_keys`: Vertex every scan starts from, inclusive, where `NULL` data starts at the first vertex in the `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.
- `predicate`: Optional verdict on the listed vertices, 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 vertices, scan after scan, inside `arena`.
- `arena`: Rewound by this call, then holding every output it writes; `NULL` is refused.
- `wanted`: Most vertices every scan returns.
- `mode`: In what order the vertices 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 `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_graph_vertices_cursor_init

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

```c
void ustore_graph_vertices_cursor_init(
    ustore_graph_vertices_cursor_init_t *arguments);
```

- `cursor`: Output for the new cursor, which the caller frees with [`ustore_graph_vertices_cursor_free`](#ustore_graph_vertices_cursor_free), or `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`: Graph collection whose vertices 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.
- `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, or a predicate cost is unknown.
- [`ustore_status_uninitialized_k`](https://www.unum.cloud/docs/ustore/c/errors.md#ustore_status_uninitialized_k) The `database` is `NULL`.

## ustore_graph_vertices_cursor_next

Pulls the next page of a walk.

```c
void ustore_graph_vertices_cursor_next(
    ustore_graph_vertices_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`.
- `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_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_graph_vertices_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_graph_vertices_cursor_free(
    ustore_graph_vertices_cursor_t cursor);
```

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

## ustore_graph_sample_vertices

Samples vertices from a batch of collections.

```c
void ustore_graph_sample_vertices(
    ustore_graph_sample_vertices_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_graph_measure_vertices

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

```c
void ustore_graph_measure_vertices(
    ustore_graph_measure_vertices_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 vertices in every range, inside `arena`.
- `max_cardinalities`: Optional output for the upper bound on the vertices 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_edge_id_default_k

The edge identifier of an edge that was given none, every bit of it set like [`ustore_key_unknown_k`](https://www.unum.cloud/docs/ustore/c/collections.md#ustore_key_unknown_k).

```c
ustore_key_t const ustore_edge_id_default_k;
```

## ustore_vertex_degree_missing_k

The degree reported for a missing vertex.

```c
ustore_vertex_degree_t const ustore_vertex_degree_missing_k;
```

