From 865de51816ed7bafe0f93b5de0f12a7e8e5d46e1 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 27 Feb 2015 19:37:59 -0800 Subject: [PATCH] dag: do a DFS for each vertex --- dag/dag.go | 38 ++++++++++++++++----------------- terraform/graph_builder_test.go | 1 - 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/dag/dag.go b/dag/dag.go index d319e84c5..b81cb2874 100644 --- a/dag/dag.go +++ b/dag/dag.go @@ -54,30 +54,28 @@ func (g *AcyclicGraph) Root() (Vertex, error) { // // Complexity: O(V(V+E)), or asymptotically O(VE) func (g *AcyclicGraph) TransitiveReduction() { - // Find the root-like objects to start a depthFirstWalk from. - frontier := make([]Vertex, 0, 5) - for _, v := range g.Vertices() { - if g.UpEdges(v).Len() == 0 { - frontier = append(frontier, v) + // For each vertex u in graph g, do a DFS starting from each vertex + // v such that the edge (u,v) exists (v is a direct descendant of u). + // + // For each v-prime reachable from v, remove the edge (u, v-prime). + + for _, u := range g.Vertices() { + uTargets := g.DownEdges(u) + vs := make([]Vertex, uTargets.Len()) + for i, vRaw := range uTargets.List() { + vs[i] = vRaw.(Vertex) } - } - // Do a DFS - g.depthFirstWalk(frontier, func(v Vertex) error { - parents := g.UpEdges(v).List() - targets := g.DownEdges(v) - - for _, rawParent := range parents { - parent := rawParent.(Vertex) - shared := g.DownEdges(parent).Intersection(targets) - for _, rawTarget := range shared.List() { - target := rawTarget.(Vertex) - g.RemoveEdge(BasicEdge(parent, target)) + g.depthFirstWalk(vs, func(v Vertex) error { + shared := uTargets.Intersection(g.DownEdges(v)) + for _, raw := range shared.List() { + vPrime := raw.(Vertex) + g.RemoveEdge(BasicEdge(u, vPrime)) } - } - return nil - }) + return nil + }) + } } // Validate validates the DAG. A DAG is valid if it has a single root diff --git a/terraform/graph_builder_test.go b/terraform/graph_builder_test.go index 882d054b9..2f072abab 100644 --- a/terraform/graph_builder_test.go +++ b/terraform/graph_builder_test.go @@ -129,7 +129,6 @@ aws_instance.db (destroy tainted) aws_instance.web (destroy tainted) aws_instance.web aws_instance.db - aws_instance.web (destroy tainted) aws_instance.web (destroy tainted) provider.aws provider.aws