From 2f7a9c5a79d3734eba19aa881135ea39ef212774 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Tue, 11 Jan 2022 10:25:04 -0800 Subject: [PATCH] Add support for detecting and breaking cycles in graph --- .../commands/serve/mappers/internal/graph.rb | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plugins/commands/serve/mappers/internal/graph.rb b/plugins/commands/serve/mappers/internal/graph.rb index 0f40d7cd8..cfe77421c 100644 --- a/plugins/commands/serve/mappers/internal/graph.rb +++ b/plugins/commands/serve/mappers/internal/graph.rb @@ -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