diff options
author | Luke Kanies <luke@madstop.com> | 2009-04-21 17:49:05 -0500 |
---|---|---|
committer | James Turnbull <james@lovedthanlost.net> | 2009-04-22 14:53:14 +1000 |
commit | 828b1ea605786183c69a8be3bca2272b50761790 (patch) | |
tree | 53a01136bef3d799fc4895d2cfbee5859f810c58 /lib/puppet | |
parent | 9f32172e7d93f926b2ab291e68bdd0cc955ff3d2 (diff) | |
download | puppet-828b1ea605786183c69a8be3bca2272b50761790.tar.gz puppet-828b1ea605786183c69a8be3bca2272b50761790.tar.xz puppet-828b1ea605786183c69a8be3bca2272b50761790.zip |
Fixing #2182 - SimpleGraph#walk is now iterative
It was previously recursive, and was causing
significant performance problems for large, wide
graphs.
Signed-off-by: Luke Kanies <luke@madstop.com>
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/simple_graph.rb | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb index b1aaf6363..05420eab9 100644 --- a/lib/puppet/simple_graph.rb +++ b/lib/puppet/simple_graph.rb @@ -364,10 +364,21 @@ class Puppet::SimpleGraph end # Just walk the tree and pass each edge. - def walk(source, direction, &block) - adjacent(source, :direction => direction).each do |target| - yield source, target - walk(target, direction, &block) + def walk(source, direction) + # Use an iterative, breadth-first traversal of the graph. One could do + # this recursively, but Ruby's slow function calls and even slower + # recursion make the shorter, recursive algorithm cost-prohibitive. + stack = [source] + seen = Set.new + until stack.empty? + node = stack.shift + next if seen.member? node + connected = adjacent(node, :direction => direction) + connected.each do |target| + yield node, target + end + stack.concat(connected) + seen << node end end |