Ok, I've squashed the following changes into the branch.  I believe this
addresses all the issues Jesse and I found in our code review.

Regarding the downstream_from_vertex and upstream_from_vertex, I stuck with
the rewrite Jesse and I suggested because (a) there seemed to be a loose
majority in favor of it, and (b) in my speed tests it proved to be 1.5 times
faster.

diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index cd80297..6d153b4 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -33,8 +33,6 @@ class Puppet::SimpleGraph

   # Clear our graph.
   def clear
-    @in_to.each { |k,v| v.clear }
-    @out_from.each { |k,v| v.clear }
     @in_to.clear
     @out_from.clear
     @upstream_from.clear
@@ -43,11 +41,11 @@ class Puppet::SimpleGraph

   # Which resources depend upon the given resource.
   def dependencies(resource)
-   vertex?(resource) ? upstream_from_vertex(resource).keys : []
+    vertex?(resource) ? upstream_from_vertex(resource).keys : []
   end

   def dependents(resource)
-   vertex?(resource) ? downstream_from_vertex(resource).keys : []
+    vertex?(resource) ? downstream_from_vertex(resource).keys : []
   end

   # Whether our graph is directed.  Always true.  Used to produce dot
files.
@@ -158,8 +156,6 @@ class Puppet::SimpleGraph

   # Add a new vertex to the graph.
   def add_vertex(vertex)
-    @upstream_from.clear
-    @downstream_from.clear
     @in_to[vertex]    ||= {}
     @out_from[vertex] ||= {}
   end
@@ -200,14 +196,9 @@ class Puppet::SimpleGraph
     add_edge Puppet::Relationship.new(source, target, label)
   end

-  # Find a matching edge.  Note that this only finds the first edge,
-  # not all of them or whatever.
-  def edge(source, target)
-    edge?(source,target) && @out_from[source][target].first
-  end
-
-  def edge_label(source, target)
-    (e = edge(source, target)) && e.label
+  # Find all matching edges.
+  def edges_between(source, target)
+    (@out_from[source] || {})[target] || []
   end

   # Is there an edge between the two vertices?
@@ -315,11 +306,23 @@ class Puppet::SimpleGraph
   end

   def downstream_from_vertex(v)
-    @downstream_from[v] || @out_from[v].keys.inject(@downstream_from[v] =
{}) { |result,node| result.update(node=>1).update
downstream_from_vertex(node) }
+    return @downstream_from[v] if @downstream_from[v]
+    result = @downstream_from[v] = {}
+    @out_from[v].keys.each do |node|
+      result[node] = 1
+      result.update(downstream_from_vertex(node))
+    end
+    result
   end

   def upstream_from_vertex(v)
-    @upstream_from[v]   || @in_to[v].keys.inject(   @upstream_from[v]   =
{}) { |result,node| result.update(node=>1).update upstream_from_vertex(node)
}
+    return @upstream_from[v] if @upstream_from[v]
+    result = @upstream_from[v] = {}
+    @in_to[v].keys.each do |node|
+      result[node] = 1
+      result.update(upstream_from_vertex(node))
+    end
+    result
   end

   # LAK:FIXME This is just a paste of the GRATR code with slight
modifications.
@@ -363,18 +366,6 @@ class Puppet::SimpleGraph
     system('dotty', dotfile)
   end

-  # Use +dot+ to create a graphical representation of the graph.  Returns
the
-  # filename of the graphics file.
-  def write_to_graphic_file (fmt='png', dotfile='graph')
-    src = dotfile + '.dot'
-    dot = dotfile + '.' + fmt
-
-    File.open(src, 'w') {|f| f << self.to_dot << "\n"}
-
-    system( "dot -T#{fmt} #{src} -o #{dot}" )
-    dot
-  end
-
   # Produce the graph files if requested.
   def write_graph(name)
     return unless Puppet[:graph]
diff --git a/spec/unit/resource/catalog_spec.rb
b/spec/unit/resource/catalog_spec.rb
index f66d330..fbfe29f 100755
--- a/spec/unit/resource/catalog_spec.rb
+++ b/spec/unit/resource/catalog_spec.rb
@@ -374,7 +374,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
       @original.add_edge(@r1,@r2)
       @original.filter do |r|
         r == @r1
-      end.edge(@r1,@r2).should_not be
+      end.edge?(@r1,@r2).should_not be
     end
   end

@@ -933,8 +933,8 @@ describe Puppet::Resource::Catalog, "when converting to
pson" do
     @catalog.add_edge(one, two)
     @catalog.add_edge(two, three)

-    @catalog.edge(one, two  ).expects(:to_pson_data_hash).returns
"one_two_pson"
-    @catalog.edge(two, three).expects(:to_pson_data_hash).returns
"two_three_pson"
+    @catalog.edges_between(one, two
 )[0].expects(:to_pson_data_hash).returns "one_two_pson"
+    @catalog.edges_between(two,
three)[0].expects(:to_pson_data_hash).returns "two_three_pson"

     PSON.parse(@catalog.to_pson,:create_additions =>
false)['data']['edges'].sort.should == %w{one_two_pson two_three_pson}.sort
   end
diff --git a/spec/unit/simple_graph_spec.rb b/spec/unit/simple_graph_spec.rb
index c5ce50a..fa0bcb0 100755
--- a/spec/unit/simple_graph_spec.rb
+++ b/spec/unit/simple_graph_spec.rb
@@ -111,16 +111,31 @@ describe Puppet::SimpleGraph do
       @graph.edge?(:one, :two).should be_true
     end

-    it "should provide a method for retrieving an edge label" do
-      edge = Puppet::Relationship.new(:one, :two, :callback => :awesome)
-      @graph.add_edge(edge)
-      @graph.edge_label(:one, :two).should == {:callback => :awesome}
-    end
+    describe "when retrieving edges between two nodes" do
+      it "should handle the case of nodes not in the graph" do
+        @graph.edges_between(:one, :two).should == []
+      end

