Initial release #1
+25
-70
@@ -18,73 +18,19 @@ pub struct VertexIncidenceHeader {
|
|||||||
first_incidence: Option<IncidenceSlot>,
|
first_incidence: Option<IncidenceSlot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
pub struct IncidenceEntry {
|
pub struct IncidenceEntry {
|
||||||
next: Option<IncidenceSlot>,
|
next: Option<IncidenceSlot>,
|
||||||
adjacent: VertexSlot,
|
adjacent: VertexSlot,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AdjacentVertexIterator<'a> {
|
|
||||||
graph: &'a Graph,
|
|
||||||
incidence: Option<IncidenceSlot>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for AdjacentVertexIterator<'a> {
|
|
||||||
type Item = Vertex;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
// TODO: Benchmark storing full Index (one read, larger entries) vs. slot + get_idx() (two reads, smaller entries).
|
|
||||||
let incidence = self.incidence?;
|
|
||||||
let i = self.graph.incidences.get_idx(incidence.0).unwrap();
|
|
||||||
let entry = &self.graph.incidences[i];
|
|
||||||
self.incidence = entry.next;
|
|
||||||
Some(self.graph.vertices.get_idx(entry.adjacent.0).unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct IncidentEdgeIterator<'a> {
|
|
||||||
graph: &'a Graph,
|
|
||||||
incidence: Option<IncidenceSlot>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for IncidentEdgeIterator<'a> {
|
|
||||||
type Item = Edge;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let current = self.incidence?;
|
|
||||||
let e = self.graph.incidences.get_idx(current.0).unwrap();
|
|
||||||
self.incidence = self.graph.incidences[e].next;
|
|
||||||
Some(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct IncidentEdgeCursor {
|
struct IncidentEdgeCursor {
|
||||||
incidence: Option<IncidenceSlot>,
|
incidence: Option<IncidenceSlot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IncidentEdgeCursor {
|
impl IncidentEdgeCursor {
|
||||||
fn next(&mut self, graph: &Graph) -> Option<Edge> {
|
fn next(&mut self, graph: &Graph) -> Option<Edge> {
|
||||||
let current = self.incidence?;
|
graph.step_incidence(&mut self.incidence).map(|(_, e)| e)
|
||||||
let e = graph.incidences.get_idx(current.0).unwrap();
|
|
||||||
self.incidence = graph.incidences[e].next;
|
|
||||||
Some(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct IncidenceIterator<'a> {
|
|
||||||
graph: &'a Graph,
|
|
||||||
incidence: Option<IncidenceSlot>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for IncidenceIterator<'a> {
|
|
||||||
type Item = (Vertex, Edge);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let current = self.incidence?;
|
|
||||||
let e = self.graph.incidences.get_idx(current.0).unwrap();
|
|
||||||
let entry = &self.graph.incidences[e];
|
|
||||||
self.incidence = entry.next;
|
|
||||||
let v = self.graph.vertices.get_idx(entry.adjacent.0).unwrap();
|
|
||||||
Some((v, self.graph.normalize_edge(e)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,16 +97,27 @@ impl Graph {
|
|||||||
if first.0 == e.arr_idx() {
|
if first.0 == e.arr_idx() {
|
||||||
vertex_header.first_incidence = next;
|
vertex_header.first_incidence = next;
|
||||||
} else {
|
} else {
|
||||||
let previous = IncidentEdgeIterator {
|
let graph: &Graph = self;
|
||||||
graph: self,
|
let mut incidence = self.vertices[source_vertex].first_incidence;
|
||||||
incidence: self.vertices[source_vertex].first_incidence,
|
let (_, previous) = std::iter::from_fn(move || graph.step_incidence(&mut incidence))
|
||||||
}
|
.find(|(_, f)| {
|
||||||
.find(|f| self.incidences[*f].next.is_some_and(|i| i.0 == e.arr_idx()))
|
graph.incidences[*f]
|
||||||
.expect("cannot find previous incidence, corrupt internal data state");
|
.next
|
||||||
|
.is_some_and(|i| i.0 == e.arr_idx())
|
||||||
|
})
|
||||||
|
.expect("cannot find previous incidence, corrupt internal data state");
|
||||||
self.incidences[previous].next = next;
|
self.incidences[previous].next = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn step_incidence(&self, incidence: &mut Option<IncidenceSlot>) -> Option<(VertexSlot, Edge)> {
|
||||||
|
let current = (*incidence)?;
|
||||||
|
let e = self.incidences.get_idx(current.0).unwrap();
|
||||||
|
let entry = self.incidences[e];
|
||||||
|
*incidence = entry.next;
|
||||||
|
Some((entry.adjacent, e))
|
||||||
|
}
|
||||||
|
|
||||||
fn normalize_edge(&self, e: Edge) -> Edge {
|
fn normalize_edge(&self, e: Edge) -> Edge {
|
||||||
self.incidences.get_idx(e.arr_idx() & !1).unwrap()
|
self.incidences.get_idx(e.arr_idx() & !1).unwrap()
|
||||||
}
|
}
|
||||||
@@ -214,10 +171,9 @@ impl GraphTopology for Graph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn adjacent_vertices(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex> {
|
fn adjacent_vertices(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex> {
|
||||||
AdjacentVertexIterator {
|
let mut incidence = self.vertices[v].first_incidence;
|
||||||
graph: self,
|
std::iter::from_fn(move || self.step_incidence(&mut incidence))
|
||||||
incidence: self.vertices[v].first_incidence,
|
.map(|(vs, _)| self.vertices.get_idx(vs.0).unwrap())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edges(&self) -> impl Iterator<Item = Self::Edge> {
|
fn edges(&self) -> impl Iterator<Item = Self::Edge> {
|
||||||
@@ -228,10 +184,9 @@ impl GraphTopology for Graph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn incidences(&self, v: Self::Vertex) -> impl Iterator<Item = (Self::Vertex, Self::Edge)> {
|
fn incidences(&self, v: Self::Vertex) -> impl Iterator<Item = (Self::Vertex, Self::Edge)> {
|
||||||
IncidenceIterator {
|
let mut incidence = self.vertices[v].first_incidence;
|
||||||
graph: self,
|
std::iter::from_fn(move || self.step_incidence(&mut incidence))
|
||||||
incidence: self.vertices[v].first_incidence,
|
.map(|(vs, e)| (self.vertices.get_idx(vs.0).unwrap(), self.normalize_edge(e)))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_vertex(&mut self) -> Self::Vertex {
|
fn add_vertex(&mut self) -> Self::Vertex {
|
||||||
|
|||||||
Reference in New Issue
Block a user