Class: Bundler::Molinillo::DependencyGraph
- Inherits:
-
Object
- Object
- Bundler::Molinillo::DependencyGraph
- Includes:
- Enumerable, TSort
- Defined in:
- lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb
Overview
A directed acyclic graph that is tuned to hold named dependencies
Defined Under Namespace
Instance Attribute Summary collapse
-
#vertices ⇒ {String => Vertex}
readonly
The vertices of the dependency graph, keyed by Vertex#name.
Class Method Summary collapse
-
.tsort(vertices) ⇒ Array<Vertex>
Topologically sorts the given vertices.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Whether the two dependency graphs are equal, determined by a recursive traversal of each #root_vertices and its Vertex#successors.
- #add_child_vertex(name, payload, parent_names, requirement) ⇒ void
-
#add_edge(origin, destination, requirement) ⇒ Edge
Adds a new Edge to the dependency graph.
-
#add_vertex(name, payload, root = false) ⇒ Vertex
Adds a vertex with the given name, or updates the existing one.
-
#detach_vertex_named(name) ⇒ void
Detaches the #vertex_named ‘name` Vertex from the graph, recursively removing any non-root vertices that were orphaned in the process.
-
#each ⇒ Array<Vertex>
(also: #tsort_each_node)
Enumerates through the vertices of the graph.
-
#initialize ⇒ DependencyGraph
constructor
Initializes an empty dependency graph.
-
#initialize_copy(other) ⇒ Object
Initializes a copy of a DependencyGraph, ensuring that all #vertices are properly copied.
-
#inspect ⇒ String
A string suitable for debugging.
-
#root_vertex_named(name) ⇒ Vertex?
The root vertex with the given name.
-
#vertex_named(name) ⇒ Vertex?
The vertex with the given name.
Constructor Details
#initialize ⇒ DependencyGraph
Initializes an empty dependency graph
48 49 50 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 48 def initialize @vertices = {} end |
Instance Attribute Details
#vertices ⇒ {String => Vertex} (readonly)
Returns the vertices of the dependency graph, keyed by Bundler::Molinillo::DependencyGraph::Vertex#name.
45 46 47 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 45 def vertices @vertices end |
Class Method Details
.tsort(vertices) ⇒ Array<Vertex>
Topologically sorts the given vertices.
30 31 32 33 34 35 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 30 def self.tsort(vertices) TSort.tsort( lambda { |b| vertices.each(&b) }, lambda { |v, &b| (v.successors & vertices).each(&b) } ) end |
Instance Method Details
#==(other) ⇒ Boolean
Returns whether the two dependency graphs are equal, determined by a recursive traversal of each #root_vertices and its Bundler::Molinillo::DependencyGraph::Vertex#successors.
81 82 83 84 85 86 87 88 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 81 def ==(other) return false unless other vertices.each do |name, vertex| other_vertex = other.vertex_named(name) return false unless other_vertex return false unless other_vertex.successors.map(&:name).to_set == vertex.successors.map(&:name).to_set end end |
#add_child_vertex(name, payload, parent_names, requirement) ⇒ void
This method returns an undefined value.
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 95 def add_child_vertex(name, payload, parent_names, requirement) vertex = add_vertex(name, payload) parent_names.each do |parent_name| unless parent_name vertex.root = true next end parent_node = vertex_named(parent_name) add_edge(parent_node, vertex, requirement) end vertex end |
#add_edge(origin, destination, requirement) ⇒ Edge
Adds a new Edge to the dependency graph
154 155 156 157 158 159 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 154 def add_edge(origin, destination, requirement) if destination.path_to?(origin) raise CircularDependencyError.new([origin, destination]) end add_edge_no_circular(origin, destination, requirement) end |
#add_vertex(name, payload, root = false) ⇒ Vertex
Adds a vertex with the given name, or updates the existing one.
112 113 114 115 116 117 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 112 def add_vertex(name, payload, root = false) vertex = vertices[name] ||= Vertex.new(name, payload) vertex.payload ||= payload vertex.root ||= root vertex end |
#detach_vertex_named(name) ⇒ void
This method returns an undefined value.
Detaches the #vertex_named ‘name` Vertex from the graph, recursively removing any non-root vertices that were orphaned in the process
123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 123 def detach_vertex_named(name) return unless vertex = vertices.delete(name) vertex.outgoing_edges.each do |e| v = e.destination v.incoming_edges.delete(e) detach_vertex_named(v.name) unless v.root? || v.predecessors.any? end vertex.incoming_edges.each do |e| v = e.origin v.outgoing_edges.delete(e) end end |
#each ⇒ Array<Vertex> Also known as: tsort_each_node
Enumerates through the vertices of the graph.
12 13 14 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 12 def each vertices.values.each { |v| yield v } end |
#initialize_copy(other) ⇒ Object
Initializes a copy of a Bundler::Molinillo::DependencyGraph, ensuring that all #vertices are properly copied.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 55 def initialize_copy(other) super @vertices = {} traverse = lambda do |new_v, old_v| return if new_v.outgoing_edges.size == old_v.outgoing_edges.size old_v.outgoing_edges.each do |edge| destination = add_vertex(edge.destination.name, edge.destination.payload) add_edge_no_circular(new_v, destination, edge.requirement) traverse.call(destination, edge.destination) end end other.vertices.each do |name, vertex| new_vertex = add_vertex(name, vertex.payload, vertex.root?) new_vertex.explicit_requirements.replace(vertex.explicit_requirements) traverse.call(new_vertex, vertex) end end |
#inspect ⇒ String
Returns a string suitable for debugging.
74 75 76 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 74 def inspect "#{self.class}:#{vertices.values.inspect}" end |
#root_vertex_named(name) ⇒ Vertex?
Returns the root vertex with the given name.
144 145 146 147 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 144 def root_vertex_named(name) vertex = vertex_named(name) vertex if vertex && vertex.root? end |
#vertex_named(name) ⇒ Vertex?
Returns the vertex with the given name.
138 139 140 |
# File 'lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb', line 138 def vertex_named(name) vertices[name] end |