With recursive file resources, many change events can be generated.
The method used to find the good ones is pretty inefficient allocating
arrays and/or appending to arrays which is a slow operation.

This patch rewrite the code to never append or allocate an array if
there is no matching edge, or to limit those operations to their strict
minimum needed in the other cases.

Results for matching 1100 events:
 * old code: 22s
 * new code:  4s

This patch also helps on the memory consumption side since the GC has
almost no work to perform.

Signed-off-by: Brice Figureau <[email protected]>
---
 lib/puppet/simple_graph.rb |   20 ++++++++++++++++----
 lib/puppet/transaction.rb  |   18 ++++++++++--------
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index 5e8f5cd..591c75d 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -64,6 +64,14 @@ class Puppet::SimpleGraph
             end
         end
 
+        def each_out_edges
+            @adjacencies[:out].values.each do |edges|
+                edges.each do |edge|
+                    yield edge
+                end
+            end
+        end
+
         # The other vertex in the edge.
         def other_vertex(direction, edge)
             case direction
@@ -146,7 +154,7 @@ class Puppet::SimpleGraph
     # Collect all of the edges that the passed events match.  Returns
     # an array of edges.
     def matching_edges(events, base = nil)
-        events.collect do |event|
+        events.inject([]) do |matching,event|
             source = base || event.source
 
             unless vertex?(source)
@@ -156,10 +164,14 @@ class Puppet::SimpleGraph
             # Get all of the edges that this vertex should forward events
             # to, which is the same thing as saying all edges directly below
             # This vertex in the graph.
-            adjacent(source, :direction => :out, :type => :edges).find_all do 
|edge|
-                edge.match?(event.name)
+
+            if wrapper = @vertices[source]
+                wrapper.each_out_edges do |edge|
+                    matching << edge if edge.match?(event.name)
+                end
             end
-        end.compact.flatten
+            matching
+        end
     end
 
     # Return a reversed version of this graph.
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index e132b72..3d8e38e 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -215,15 +215,17 @@ class Transaction
         # Collect the targets of any subscriptions to those events.  We pass
         # the parent resource in so it will override the source in the events,
         # since eval_generated children can't have direct relationships.
-        relationship_graph.matching_edges(events, resource).each do |orig_edge|
-            # We have to dup the label here, else we modify the original edge 
label,
-            # which affects whether a given event will match on the next run, 
which is,
-            # of course, bad.
-            edge = orig_edge.class.new(orig_edge.source, orig_edge.target, 
orig_edge.label)
-            edge.event = events.collect { |e| e.name }
-            set_trigger(edge)
+        Puppet::Util.benchmark(:debug, "Time for triggering events to edges") 
do
+            relationship_graph.matching_edges(events, resource).each do 
|orig_edge|
+                # We have to dup the label here, else we modify the original 
edge label,
+                # which affects whether a given event will match on the next 
run, which is,
+                # of course, bad.
+                puts "new edge: #{orig_edge.target} <- #{orig_edge.source} 
#{orig_edge.label}"
+                edge = orig_edge.class.new(orig_edge.source, orig_edge.target, 
orig_edge.label)
+                edge.event = events.collect { |e| e.name }
+                set_trigger(edge)
+            end
         end
-
         # And return the events for collection
         events
     end
-- 
1.6.6.1

-- 
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