class graph_collection_t A graph_collection_t batches edges and vertices, and can be used from inside a transaction like any other handle:
auto [graph, status] = db.create<graph_collection_t>("graph");
status = graph.write_edge(edge_t {key_from_integer(1), key_from_integer(2), key_from_integer(9)});
std::array<edge_t, 2> triplets {edge_t {key_from_integer(2), key_from_integer(3), key_from_integer(10)}, edge_t {key_from_integer(3), key_from_integer(4), key_from_integer(11)}};
status = graph.write_edges(edges(triplets));
expected<ustore_vertex_degree_t> degree = graph.degree(key_from_integer(2));
expected<bool> present = graph.present(key_from_integer(2));
auto successors = graph.successors(key_from_integer(2), arena);
auto between = graph.edges_between(key_from_integer(1), key_from_integer(2), arena);
auto touching = graph.read_edges(key_from_integer(3), arena, ustore_vertex_role_target_k);
std::array<ustore_key_t, 3> vertices {key_from_integer(1), key_from_integer(7), key_from_integer(2)};
expected<edges_view_t> leaving = graph.read_edges(strided(vertices).immutable(), arena);
edges_view_t of_missing = leaving->of_vertex(1); // empty, as vertex 7 is missingdegree and present of one vertex are shorthand, copying a scalar out of a one-off arena, while edges, neighbors and the degrees of a batch land in the arena the call is given.
The edges of a batch come in the order of its vertices, and their offsets split them by vertex, so of_vertex(i) views the edges of vertex i and a missing vertex has none. edges streams every edge of the collection, and vertex_stream every vertex, both reading ahead in batches.
API
Types
graph_collection_tA handle to one graph collection that reads and writes the head or the view of a transaction.
edges_spanEdges as three strided columns of sources, targets and edge identifiers, which the offsets of the read that exported them split by vertex.
template <typename id_type_>
struct edges_span Fields
sources | strided_span<id_type_> | |
|---|---|---|
targets | strided_span<id_type_> | |
ids | strided_span<id_type_> | |
offsets | std::span<ustore_length_t const> | One offset per vertex of the read plus one, counted in edges, where a missing vertex spans none; empty for edges no read exported. |
Classgraph_read_collection_tA handle to one graph collection that only reads, stored as an inverted index from every vertex to its edges, cheap to construct and to copy.14
class graph_read_collection_t It holds no state of its own, so any number of threads share it, at the head, inside a transaction or at a snapshot.
read_only_tThe handle a snapshot hands out for this kind of collection, which only reads.
using read_only_t = graph_read_collection_t; deferred_tThe twin a deferred receiver hands out, whose verbs answer deferred calls.
using deferred_t = deferred_graph_read_collection_t; modality_kWhat the collections this kind of handle addresses hold, which a creation records and a lookup checks.
ustore_modality_t modality_k; graph_read_collection_t
graph_read_collection_t() noexcept=default; graph_read_collection_t(
receiver_t receiver,
ustore_collection_id_t collection) noexcept; degreeReads the degree of vertex in role through a one-off arena.
expected<ustore_vertex_degree_t> degree(
ustore_key_t vertex,
ustore_vertex_role_t role = ustore_vertex_role_any_k,
ustore_watch_t watch = ustore_watch_keys_k) noexcept; degreesReads the degree of every vertex into arena.
expected<std::span<ustore_vertex_degree_t const>> degrees(
strided_span<ustore_key_t const> vertices,
arena_t & arena,
strided_span<ustore_vertex_role_t const> roles = {},
ustore_watch_t watch = ustore_watch_keys_k) noexcept; presentChecks whether vertex is present through a one-off arena, including a vertex without edges, as a vertex whose degree is known.
expected<bool> present(
ustore_key_t vertex,
ustore_watch_t watch = ustore_watch_keys_k) noexcept; expected<bits_view_t> present(
strided_span<ustore_key_t const> const & vertices,
std::span<ustore_octet_t> presences,
arena_t & arena,
ustore_watch_t watch = ustore_watch_keys_k) noexcept; Marks in presences, one bit per vertex, which of vertices are present, including those without any edges, reading their degrees into arena.
Statuses
status_code_t::invalid_argument_kThepresenceshold fewer bits thanvertices.
sizeCounts the vertices by streaming through all of them.
expected<std::size_t> size() noexcept; number_of_edgesCounts the edges by streaming through the outgoing edges of every vertex.
expected<std::size_t> number_of_edges() noexcept; read_edgesReads every edge that has vertex in role into arena.
expected<edges_view_t> read_edges(
ustore_key_t vertex,
arena_t & arena,
ustore_vertex_role_t role = ustore_vertex_role_any_k,
ustore_watch_t watch = ustore_watch_keys_k) noexcept; expected<edges_view_t> read_edges(
strided_span<ustore_key_t const> vertices,
arena_t & arena,
strided_span<ustore_vertex_role_t const> roles = {},
ustore_watch_t watch = ustore_watch_keys_k) noexcept; Reads every edge that has any of vertices in an allowed role into arena, split by vertex through the offsets of the answer, where undirected graphs may repeat an edge reversed.
edges_betweenReads the edges from source to target into arena.
expected<edges_view_t> edges_between(
ustore_key_t source,
ustore_key_t target,
arena_t & arena,
ustore_watch_t watch = ustore_watch_keys_k) noexcept; successorsReads the targets of the edges leaving vertex into arena.
expected<strided_span<ustore_key_t const>> successors(
ustore_key_t vertex,
arena_t & arena) noexcept; predecessorsReads the sources of the edges entering vertex into arena.
expected<strided_span<ustore_key_t const>> predecessors(
ustore_key_t vertex,
arena_t & arena) noexcept; neighborsLists the distinct neighbors of vertex in arena, reordering the edges it fetched there in place.
expected<strided_span<ustore_key_t const>> neighbors(
ustore_key_t vertex,
arena_t & arena,
ustore_vertex_role_t role = ustore_vertex_role_any_k) noexcept; Classgraph_stream_tA stream of every edge in a graph, pulled one page of vertices at a time from the vertex scans of its stream and in no particular order, the vertices into the arena of that stream and their edges into an arena of its own, as a read never takes its inputs from the arena it rewinds.6
class graph_stream_t It owns both for its lifetime as shorthand for a range-based loop, with no place for an arena. A default-constructed stream is at the end.
graph_stream_t
graph_stream_t() noexcept=default; graph_stream_t(graph_stream_t &&) noexcept=default; graph_stream_t(graph_stream_t const &)=delete; operator=
graph_stream_t & operator=(graph_stream_t &&) noexcept=default; graph_stream_t & operator=(graph_stream_t const &)=delete; operator++Advances like advance, but a failed fetch ends the stream since a reference carries no status.
graph_stream_t & operator++() noexcept; edges_batchExposes the whole fetched page, passed edges included, for use with seek_to_next_batch.
edges_view_t edges_batch() noexcept; operator==
bool operator==(graph_stream_t const & other) const noexcept; makeOpens a stream over the edges of collection in role, from the vertex start onwards, fetching the edges of read_ahead vertices a page.
expected<graph_stream_t> make(
receiver_t receiver,
ustore_collection_id_t collection,
ustore_vertex_role_t role,
ustore_key_t start,
std::size_t read_ahead = keys_stream_t::default_read_ahead_k) noexcept; Functions
exported_edgesThe edges a read of count vertices exported into its arena, split by vertex through its offsets.
edges_view_t exported_edges(
ustore_key_t const *edges,
ustore_length_t const *offsets,
std::size_t count) noexcept; edgesViews a contiguous container of edge_t as strided edge columns.
template <std::ranges::contiguous_range tuples_type_>
requires std::ranges::sized_range<tuples_type_>
auto edges(tuples_type_ && tuples) noexcept; TypesMember types4
graph_read_collection_t::adjacency_range_t | range<graph_stream_t> |
|---|---|
graph_stream_t::iterator_category | std::forward_iterator_tag |
graph_stream_t::difference_type | std::ptrdiff_t |
graph_stream_t::value_type | edge_t |