From f85f5504d6ecdde882b37c43999a1eb1aa00263f Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 28 Apr 2015 23:17:34 +0100 Subject: [PATCH] Exit early when searching for a path. Don't wait until all connected vertices have been searched, exit when the target vertex is found. --- src/backend/graph.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/backend/graph.cpp b/src/backend/graph.cpp index 9e86f13c..32481e09 100644 --- a/src/backend/graph.cpp +++ b/src/backend/graph.cpp @@ -83,6 +83,15 @@ namespace loot { } }; + struct path_detector : public boost::bfs_visitor < > { + vertex_t target; + + inline void discover_vertex(vertex_t u, const PluginGraph& g) { + if (u == target) + throw error(error::ok, "Found a path."); + } + }; + bool GetVertexByName(const PluginGraph& graph, const std::string& name, vertex_t& vertex) { vertex_it vit, vit_end; boost::tie(vit, vit_end) = boost::vertices(graph); @@ -104,12 +113,16 @@ namespace loot { bool EdgeCreatesCycle(const vertex_t& u, const vertex_t& v, const PluginGraph& graph, const vertex_map_t& v_index_map) { //A cycle is created when adding the edge (u,v) if there already exists a path from v to u, so check for that using a breadth-first search. - map predecessor_map; - boost::associative_property_map< map > v_predecessor_map(predecessor_map); - - boost::breadth_first_search(graph, v, visitor(boost::make_bfs_visitor(boost::record_predecessors(v_predecessor_map, boost::on_tree_edge()))).vertex_index_map(v_index_map)); - - return predecessor_map.find(u) != predecessor_map.end(); + path_detector vis; + vis.target = u; + try { + boost::breadth_first_search(graph, v, visitor(vis).vertex_index_map(v_index_map)); + } + catch (error& e) { + if (e.code() == error::ok) + return true; + } + return false; } void AddSpecificEdges(PluginGraph& graph, const vertex_map_t& v_index_map) {