Initial release #1

Merged
warrence merged 102 commits from dev into main 2026-06-30 10:26:52 +02:00
3 changed files with 54 additions and 27 deletions
Showing only changes of commit f009a86f1e - Show all commits
+27 -25
View File
@@ -1,5 +1,5 @@
use crate::maps::{EdgeMap, VertexMap};
use crate::traits::GraphTopology;
use crate::traits::{GraphTopology, IncidenceCursor};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Vertex(usize);
@@ -18,24 +18,20 @@ struct VertexIncidenceHeader {
first_incidence: Option<Incidence>,
}
#[derive(Copy, Clone)]
struct IncidenceEntry {
next: Option<Incidence>,
adjacent: Vertex,
}
struct RawIncidenceIterator<'a> {
graph: &'a AppendGraph,
#[derive(Copy, Clone)]
pub struct AppendGraphIncidenceCursor {
incidence: Option<Incidence>,
}
impl<'a> Iterator for RawIncidenceIterator<'a> {
type Item = (Vertex, Incidence);
fn next(&mut self) -> Option<Self::Item> {
let current = self.incidence?;
let entry = &self.graph.incidences[current.0];
self.incidence = entry.next;
Some((entry.adjacent, current))
impl IncidenceCursor<AppendGraph> for AppendGraphIncidenceCursor {
fn next(&mut self, graph: &AppendGraph) -> Option<(Vertex, Incidence)> {
graph.step_incidence(&mut self.incidence)
}
}
@@ -62,6 +58,18 @@ impl AppendGraph {
self.vertices[v1.0].incidence_count += 1;
self.vertices[v1.0].first_incidence = Some(Incidence(self.incidences.len() - 1));
}
fn raw_incidences(&self, v: Vertex) -> impl Iterator<Item = (Vertex, Incidence)> {
let mut incidence = self.vertices[v.0].first_incidence;
std::iter::from_fn(move || self.step_incidence(&mut incidence))
}
fn step_incidence(&self, incidence: &mut Option<Incidence>) -> Option<(Vertex, Incidence)> {
let current = (*incidence)?;
let entry = self.incidences[current.0];
*incidence = entry.next;
Some((entry.adjacent, current))
}
}
impl Default for AppendGraph {
@@ -72,8 +80,8 @@ impl Default for AppendGraph {
impl GraphTopology for AppendGraph {
type Vertex = Vertex;
type Edge = Incidence;
type IncidenceCursor = AppendGraphIncidenceCursor;
fn vertex_count(&self) -> usize {
self.vertices.len()
@@ -112,11 +120,7 @@ impl GraphTopology for AppendGraph {
}
fn adjacent_vertices(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex> {
RawIncidenceIterator {
graph: self,
incidence: self.vertices[v.0].first_incidence,
}
.map(|(v, _)| v)
self.raw_incidences(v).map(|(v, _)| v)
}
fn incident_vertices(&self, e: Self::Edge) -> (Self::Vertex, Self::Vertex) {
@@ -130,19 +134,17 @@ impl GraphTopology for AppendGraph {
}
fn incident_edges(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Edge> {
RawIncidenceIterator {
graph: self,
incidence: self.vertices[v.0].first_incidence,
}
.map(|(_, e)| e.normalize())
self.raw_incidences(v).map(|(_, e)| e.normalize())
}
fn incidences(&self, v: Self::Vertex) -> impl Iterator<Item = (Self::Vertex, Self::Edge)> {
RawIncidenceIterator {
graph: self,
self.raw_incidences(v).map(|(v, e)| (v, e.normalize()))
}
fn incidence_cursor(&self, v: Self::Vertex) -> Self::IncidenceCursor {
AppendGraphIncidenceCursor {
incidence: self.vertices[v.0].first_incidence,
}
.map(|(v, e)| (v, e.normalize()))
}
fn add_vertex(&mut self) -> Self::Vertex {
+21 -2
View File
@@ -1,7 +1,7 @@
use typed_generational_arena::{Arena, Index};
use crate::maps::{EdgeMap, VertexMap};
use crate::traits::{GraphTopology, GraphTopologyDeletion};
use crate::traits::{GraphTopology, GraphTopologyDeletion, IncidenceCursor};
type Vertex = Index<VertexIncidenceHeader, usize, usize>;
@@ -34,6 +34,19 @@ impl IncidentEdgeCursor {
}
}
#[derive(Copy, Clone)]
pub struct GraphIncidenceCursor {
incidence: Option<IncidenceSlot>,
}
impl IncidenceCursor<Graph> for GraphIncidenceCursor {
fn next(&mut self, graph: &Graph) -> Option<(Vertex, Edge)> {
graph
.step_incidence(&mut self.incidence)
.map(|(vs, e)| (graph.vertices.get_idx(vs.0).unwrap(), e))
}
}
pub struct Graph {
// TODO: Arena index and generation types could be externalized to Graph.
vertices: Arena<VertexIncidenceHeader, usize, usize>,
@@ -137,8 +150,8 @@ impl Default for Graph {
impl GraphTopology for Graph {
type Vertex = Vertex;
type Edge = Edge;
type IncidenceCursor = GraphIncidenceCursor;
fn vertex_count(&self) -> usize {
self.vertices.len()
@@ -210,6 +223,12 @@ impl GraphTopology for Graph {
.map(|(vs, e)| (self.vertices.get_idx(vs.0).unwrap(), self.normalize_edge(e)))
}
fn incidence_cursor(&self, v: Self::Vertex) -> Self::IncidenceCursor {
GraphIncidenceCursor {
incidence: self.vertices[v].first_incidence,
}
}
fn add_vertex(&mut self) -> Self::Vertex {
self.vertices.insert(VertexIncidenceHeader {
incidence_count: 0,
+6
View File
@@ -5,6 +5,7 @@ use crate::maps::{EdgeMap, VertexMap};
pub trait GraphTopology {
type Vertex: Copy + Eq;
type Edge: Copy + Eq;
type IncidenceCursor: IncidenceCursor<Self> + Copy;
fn vertex_count(&self) -> usize;
fn vertex_capacity(&self) -> usize;
@@ -20,6 +21,7 @@ pub trait GraphTopology {
fn edges(&self) -> impl Iterator<Item = Self::Edge>;
fn incident_edges(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Edge>;
fn incidences(&self, v: Self::Vertex) -> impl Iterator<Item = (Self::Vertex, Self::Edge)>;
fn incidence_cursor(&self, v: Self::Vertex) -> Self::IncidenceCursor;
fn add_vertex(&mut self) -> Self::Vertex;
fn add_edge(&mut self, v1: Self::Vertex, v2: Self::Vertex) -> Self::Edge;
}
@@ -28,3 +30,7 @@ pub trait GraphTopologyDeletion: GraphTopology {
fn delete_vertex(&mut self, v: Self::Vertex);
fn delete_edge(&mut self, e: Self::Edge);
}
pub trait IncidenceCursor<G: GraphTopology + ?Sized> {
fn next(&mut self, graph: &G) -> Option<(G::Vertex, G::Edge)>;
}