Skip to content

Commit

Permalink
graph_algos: add vertex_labels, edge_labels iterators. make mutable v…
Browse files Browse the repository at this point in the history
…ersions match naming
  • Loading branch information
m4b committed Jul 7, 2017
1 parent 66f0ad5 commit 9eb8981
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 52 deletions.
8 changes: 4 additions & 4 deletions core/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ use uuid::Uuid;

/// An iterator over every BasicBlock in a Function
pub struct BasicBlockIterator<'a> {
iter: VertexLabelIterator<'a, ControlFlowTarget, Guard, AdjacencyList<ControlFlowTarget, Guard>>
iter: VertexLabelIterator<'a, ControlFlowRef, ControlFlowTarget>
}

impl<'a> BasicBlockIterator<'a> {
/// Create a new statement iterator from `mnemonics`
pub fn new(cfg: &'a ControlFlowGraph) -> Self {
BasicBlockIterator {
iter: cfg.into_iter(),
iter: cfg.vertex_labels(),
}
}
}
Expand Down Expand Up @@ -128,7 +128,7 @@ impl Function {
let mut size = 0;
let (mut mnemonics, mut by_source, mut by_destination) = Self::index_cflow_graph(&mut cflow_graph, start);

let mut todo = cflow_graph.into_iter().filter_map(|lb| {
let mut todo = cflow_graph.vertex_labels().filter_map(|lb| {
if let &ControlFlowTarget::Unresolved(Rvalue::Constant{ value,.. }) = lb {
Some(value)
} else {
Expand Down Expand Up @@ -305,7 +305,7 @@ impl Function {

by_destination.insert(entry, vec![(Rvalue::Undefined, Guard::always())]);

for cft in g {
for cft in g.vertex_labels() {
match cft {
&ControlFlowTarget::Resolved(ref bb) => {
let mut prev_mne = None;
Expand Down
49 changes: 18 additions & 31 deletions graph-algos/src/adjacency_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,40 +129,19 @@ impl<'a, V, E> AdjacencyGraph<'a, V, E> for AdjacencyList<V, E> {
}
}

pub struct VertexLabelIterator<'a, V: 'a, E: 'a, G: VertexListGraph<'a, V, E> + 'a> where G::Vertex: 'a {
cfg: &'a G,
iter: G::Vertices,
}

impl<'a, V: 'a, E, G: VertexListGraph<'a, V, E> + 'a> VertexLabelIterator<'a, V, E, G> {
/// Create a new vertex label iterator from this VertexListGraph
pub fn new(cfg: &'a G) -> Self {
VertexLabelIterator { cfg, iter: cfg.vertices() }
}
}

impl<'a, V: 'a, E, G: VertexListGraph<'a, V, E> + 'a> Iterator for VertexLabelIterator<'a, V, E, G> {
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
Some(vx) => {
self.cfg.vertex_label(vx)
},
None => None
}
}
}
pub type VertexLabelIterator<'a, K, V> = std::collections::hash_map::Values<'a, K, V>;

impl<'a, V: 'a, E> IntoIterator for &'a AdjacencyList<V, E> {
type Item = &'a V;
type IntoIter = VertexLabelIterator<'a, V, E, AdjacencyList<V, E>>;
type IntoIter = <AdjacencyList<V, E> as VertexListGraph<'a, V, E>>::VertexLabels;
fn into_iter(self) -> Self::IntoIter {
VertexLabelIterator::new(self)
self.vertex_labels()
}
}

impl<'a, V: 'a, E> VertexListGraph<'a, V, E> for AdjacencyList<V, E> {
type Vertices = std::iter::Map<std::collections::hash_map::Keys<'a, Self::Vertex, V>, fn(&Self::Vertex) -> Self::Vertex>;
type VertexLabels = std::collections::hash_map::Values<'a, Self::Vertex, V>;

fn num_vertices(&self) -> usize {
return self.vertex_labels.len();
Expand All @@ -171,10 +150,15 @@ impl<'a, V: 'a, E> VertexListGraph<'a, V, E> for AdjacencyList<V, E> {
fn vertices(&'a self) -> Self::Vertices {
return self.vertex_labels.keys().map(std::clone::Clone::clone);
}

fn vertex_labels(&'a self) -> Self::VertexLabels {
self.vertex_labels.values()
}
}

impl<'a, V, E: 'a> EdgeListGraph<'a, V, E> for AdjacencyList<V, E> {
type Edges = std::iter::Map<std::collections::hash_map::Keys<'a, Self::Edge, E>, fn(&Self::Edge) -> Self::Edge>;
type EdgeLabels = std::collections::hash_map::Values<'a, Self::Edge, E>;

fn num_edges(&self) -> usize {
return self.edge_labels.len();
Expand All @@ -183,8 +167,11 @@ impl<'a, V, E: 'a> EdgeListGraph<'a, V, E> for AdjacencyList<V, E> {
fn edges(&'a self) -> Self::Edges {
return self.edge_labels.keys().map(std::clone::Clone::clone);
}
}

fn edge_labels(&'a self) -> Self::EdgeLabels {
self.edge_labels.values()
}
}

impl<'a, V, E> AdjacencyMatrixGraph<'a, V, E> for AdjacencyList<V, E> {
fn edge(&'a self, from: Self::Vertex, to: Self::Vertex) -> Option<Self::Edge> {
Expand All @@ -196,8 +183,8 @@ impl<'a, V, E> AdjacencyMatrixGraph<'a, V, E> for AdjacencyList<V, E> {
}

impl<'a, V: 'a, E: 'a> MutableGraph<'a, V, E> for AdjacencyList<V, E> {
type LabelsMut = std::collections::hash_map::ValuesMut<'a, Self::Vertex, V>;
type EdgesMut = std::collections::hash_map::ValuesMut<'a, Self::Edge, E>;
type VertexLabelsMut = std::collections::hash_map::ValuesMut<'a, Self::Vertex, V>;
type EdgeLabelsMut = std::collections::hash_map::ValuesMut<'a, Self::Edge, E>;
fn add_vertex(&mut self, lb: V) -> Self::Vertex {
let n = self.next_vertex;

Expand Down Expand Up @@ -311,10 +298,10 @@ impl<'a, V: 'a, E: 'a> MutableGraph<'a, V, E> for AdjacencyList<V, E> {
fn edge_label_mut(&mut self, n: Self::Edge) -> Option<&mut E> {
return self.edge_labels.get_mut(&n);
}
fn labels_mut(&'a mut self) -> Self::LabelsMut {
fn vertex_labels_mut(&'a mut self) -> Self::VertexLabelsMut {
self.vertex_labels.values_mut()
}
fn edges_mut(&'a mut self) -> Self::EdgesMut {
fn edge_labels_mut(&'a mut self) -> Self::EdgeLabelsMut {
self.edge_labels.values_mut()
}
}
Expand Down Expand Up @@ -684,7 +671,7 @@ mod test {

assert!(e12.is_some() && e23.is_some() && e21.is_some() && e14.is_some());

let mut labels_iter: VertexLabelIterator<isize, String, _> = g.into_iter();
let mut labels_iter = g.into_iter();
assert!(labels_iter.next().is_some());
assert!(labels_iter.next().is_some());
assert!(labels_iter.next().is_some());
Expand Down
4 changes: 4 additions & 0 deletions graph-algos/src/adjacency_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ impl<'a, V, E> AdjacencyGraph<'a, V, E> for AdjacencyMatrix<'a, V, E> {

impl<'a, V, E> VertexListGraph<'a, V, E> for AdjacencyMatrix<'a, V, E> {
type Vertices = Range<usize>;
type VertexLabels = ::std::slice::Iter<'a, V>;

fn vertices(&'a self) -> Self::Vertices {
return 0..self.vertex_labels.len();
Expand All @@ -184,6 +185,9 @@ impl<'a, V, E> VertexListGraph<'a, V, E> for AdjacencyMatrix<'a, V, E> {
fn num_vertices(&self) -> usize {
return self.vertex_labels.len();
}
fn vertex_labels(&self) -> Self::VertexLabels {
self.vertex_labels.iter()
}
}

#[cfg(test)]
Expand Down
8 changes: 4 additions & 4 deletions graph-algos/src/dominator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::collections::HashMap;
use std::iter::FromIterator;
use traits::{BidirectionalGraph, Graph, VertexListGraph};

pub fn dominators<'a, V, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
pub fn dominators<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
start: G::Vertex,
graph: &'a G,
) -> HashMap<G::Vertex, Vec<G::Vertex>> {
Expand Down Expand Up @@ -78,7 +78,7 @@ pub fn dominators<'a, V, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V,
}

/// Cooper, Harvey, Kennedy: "A Simple, Fast Dominance Algorithm"
pub fn dominance_frontiers<'a, V, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>
pub fn dominance_frontiers<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>
(
idom: &HashMap<G::Vertex, G::Vertex>,
graph: &'a G,
Expand Down Expand Up @@ -114,13 +114,13 @@ pub fn dominance_frontiers<'a, V, E, G: 'a + Graph<'a, V, E> + BidirectionalGrap
}

/// Cooper, Harvey, Kennedy: "A Simple, Fast Dominance Algorithm"
pub fn immediate_dominator<'a, V, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
pub fn immediate_dominator<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
start: G::Vertex,
graph: &'a G,
) -> HashMap<G::Vertex, G::Vertex> {
let postorder = TreeIterator::new(start, TraversalOrder::Postorder, graph).collect::<Vec<_>>();
let po_idx = HashMap::<G::Vertex, usize>::from_iter(postorder.iter().enumerate().map(|(a, b)| (b.clone(), a)));
fn intersect<'a, V, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
fn intersect<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
b1: G::Vertex,
b2: G::Vertex,
po_idx: &HashMap<G::Vertex, usize>,
Expand Down
6 changes: 3 additions & 3 deletions graph-algos/src/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ pub enum HierarchicalOrdering<T: Clone> {
}

/// Bourdoncle: "Efficient chaotic iteration strategies with widenings"
pub fn weak_topo_order<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
pub fn weak_topo_order<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
root: G::Vertex,
graph: &'a G,
) -> HierarchicalOrdering<G::Vertex>
where
G::Vertex: Debug,
{
fn visit<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
fn visit<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
vx: G::Vertex,
graph: &'a G,
ret: &mut Vec<Box<HierarchicalOrdering<G::Vertex>>>,
Expand Down Expand Up @@ -88,7 +88,7 @@ where
head
}

fn component<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
fn component<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
vx: G::Vertex,
graph: &'a G,
stack: &mut Vec<G::Vertex>,
Expand Down
8 changes: 4 additions & 4 deletions graph-algos/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub enum TraversalOrder {
Postorder,
}

pub struct TreeIterator<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>> {
pub struct TreeIterator<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>> {
order: TraversalOrder,
stack: Vec<G::Vertex>,
seen: HashSet<G::Vertex>,
Expand Down Expand Up @@ -113,7 +113,7 @@ impl<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGr
}
}

pub fn is_connected<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(graph: &'a G)
pub fn is_connected<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + BidirectionalGraph<'a, V, E> + VertexListGraph<'a, V, E>>(graph: &'a G)
-> bool {
let mut seen = HashSet::<G::Vertex>::new();

Expand Down Expand Up @@ -160,7 +160,7 @@ pub enum VertexColor {
Black,
}

pub fn depth_first_visit<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
pub fn depth_first_visit<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
vertex_visitor: &mut FnMut(&G::Vertex, VertexEvent),
edge_visitor: &mut FnMut(&G::Edge, EdgeKind),
start: &G::Vertex,
Expand All @@ -172,7 +172,7 @@ pub fn depth_first_visit<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a,
color.insert(v, VertexColor::White);
}

fn visit<'a, V, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
fn visit<'a, V: 'a, E, G: 'a + Graph<'a, V, E> + IncidenceGraph<'a, V, E> + VertexListGraph<'a, V, E>>(
vx: &G::Vertex,
color: &mut HashMap<G::Vertex, VertexColor>,
vertex_visitor: &mut FnMut(&G::Vertex, VertexEvent),
Expand Down
16 changes: 10 additions & 6 deletions graph-algos/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,32 +46,36 @@ pub trait AdjacencyGraph<'a, V, E>: Graph<'a, V, E> {
fn adjacent_vertices(&'a self, Self::Vertex) -> Self::Adjacency;
}

pub trait VertexListGraph<'a, V, E>
pub trait VertexListGraph<'a, V: 'a, E>
: IncidenceGraph<'a, V, E> + AdjacencyGraph<'a, V, E> {
type Vertices: Iterator<Item = Self::Vertex>;
type VertexLabels: Iterator<Item = &'a V>;
fn vertices(&'a self) -> Self::Vertices;
fn num_vertices(&self) -> usize;
fn vertex_labels(&'a self) -> Self::VertexLabels;
}

pub trait EdgeListGraph<'a, V, E>: Graph<'a, V, E> {
pub trait EdgeListGraph<'a, V, E: 'a>: Graph<'a, V, E> {
type Edges: Iterator<Item = Self::Edge>;
type EdgeLabels: Iterator<Item = &'a E>;
fn num_edges(&self) -> usize;
fn edges(&'a self) -> Self::Edges;
fn edge_labels(&'a self) -> Self::EdgeLabels;
}

pub trait AdjacencyMatrixGraph<'a, V, E>: Graph<'a, V, E> {
fn edge(&'a self, Self::Vertex, Self::Vertex) -> Option<Self::Edge>;
}

pub trait MutableGraph<'a, V: 'a, E: 'a>: Graph<'a, V, E> {
type LabelsMut: Iterator<Item = &'a mut V>;
type EdgesMut: Iterator<Item = &'a mut E>;
type VertexLabelsMut: Iterator<Item = &'a mut V>;
type EdgeLabelsMut: Iterator<Item = &'a mut E>;
fn add_vertex(&mut self, V) -> Self::Vertex;
fn add_edge(&mut self, E, Self::Vertex, Self::Vertex) -> Option<Self::Edge>;
fn remove_vertex<'t>(&'t mut self, Self::Vertex) -> Option<V>;
fn remove_edge(&mut self, Self::Edge) -> Option<E>;
fn edge_label_mut(&mut self, Self::Edge) -> Option<&mut E>;
fn edge_labels_mut(&'a mut self) -> Self::EdgeLabelsMut;
fn vertex_label_mut(&mut self, Self::Vertex) -> Option<&mut V>;
fn labels_mut(&'a mut self) -> Self::LabelsMut;
fn edges_mut(&'a mut self) -> Self::EdgesMut;
fn vertex_labels_mut(&'a mut self) -> Self::VertexLabelsMut;
}

0 comments on commit 9eb8981

Please sign in to comment.