# Graphs

> UStore for Mojo

`from ustore import VertexRole, Edges, GraphScanConfig, …`

## VertexRolesView

A strided run of roles, `ustore_vertex_roles_view_t`; zeroed stands for [`ANY`](#ANY).

```mojo
comptime VertexRolesView[origin: ImmOrigin = ImmUntrackedOrigin]: AnyStruct[StridedView[VertexRole, origin]] = StridedView[VertexRole, origin]
```

## VertexRole

The role a vertex plays in an edge, `ustore_vertex_role_t`; undirected graphs use [`ANY`](#ANY).

```mojo
struct VertexRole
```

- `UNKNOWN` = `VertexRole(Int32(0))`: No role.
- `SOURCE` = `VertexRole(Int32(1))`: The vertex an edge leaves.
- `TARGET` = `VertexRole(Int32(2))`: The vertex an edge enters.
- `ANY` = `VertexRole(Int32(3))`: Either end of an edge.
- `code` `c_int`: The raw `ustore_vertex_role_t` value the ABI exchanges.

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

## Edges

The edges of a batch of vertices, three keys per edge, read in place from the arena a read borrows.

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

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

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

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

## __init__

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

## __len__

The vertices the read carried.

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

## degrees

The degree of every vertex, [`VERTEX_DEGREE_MISSING`](#VERTEX_DEGREE_MISSING) for a missing one.

```mojo
def degrees(ref self) -> Span[UInt32, origin_of(self)]
```

## offsets

The vertices' boundaries in edges, one more of them than vertices; empty unless edges were asked for.

```mojo
def offsets(ref self) -> Span[UInt64, origin_of(self)]
```

## edges

The edges of vertex `vertex`, each as its source, target and edge identifier.

```mojo
def edges(ref self, vertex: Int) -> Span[Key, origin_of(self)]
```

## GraphScanConfig

The bounds, order and verdict of a scan over vertices.

```mojo
struct GraphScanConfig[end_origin: ImmOrigin = ImmUntrackedOrigin]
```

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

- `end_keys` `StridedView[Key, end_origin]`: Vertex every scan stops before, exclusive; zeroed bounds nothing.
- `direction` `ScanDirection`: Ascending or descending from the start keys.
- `mode` `ScanMode`: In what order the vertices come.
- `predicate` `Predicate`: The caller's verdict on the listed vertices.
- `progress` `Progress`: Reports the scans finished, and stops the call where it says to.

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

## __init__

Names only the knobs that differ from the defaults.

```mojo
def __init__(
    out self,
    *,
    end_keys: StridedView[Key, end_origin] = StridedView(),
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    predicate: Predicate = Predicate(),
    progress: Progress = Progress()
)
```

## GraphVerticesCursor

A walk over the vertices of one graph collection, every pull resuming past the last vertex the pull before it handed out, freed when it goes out of scope. It holds its database open, and the transaction or snapshot it reads through.

```mojo
struct GraphVerticesCursor
```

- `library` `Library`: The loaded engine.
- `database` `Address`: The `ustore_database_t` it walks.
- `address` `Address`: The `ustore_graph_vertices_cursor_t`.

Conforms to: `Deinitable`, `Movable`

## __init__

Adopts a cursor the engine just opened.

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

## __deinit__

Frees the cursor and the holds it kept. Calls `ustore_graph_vertices_cursor_free`.

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

## next

Pulls the next page of up to `wanted` vertices. Calls `ustore_graph_vertices_cursor_next`.

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

Raises: [`Error`](https://www.unum.cloud/docs/ustore/mojo/errors.md#Error) with [`CANCELLED`](https://www.unum.cloud/docs/ustore/mojo/errors.md#CANCELLED) when `progress` stops the pull, which leaves the cursor where it was.

## VERTEX_DEGREE_MISSING

The degree a read reports for a missing vertex.

```mojo
comptime VERTEX_DEGREE_MISSING = UInt32(4294967295)
```

## Overview

An edge is a source, a target and an optional edge identifier, so distinct identifiers let a pair of
vertices share several edges. One collection holds an undirected or a directed graph over its own
vertices, or a joining graph between two collections.

