diff --git a/algorithms/bfs_components.hpp b/algorithms/bfs_components.hpp index bdcbd5e43..57be63553 100644 --- a/algorithms/bfs_components.hpp +++ b/algorithms/bfs_components.hpp @@ -122,38 +122,38 @@ template class BFSComponentExplorer const NodeID u = current_queue_item.second; // parent // increment size counter of current component ++current_component_size; - const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); - if (!is_barrier_node) + if (m_barrier_nodes.find(v) != m_barrier_nodes.end()) { - const NodeID to_node_of_only_restriction = - m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); + continue; + } + const NodeID to_node_of_only_restriction = + m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); - for (auto e2 : m_graph.GetAdjacentEdgeRange(v)) + for (auto e2 : m_graph.GetAdjacentEdgeRange(v)) + { + const NodeID w = m_graph.GetTarget(e2); + + if (to_node_of_only_restriction != std::numeric_limits::max() && + w != to_node_of_only_restriction) { - const NodeID w = m_graph.GetTarget(e2); + // At an only_-restriction but not at the right turn + continue; + } - if (to_node_of_only_restriction != std::numeric_limits::max() && - w != to_node_of_only_restriction) + if (u != w) + { + // only add an edge if turn is not a U-turn except + // when it is at the end of a dead-end street. + if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w)) { - // At an only_-restriction but not at the right turn - continue; - } - - if (u != w) - { - // only add an edge if turn is not a U-turn except - // when it is at the end of a dead-end street. - if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w)) + // only add an edge if turn is not prohibited + if (std::numeric_limits::max() == m_component_index_list[w]) { - // only add an edge if turn is not prohibited - if (std::numeric_limits::max() == m_component_index_list[w]) - { - // insert next (node, parent) only if w has - // not yet been explored - // mark node as read - m_component_index_list[w] = current_component; - bfs_queue.emplace(w, v); - } + // insert next (node, parent) only if w has + // not yet been explored + // mark node as read + m_component_index_list[w] = current_component; + bfs_queue.emplace(w, v); } } } diff --git a/algorithms/tiny_components.hpp b/algorithms/tiny_components.hpp index 44256e2ab..322137562 100644 --- a/algorithms/tiny_components.hpp +++ b/algorithms/tiny_components.hpp @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../data_structures/query_node.hpp" #include "../data_structures/percent.hpp" #include "../data_structures/restriction.hpp" +#include "../data_structures/restriction_map.hpp" #include "../data_structures/turn_instructions.hpp" #include "../Util/integer_range.hpp" @@ -75,64 +76,23 @@ class TarjanSCC bool on_stack; }; - using RestrictionSource = std::pair; - using RestrictionTarget = std::pair; - using EmanatingRestrictionsVector = std::vector; - using RestrictionMap = std::unordered_map; - - std::vector m_restriction_bucket_list; std::vector components_index; std::vector component_size_vector; std::shared_ptr m_node_based_graph; - std::unordered_set barrier_node_list; - unsigned size_one_counter; + std::unordered_set barrier_node_set; RestrictionMap m_restriction_map; + unsigned size_one_counter; public: TarjanSCC(std::shared_ptr graph, - std::vector &bn, - std::vector &irs) + const RestrictionMap &restrictions, + const std::vector &barrier_node_list) : components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID), - m_node_based_graph(graph), + m_node_based_graph(graph), m_restriction_map(restrictions), size_one_counter(0) { - - TIMER_START(SCC_LOAD); - for (const TurnRestriction &restriction : irs) - { - std::pair restriction_source = {restriction.from.node, - restriction.via.node}; - unsigned index = 0; - const auto restriction_iterator = m_restriction_map.find(restriction_source); - if (restriction_iterator == m_restriction_map.end()) - { - index = m_restriction_bucket_list.size(); - m_restriction_bucket_list.resize(index + 1); - m_restriction_map.emplace(restriction_source, index); - } - else - { - index = restriction_iterator->second; - // Map already contains an is_only_*-restriction - if (m_restriction_bucket_list.at(index).begin()->second) - { - continue; - } - else if (restriction.flags.is_only) - { - // We are going to insert an is_only_*-restriction. There can be only one. - m_restriction_bucket_list.at(index).clear(); - } - } - - m_restriction_bucket_list.at(index) - .emplace_back(restriction.to.node, restriction.flags.is_only); - } - - barrier_node_list.insert(bn.begin(), bn.end()); - - TIMER_STOP(SCC_LOAD); - SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s"; + barrier_node_set.insert(std::begin(barrier_node_list), std::end(barrier_node_list)); + BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() > 0); } void Run() @@ -158,8 +118,10 @@ class TarjanSCC while (!recursion_stack.empty()) { TarjanStackFrame currentFrame = recursion_stack.top(); + const NodeID u = currentFrame.parent; const NodeID v = currentFrame.v; recursion_stack.pop(); + const bool before_recursion = processing_node_before_recursion[v]; if (before_recursion && tarjan_node_list[v].index != UINT_MAX) @@ -181,9 +143,29 @@ class TarjanSCC ++index; // Traverse outgoing edges + if (barrier_node_set.find(v) != barrier_node_set.end()) + { + continue; + } + + const NodeID to_node_of_only_restriction = + m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); + for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v)) { const auto vprime = m_node_based_graph->GetTarget(current_edge); + if (to_node_of_only_restriction != std::numeric_limits::max() && + vprime == to_node_of_only_restriction) + { + // At an only_-restriction but not at the right turn + // continue; + } + + if (m_restriction_map.CheckIfTurnIsRestricted(u, v, vprime)) + { + // continue; + } + if (SPECIAL_NODEID == tarjan_node_list[vprime].index) { recursion_stack.emplace(TarjanStackFrame(vprime, v)); @@ -253,44 +235,6 @@ class TarjanSCC { return component_size_vector[components_index[node]]; } - - private: - unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const - { - std::pair restriction_source = {u, v}; - const auto restriction_iterator = m_restriction_map.find(restriction_source); - if (restriction_iterator != m_restriction_map.end()) - { - const unsigned index = restriction_iterator->second; - for (const RestrictionSource &restriction_target : m_restriction_bucket_list.at(index)) - { - if (restriction_target.second) - { - return restriction_target.first; - } - } - } - return SPECIAL_NODEID; - } - - bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const - { - // only add an edge if turn is not a U-turn except it is the end of dead-end street. - std::pair restriction_source = {u, v}; - const auto restriction_iterator = m_restriction_map.find(restriction_source); - if (restriction_iterator != m_restriction_map.end()) - { - const unsigned index = restriction_iterator->second; - for (const RestrictionTarget &restriction_target : m_restriction_bucket_list.at(index)) - { - if (w == restriction_target.first) - { - return true; - } - } - } - return false; - } }; #endif /* TINY_COMPONENTS_HPP */ diff --git a/tools/components.cpp b/tools/components.cpp index dae7eb414..79b09e9f5 100644 --- a/tools/components.cpp +++ b/tools/components.cpp @@ -52,7 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include std::vector coordinate_list; -std::vector restrictions_vector; +std::vector restriction_list; std::vector bollard_node_list; std::vector traffic_lights_list; @@ -107,12 +107,12 @@ int main(int argc, char *argv[]) } uint32_t usable_restrictions = 0; restriction_ifstream.read((char *)&usable_restrictions, sizeof(uint32_t)); - restrictions_vector.resize(usable_restrictions); + restriction_list.resize(usable_restrictions); // load restrictions if (usable_restrictions > 0) { - restriction_ifstream.read((char *)&(restrictions_vector[0]), + restriction_ifstream.read((char *)&(restriction_list[0]), usable_restrictions * sizeof(TurnRestriction)); } restriction_ifstream.close(); @@ -130,14 +130,14 @@ int main(int argc, char *argv[]) bollard_node_list, traffic_lights_list, &coordinate_list, - restrictions_vector); + restriction_list); input_stream.close(); - BOOST_ASSERT_MSG(restrictions_vector.size() == usable_restrictions, - "size of restrictions_vector changed"); + BOOST_ASSERT_MSG(restriction_list.size() == usable_restrictions, + "size of restriction_list changed"); - SimpleLogger().Write() << restrictions_vector.size() << " restrictions, " + SimpleLogger().Write() << restriction_list.size() << " restrictions, " << bollard_node_list.size() << " bollard nodes, " << traffic_lights_list.size() << " traffic lights"; @@ -179,9 +179,11 @@ int main(int argc, char *argv[]) edge_list.shrink_to_fit(); SimpleLogger().Write() << "Starting SCC graph traversal"; + + RestrictionMap restriction_map(restriction_list); auto tarjan = osrm::make_unique>(graph, - bollard_node_list, - restrictions_vector); + restriction_map, + bollard_node_list); tarjan->Run(); // output