1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 A graph module for use in dataflow, region resolution, and elsewhere.
17 You customize the graph by specifying a "node data" type `N` and an
18 "edge data" type `E`. You can then later gain access (mutable or
19 immutable) to these "user-data" bits. Currently, you can only add
20 nodes or edges to the graph. You cannot remove or modify them once
21 added. This could be changed if we have a need.
23 # Implementation details
25 The main tricky thing about this code is the way that edges are
26 stored. The edges are stored in a central array, but they are also
27 threaded onto two linked lists for each node, one for incoming edges
28 and one for outgoing edges. Note that every edge is a member of some
29 incoming list and some outgoing list. Basically you can load the
30 first index of the linked list from the node data structures (the
31 field `first_edge`) and then, for each edge, load the next index from
32 the field `next_edge`). Each of those fields is an array that should
33 be indexed by the direction (see the type `Direction`).
37 #![allow(dead_code)] // still WIP
41 pub struct Graph<N,E> {
47 first_edge: [EdgeIndex, ..2], // see module comment
52 next_edge: [EdgeIndex, ..2], // see module comment
58 #[deriving(Clone, PartialEq, Show)]
59 pub struct NodeIndex(pub uint);
60 pub static InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
62 #[deriving(PartialEq)]
63 pub struct EdgeIndex(pub uint);
64 pub static InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
66 // Use a private field here to guarantee no more instances are created:
67 pub struct Direction { repr: uint }
68 pub static Outgoing: Direction = Direction { repr: 0 };
69 pub static Incoming: Direction = Direction { repr: 1 };
72 fn get(&self) -> uint { let NodeIndex(v) = *self; v }
73 /// Returns unique id (unique with respect to the graph holding associated node).
74 pub fn node_id(&self) -> uint { self.get() }
78 fn get(&self) -> uint { let EdgeIndex(v) = *self; v }
79 /// Returns unique id (unique with respect to the graph holding associated edge).
80 pub fn edge_id(&self) -> uint { self.get() }
83 impl<N,E> Graph<N,E> {
84 pub fn new() -> Graph<N,E> {
91 pub fn with_capacity(num_nodes: uint,
92 num_edges: uint) -> Graph<N,E> {
94 nodes: Vec::with_capacity(num_nodes),
95 edges: Vec::with_capacity(num_edges),
99 ///////////////////////////////////////////////////////////////////////////
103 pub fn all_nodes<'a>(&'a self) -> &'a [Node<N>] {
104 let nodes: &'a [Node<N>] = self.nodes.as_slice();
109 pub fn all_edges<'a>(&'a self) -> &'a [Edge<E>] {
110 let edges: &'a [Edge<E>] = self.edges.as_slice();
114 ///////////////////////////////////////////////////////////////////////////
117 pub fn next_node_index(&self) -> NodeIndex {
118 NodeIndex(self.nodes.len())
121 pub fn add_node(&mut self, data: N) -> NodeIndex {
122 let idx = self.next_node_index();
123 self.nodes.push(Node {
124 first_edge: [InvalidEdgeIndex, InvalidEdgeIndex],
130 pub fn mut_node_data<'a>(&'a mut self, idx: NodeIndex) -> &'a mut N {
131 &mut self.nodes.get_mut(idx.get()).data
134 pub fn node_data<'a>(&'a self, idx: NodeIndex) -> &'a N {
135 &self.nodes.get(idx.get()).data
138 pub fn node<'a>(&'a self, idx: NodeIndex) -> &'a Node<N> {
139 self.nodes.get(idx.get())
142 ///////////////////////////////////////////////////////////////////////////
143 // Edge construction and queries
145 pub fn next_edge_index(&self) -> EdgeIndex {
146 EdgeIndex(self.edges.len())
149 pub fn add_edge(&mut self,
152 data: E) -> EdgeIndex {
153 let idx = self.next_edge_index();
155 // read current first of the list of edges from each node
156 let source_first = self.nodes.get(source.get())
157 .first_edge[Outgoing.repr];
158 let target_first = self.nodes.get(target.get())
159 .first_edge[Incoming.repr];
161 // create the new edge, with the previous firsts from each node
162 // as the next pointers
163 self.edges.push(Edge {
164 next_edge: [source_first, target_first],
170 // adjust the firsts for each node target be the next object.
171 self.nodes.get_mut(source.get()).first_edge[Outgoing.repr] = idx;
172 self.nodes.get_mut(target.get()).first_edge[Incoming.repr] = idx;
177 pub fn mut_edge_data<'a>(&'a mut self, idx: EdgeIndex) -> &'a mut E {
178 &mut self.edges.get_mut(idx.get()).data
181 pub fn edge_data<'a>(&'a self, idx: EdgeIndex) -> &'a E {
182 &self.edges.get(idx.get()).data
185 pub fn edge<'a>(&'a self, idx: EdgeIndex) -> &'a Edge<E> {
186 self.edges.get(idx.get())
189 pub fn first_adjacent(&self, node: NodeIndex, dir: Direction) -> EdgeIndex {
190 //! Accesses the index of the first edge adjacent to `node`.
191 //! This is useful if you wish to modify the graph while walking
192 //! the linked list of edges.
194 self.nodes.get(node.get()).first_edge[dir.repr]
197 pub fn next_adjacent(&self, edge: EdgeIndex, dir: Direction) -> EdgeIndex {
198 //! Accesses the next edge in a given direction.
199 //! This is useful if you wish to modify the graph while walking
200 //! the linked list of edges.
202 self.edges.get(edge.get()).next_edge[dir.repr]
205 ///////////////////////////////////////////////////////////////////////////
206 // Iterating over nodes, edges
208 pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool {
209 //! Iterates over all edges defined in the graph.
210 self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node))
213 pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool {
214 //! Iterates over all edges defined in the graph
215 self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge))
218 pub fn each_outgoing_edge<'a>(&'a self,
220 f: |EdgeIndex, &'a Edge<E>| -> bool)
222 //! Iterates over all outgoing edges from the node `from`
224 self.each_adjacent_edge(source, Outgoing, f)
227 pub fn each_incoming_edge<'a>(&'a self,
229 f: |EdgeIndex, &'a Edge<E>| -> bool)
231 //! Iterates over all incoming edges to the node `target`
233 self.each_adjacent_edge(target, Incoming, f)
236 pub fn each_adjacent_edge<'a>(&'a self,
239 f: |EdgeIndex, &'a Edge<E>| -> bool)
241 //! Iterates over all edges adjacent to the node `node`
242 //! in the direction `dir` (either `Outgoing` or `Incoming)
244 let mut edge_idx = self.first_adjacent(node, dir);
245 while edge_idx != InvalidEdgeIndex {
246 let edge = self.edges.get(edge_idx.get());
247 if !f(edge_idx, edge) {
250 edge_idx = edge.next_edge[dir.repr];
255 ///////////////////////////////////////////////////////////////////////////
256 // Fixed-point iteration
258 // A common use for graphs in our compiler is to perform
259 // fixed-point iteration. In this case, each edge represents a
260 // constraint, and the nodes themselves are associated with
261 // variables or other bitsets. This method facilitates such a
264 pub fn iterate_until_fixed_point<'a>(&'a self,
265 op: |iter_index: uint,
266 edge_index: EdgeIndex,
269 let mut iteration = 0;
270 let mut changed = true;
274 for (i, edge) in self.edges.iter().enumerate() {
275 changed |= op(iteration, EdgeIndex(i), edge);
281 pub fn each_edge_index(max_edge_index: EdgeIndex, f: |EdgeIndex| -> bool) {
283 let n = max_edge_index.get();
285 if !f(EdgeIndex(i)) {
293 pub fn source(&self) -> NodeIndex {
297 pub fn target(&self) -> NodeIndex {
304 use middle::graph::*;
306 type TestNode = Node<&'static str>;
307 type TestEdge = Edge<&'static str>;
308 type TestGraph = Graph<&'static str, &'static str>;
310 fn create_graph() -> TestGraph {
311 let mut graph = Graph::new();
313 // Create a simple graph
320 let a = graph.add_node("A");
321 let b = graph.add_node("B");
322 let c = graph.add_node("C");
323 let d = graph.add_node("D");
324 let e = graph.add_node("E");
325 let f = graph.add_node("F");
327 graph.add_edge(a, b, "AB");
328 graph.add_edge(b, c, "BC");
329 graph.add_edge(b, d, "BD");
330 graph.add_edge(d, e, "DE");
331 graph.add_edge(e, c, "EC");
332 graph.add_edge(f, b, "FB");
339 let graph = create_graph();
340 let expected = ["A", "B", "C", "D", "E", "F"];
341 graph.each_node(|idx, node| {
342 assert_eq!(&expected[idx.get()], graph.node_data(idx));
343 assert_eq!(expected[idx.get()], node.data);
350 let graph = create_graph();
351 let expected = ["AB", "BC", "BD", "DE", "EC", "FB"];
352 graph.each_edge(|idx, edge| {
353 assert_eq!(&expected[idx.get()], graph.edge_data(idx));
354 assert_eq!(expected[idx.get()], edge.data);
359 fn test_adjacent_edges<N:PartialEq,E:PartialEq>(graph: &Graph<N,E>,
360 start_index: NodeIndex,
362 expected_incoming: &[(E,N)],
363 expected_outgoing: &[(E,N)]) {
364 assert!(graph.node_data(start_index) == &start_data);
367 graph.each_incoming_edge(start_index, |edge_index, edge| {
368 assert!(graph.edge_data(edge_index) == &edge.data);
369 assert!(counter < expected_incoming.len());
370 debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}",
371 counter, expected_incoming[counter], edge_index, edge);
372 match expected_incoming[counter] {
374 assert!(e == &edge.data);
375 assert!(n == graph.node_data(edge.source));
376 assert!(start_index == edge.target);
382 assert_eq!(counter, expected_incoming.len());
385 graph.each_outgoing_edge(start_index, |edge_index, edge| {
386 assert!(graph.edge_data(edge_index) == &edge.data);
387 assert!(counter < expected_outgoing.len());
388 debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}",
389 counter, expected_outgoing[counter], edge_index, edge);
390 match expected_outgoing[counter] {
392 assert!(e == &edge.data);
393 assert!(start_index == edge.source);
394 assert!(n == graph.node_data(edge.target));
400 assert_eq!(counter, expected_outgoing.len());
404 fn each_adjacent_from_a() {
405 let graph = create_graph();
406 test_adjacent_edges(&graph, NodeIndex(0), "A",
412 fn each_adjacent_from_b() {
413 let graph = create_graph();
414 test_adjacent_edges(&graph, NodeIndex(1), "B",
415 [("FB", "F"), ("AB", "A"),],
416 [("BD", "D"), ("BC", "C"),]);
420 fn each_adjacent_from_c() {
421 let graph = create_graph();
422 test_adjacent_edges(&graph, NodeIndex(2), "C",
423 [("EC", "E"), ("BC", "B")],
428 fn each_adjacent_from_d() {
429 let graph = create_graph();
430 test_adjacent_edges(&graph, NodeIndex(3), "D",