| Class | Puppet::PGraph |
| In: |
lib/puppet/pgraph.rb
|
| Parent: | Puppet::SimpleGraph |
This class subclasses a graph class in order to handle relationships among resources.
# File lib/puppet/pgraph.rb, line 17
17: def add_vertex(*args)
18: @reversal = nil
19: super
20: end
Which resources depend upon the given resource.
# File lib/puppet/pgraph.rb, line 28
28: def dependencies(resource)
29: # Cache the reversal graph, because it's somewhat expensive
30: # to create.
31: unless defined? @reversal and @reversal
32: @reversal = reversal
33: end
34: # Strangely, it's significantly faster to search a reversed
35: # tree in the :out direction than to search a normal tree
36: # in the :in direction.
37: @reversal.tree_from_vertex(resource, :out).keys
38: end
Which resources a given resource depends upon.
# File lib/puppet/pgraph.rb, line 23
23: def dependents(resource)
24: tree_from_vertex(resource).keys
25: end
Determine all of the leaf nodes below a given vertex.
# File lib/puppet/pgraph.rb, line 41
41: def leaves(vertex, direction = :out)
42: tree = tree_from_vertex(vertex, direction)
43: l = tree.keys.find_all { |c| adjacent(c, :direction => direction).empty? }
44: return l
45: end
Collect all of the edges that the passed events match. Returns an array of edges.
# File lib/puppet/pgraph.rb, line 49
49: def matching_edges(events, base = nil)
50: events.collect do |event|
51: source = base || event.source
52:
53: unless vertex?(source)
54: Puppet.warning "Got an event from invalid vertex %s" % source.ref
55: next
56: end
57: # Get all of the edges that this vertex should forward events
58: # to, which is the same thing as saying all edges directly below
59: # This vertex in the graph.
60: adjacent(source, :direction => :out, :type => :edges).find_all do |edge|
61: edge.match?(event.name)
62: end
63: end.compact.flatten
64: end
Take container information from another graph and use it to replace any container vertices with their respective leaves. This creates direct relationships where there were previously indirect relationships through the containers.
# File lib/puppet/pgraph.rb, line 70
70: def splice!(other, type)
71: # We have to get the container list via a topological sort on the
72: # configuration graph, because otherwise containers that contain
73: # other containers will add those containers back into the
74: # graph. We could get a similar affect by only setting relationships
75: # to container leaves, but that would result in many more
76: # relationships.
77: containers = other.topsort.find_all { |v| v.is_a?(type) and vertex?(v) }
78: containers.each do |container|
79: # Get the list of children from the other graph.
80: children = other.adjacent(container, :direction => :out)
81:
82: # Just remove the container if it's empty.
83: if children.empty?
84: remove_vertex!(container)
85: next
86: end
87:
88: # First create new edges for each of the :in edges
89: [:in, :out].each do |dir|
90: edges = adjacent(container, :direction => dir, :type => :edges)
91: edges.each do |edge|
92: children.each do |child|
93: if dir == :in
94: s = edge.source
95: t = child
96: else
97: s = child
98: t = edge.target
99: end
100:
101: add_edge(s, t, edge.label)
102: end
103:
104: # Now get rid of the edge, so remove_vertex! works correctly.
105: remove_edge!(edge)
106: end
107: end
108: remove_vertex!(container)
109: end
110: end
A different way of walking a tree, and a much faster way than the one that comes with GRATR.
# File lib/puppet/pgraph.rb, line 114
114: def tree_from_vertex(start, direction = :out)
115: predecessor={}
116: walk(start, direction) do |parent, child|
117: predecessor[child] = parent
118: end
119: predecessor
120: end