From d9dc10299314769f3b2eb208cf7596a7ab4938ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Fri, 24 Jul 2026 10:06:43 +0200 Subject: [PATCH] Add documentation for models::append_graph module --- src/models/append_graph.rs | 53 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/models/append_graph.rs b/src/models/append_graph.rs index 9ccfef7..89bbea6 100644 --- a/src/models/append_graph.rs +++ b/src/models/append_graph.rs @@ -1,13 +1,24 @@ use crate::maps::{EdgeMap, VertexMap}; use crate::traits::{GraphTopology, IncidenceCursor}; +/// An opaque handle identifying a vertex in an [`AppendGraph`]. +/// +/// Handles are stable for the lifetime of the graph. They can be obtained via graph methods like +/// [`GraphTopology::add_vertex`] and [`GraphTopology::vertices`]. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct Vertex(usize); +/// An opaque handle identifying an edge in an [`AppendGraph`]. +/// +/// Handles are stable for the lifetime of the graph. They can be obtained via graph methods like +/// [`GraphTopology::add_edge`] and [`GraphTopology::edges`]. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct Edge(usize); +/// A [`VertexMap`] for [`AppendGraph`] vertices. pub type AppendGraphVertexMap = VertexMap; + +/// An [`EdgeMap`] for [`AppendGraph`] edges. pub type AppendGraphEdgeMap = EdgeMap; impl Edge { @@ -16,6 +27,7 @@ impl Edge { } } +// TODO: Check if VertexIncidenceHeader and IncidenceEntry can be made smaller. Currently they both take 24 bytes (on 64bit), see https://stackoverflow.com/a/79653173 struct VertexIncidenceHeader { incidence_count: usize, first_incidence: Option, @@ -27,6 +39,10 @@ struct IncidenceEntry { adjacent: Vertex, } +/// A resumable cursor over the incidences of a single vertex in an [`AppendGraph`]. +/// +/// Can be obtained via [`GraphTopology::incidence_cursor`]. See [`IncidenceCursor`] on how to use +/// it. #[derive(Copy, Clone)] pub struct AppendGraphIncidenceCursor { incidence: Option, @@ -38,12 +54,45 @@ impl IncidenceCursor for AppendGraphIncidenceCursor { } } +/// An undirected graph that supports adding vertices and edges, but not deleting them. +/// +/// `AppendGraph` is optimised for workloads that incrementally build a graph and query it +/// repeatedly. [`Vertex`] +/// and [`Edge`] handles are never invalidated. Use [`Graph`] instead if you need to remove vertices +/// or edges. +/// +/// Incidences are stored as interlaced adjacency lists in a single flat [`Vec`]. This means that +/// vertex neighborhood traversals in general result in scattered index jumps. +/// +/// # Examples +/// +/// ``` +/// use grapherity::prelude::*; +/// use grapherity::models::AppendGraph; +/// +/// let mut graph = AppendGraph::new(); +/// let v1 = graph.add_vertex(); +/// let v2 = graph.add_vertex(); +/// let e = graph.add_edge(v1, v2); +/// assert!(graph.are_adjacent(v1, v2)); +/// ``` +/// +/// # Time and space complexity +/// +/// Both [`add_vertex`] and [`add_edge`] run in amortised *O(1)* time. [`degree`] runs in *O(1)* +/// time since vertex degrees are stored. Space complexity is *O(|V| + |E|)*. +/// +/// [`add_vertex`]: Self::add_vertex +/// [`add_edge`]: Self::add_edge +/// [`degree`]: Self::degree +/// [`Graph`]: crate::models::Graph pub struct AppendGraph { vertices: Vec, incidences: Vec, } impl AppendGraph { + /// Creates an empty graph instance with no vertices or edges. pub fn new() -> Self { Self { vertices: vec![], @@ -51,8 +100,8 @@ impl AppendGraph { } } - // Adds a single incidence of an edge, which is composed by two such incidences, to the - // incidences vector. + /// Adds a single incidence of an edge, which is composed by two such incidences, to the + /// incidences vector. fn add_incidence(&mut self, v1: Vertex, v2: Vertex) { self.incidences.push(IncidenceEntry { next: self.vertices[v1.0].first_incidence.take(),