Add support for detecting and breaking cycles in graph

This commit is contained in:
Chris Roberts 2022-01-11 10:25:04 -08:00 committed by Paul Hinze
parent 3cdac85d91
commit 2f7a9c5a79
No known key found for this signature in database
GPG Key ID: B69DEDF2D55501C0

View File

@ -8,6 +8,30 @@ module VagrantPlugins
class Mappers
module Internal
class Graph < RGL::DirectedAdjacencyGraph
# This iterator is used for detecting and breaking cycles
# discovered within the graph using the DFS graph visitor
# concept
class CycleDeletorIterator < RGL::DFSVisitor
# Create a new iterator instance. Store the graph
# for later inspection use
def initialize(graph, *_)
@graph = graph
super
end
# Examines the vertex to detect any cycles. If an
# adjacent edge has already been visited then we
# remove the edge to break the cycle.
def handle_examine_vertex(u)
graph.each_adjacent(u) do |v|
if v.is_a?(Vertex::Output) && color_map[v] != :WHITE
graph.remove_edge(u, v)
end
end
end
end
autoload :Mappers, Vagrant.source_root.join("plugins/commands/serve/mappers/internal/graph/mappers").to_s
autoload :Search, Vagrant.source_root.join("plugins/commands/serve/mappers/internal/graph/search").to_s
autoload :Vertex, Vagrant.source_root.join("plugins/commands/serve/mappers/internal/graph/vertex").to_s
@ -189,6 +213,10 @@ module VagrantPlugins
self
end
def break_cycles!(src)
depth_first_visit(src, CycleDeletorIterator.new(self)) { true }
end
def shortest_path(source, target)
dijkstra_shortest_path(edge_weights_map, source, target)
end