-    it "should provide a method for retrieving an edge" do
-      edge = Puppet::Relationship.new(:one, :two)
-      @graph.add_edge(edge)
-      @graph.edge(:one, :two).should equal(edge)
+      it "should handle the case of nodes with no edges between them" do
+        @graph.add_vertex(:one)
+        @graph.add_vertex(:two)
+        @graph.edges_between(:one, :two).should == []
+      end
+
+      it "should handle the case of nodes connected by a single edge" do
+        edge = Puppet::Relationship.new(:one, :two)
+        @graph.add_edge(edge)
+        @graph.edges_between(:one, :two).length.should == 1
+        @graph.edges_between(:one, :two)[0].should equal(edge)
+      end
+
+      it "should handle the case of nodes connected by multiple edges" do
+        edge1 = Puppet::Relationship.new(:one, :two, :callback => :foo)
+        edge2 = Puppet::Relationship.new(:one, :two, :callback => :bar)
+        @graph.add_edge(edge1)
+        @graph.add_edge(edge2)
+        Set.new(@graph.edges_between(:one, :two)).should == Set.new([edge1,
edge2])
+      end
     end

     it "should add the edge source as a vertex if it is not already" do
@@ -247,7 +262,7 @@ describe Puppet::SimpleGraph do

     it "should retain labels on edges" do
       @graph.add_edge(:one, :two, :callback => :awesome)
-      edge = @graph.reversal.edge(:two, :one)
+      edge = @graph.reversal.edges_between(:two, :one)[0]
       edge.label.should == {:callback => :awesome}
     end
   end
@@ -516,14 +531,14 @@ describe Puppet::SimpleGraph do
     it "should not add labels to edges that have none" do
       @depgraph.add_edge(@two, @three)
       splice
-      @depgraph.edge_label("c", "i").should == {}
+      @depgraph.edges_between("c", "i")[0].label.should == {}
     end

     it "should copy labels over edges that have none" do
       @depgraph.add_edge("c", @three, {:callback => :refresh})
       splice
       # And make sure the label got copied.
-      @depgraph.edge_label("c", "i").should == {:callback => :refresh}
+      @depgraph.edges_between("c", "i")[0].label.should == {:callback =>
:refresh}
     end

     it "should not replace a label with a nil label" do
@@ -531,7 +546,7 @@ describe Puppet::SimpleGraph do
       @depgraph.add_edge(@middle, @three)
       @depgraph.add_edge("c", @three, {:callback => :refresh})
       splice
-      @depgraph.edge_label("c", "i").should == {:callback => :refresh}
+      @depgraph.edges_between("c", "i")[0].label.should == {:callback =>
:refresh}
     end

     it "should copy labels to all created edges" do
@@ -541,7 +556,7 @@ describe Puppet::SimpleGraph do
       @three.each do |child|
         edge = Puppet::Relationship.new("c", child)
         @depgraph.should be_edge(edge.source, edge.target)
-        @depgraph.edge_label(edge.source, edge.target).should == {:callback
=> :refresh}
+        @depgraph.edges_between(edge.source, edge.target)[0].label.should
== {:callback => :refresh}
       end
     end
   end
diff --git a/spec/unit/util/monkey_patches_spec.rb
b/spec/unit/util/monkey_patches_spec.rb
index b0f61c8..049ed10 100644
--- a/spec/unit/util/monkey_patches_spec.rb
+++ b/spec/unit/util/monkey_patches_spec.rb
@@ -5,3 +5,29 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f|
File.exist?(f) ? require(f
 require 'puppet/util/monkey_patches'


+
+describe "yaml deserialization" do
+  it "should call yaml_initialize when deserializing objects that have that
method defined" do
+    class Puppet::TestYamlInitializeClass
+      attr_reader :foo
+
+      def yaml_initialize(tag, var)
+        var.should == {'foo' => 100}
+        instance_variables.should == []
+        @foo = 200
+      end
+    end
+
+    obj = YAML.load("--- !ruby/object:Puppet::TestYamlInitializeClass\n
 foo: 100")
+    obj.foo.should == 200
+  end
+
+  it "should not call yaml_initialize if not defined" do
+    class Puppet::TestYamlNonInitializeClass
+      attr_reader :foo
+    end
+
+    obj = YAML.load("--- !ruby/object:Puppet::TestYamlNonInitializeClass\n
 foo: 100")
+    obj.foo.should == 100
+  end
+end
diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb
index 38a9541..2a9bc07 100644
--- a/spec/unit/util/zaml_spec.rb
+++ b/spec/unit/util/zaml_spec.rb
@@ -35,29 +35,3 @@ describe "Pure ruby yaml implementation" do
     end
   }
 end
-
-describe "yaml deserialization" do
-  it "should call yaml_initialize when deserializing objects that have that
method defined" do
-    class Puppet::TestYamlInitializeClass
-      attr_reader :foo
-
-      def yaml_initialize(tag, var)
-        var.should == {'foo' => 100}
-        instance_variable_defined?(:@hook_called).should == false
-        @foo = 200
-      end
-    end
-
-    obj = YAML.load("--- !ruby/object:Puppet::TestYamlInitializeClass\n
 foo: 100")
-    obj.foo.should == 200
-  end
-
-  it "should not call yaml_initialize if not defined" do
-    class Puppet::TestYamlNonInitializeClass
-      attr_reader :foo
-    end
-
-    obj = YAML.load("--- !ruby/object:Puppet::TestYamlNonInitializeClass\n
 foo: 100")
-    obj.foo.should == 100
-  end
-end

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to