/srv/osrm/osrm-backend/include/util
NameSizeModeActions
guidance/-0755rm
alias.hpp68700644editdlrm
assert.hpp19640644editdlrm
attributes.hpp3570644editdlrm
bearing.hpp39640644editdlrm
bit_range.hpp29500644editdlrm
cheap_ruler.hpp21240644editdlrm
concurrent_id_map.hpp21480644editdlrm
conditional_restrictions.hpp6270644editdlrm
connectivity_checksum.hpp19310644editdlrm
coordinate.hpp92440644editdlrm
coordinate_calculation.hpp162970644editdlrm
deallocating_vector.hpp112050644editdlrm
debug.hpp59580644editdlrm
dist_table_wrapper.hpp22990644editdlrm
dynamic_graph.hpp159510644editdlrm
exception.hpp51260644editdlrm
exception_utils.hpp6090644editdlrm
exclude_flag.hpp9750644editdlrm
filtered_graph.hpp54020644editdlrm
filtered_integer_range.hpp30970644editdlrm
fingerprint.hpp11660644editdlrm
for_each_indexed.hpp6340644editdlrm
for_each_pair.hpp9900644editdlrm
for_each_range.hpp4770644editdlrm
geojson_debug_logger.hpp63300644editdlrm
geojson_debug_policies.hpp18100644editdlrm
geojson_debug_policy_toolkit.hpp32580644editdlrm
geojson_validation.hpp28990644editdlrm
graph_traits.hpp12450644editdlrm
graph_utils.hpp31410644editdlrm
group_by.hpp7220644editdlrm
hilbert_value.hpp30100644editdlrm
indexed_data.hpp150390644editdlrm
integer_range.hpp32860644editdlrm
isatty.hpp6100644editdlrm
json_container.hpp31810644editdlrm
json_deep_compare.hpp47320644editdlrm
json_renderer.hpp41600644editdlrm
json_util.hpp5440644editdlrm
log.hpp21870644editdlrm
lua_util.hpp8910644editdlrm
matrix_graph_wrapper.hpp12940644editdlrm
meminfo.hpp6600644editdlrm
mmap_file.hpp27760644editdlrm
mmap_tar.hpp10070644editdlrm
msb.hpp11780644editdlrm
node_based_graph.hpp35300644editdlrm
opening_hours.hpp83380644editdlrm
packed_vector.hpp216910644editdlrm
percent.hpp21060644editdlrm
permutation.hpp19910644editdlrm
query_heap.hpp102050644editdlrm
range_table.hpp71190644editdlrm
rectangle.hpp59000644editdlrm
serialization.hpp59020644editdlrm
static_assert.hpp6400644editdlrm
static_graph.hpp107020644editdlrm
static_rtree.hpp341470644editdlrm
std_hash.hpp10350644editdlrm
string_util.hpp34000644editdlrm
tarjan_scc.hpp66460644editdlrm
timed_histogram.hpp25760644editdlrm
timezones.hpp14170644editdlrm
timing_util.hpp14850644editdlrm
to_osm_link.hpp6940644editdlrm
trigonometry_table.hpp359060644editdlrm
typedefs.hpp76270644editdlrm
vector_tile.hpp3030644editdlrm
vector_view.hpp80000644editdlrm
version.hpp.in4060644editdlrm
viewport.hpp15790644editdlrm
web_mercator.hpp64800644editdlrm
xor_fast_hash.hpp17970644editdlrm
xor_fast_hash_storage.hpp21950644editdlrm
Edit: /srv/osrm/osrm-backend/include/util/tarjan_scc.hpp (6646B)
#ifndef TARJAN_SCC_HPP #define TARJAN_SCC_HPP #include "extractor/node_based_edge.hpp" #include "extractor/query_node.hpp" #include "util/deallocating_vector.hpp" #include "util/percent.hpp" #include "util/typedefs.hpp" #include "util/integer_range.hpp" #include "util/log.hpp" #include "util/std_hash.hpp" #include "util/timing_util.hpp" #include "osrm/coordinate.hpp" #include #include #include #include #include #include #include namespace osrm::util { template class TarjanSCC { struct TarjanStackFrame { explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {} NodeID v; NodeID parent; }; struct TarjanNode { TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {} unsigned index; unsigned low_link; bool on_stack; }; std::vector components_index; std::vector component_size_vector; const GraphT &m_graph; std::size_t size_one_counter; public: TarjanSCC(const GraphT &graph) : components_index(graph.GetNumberOfNodes(), SPECIAL_NODEID), m_graph(graph), size_one_counter(0) { BOOST_ASSERT(m_graph.GetNumberOfNodes() > 0); } void Run() { TIMER_START(SCC_RUN); const NodeID max_node_id = m_graph.GetNumberOfNodes(); // The following is a hack to distinguish between stuff that happens // before the recursive call and stuff that happens after std::stack recursion_stack; // true = stuff before, false = stuff after call std::stack tarjan_stack; std::vector tarjan_node_list(max_node_id); unsigned component_index = 0, size_of_current_component = 0; unsigned large_component_count = 0; unsigned index = 0; std::vector processing_node_before_recursion(max_node_id, true); for (const NodeID node : util::irange(0u, max_node_id)) { if (SPECIAL_NODEID == components_index[node]) { recursion_stack.emplace(TarjanStackFrame(node, node)); } 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) { continue; } if (before_recursion) { // Mark frame to handle tail of recursion recursion_stack.emplace(currentFrame); processing_node_before_recursion[v] = false; // Mark essential information for SCC tarjan_node_list[v].index = index; tarjan_node_list[v].low_link = index; tarjan_stack.push(v); tarjan_node_list[v].on_stack = true; ++index; for (const auto current_edge : m_graph.GetAdjacentEdgeRange(v)) { const auto vprime = m_graph.GetTarget(current_edge); if (SPECIAL_NODEID == tarjan_node_list[vprime].index) { recursion_stack.emplace(TarjanStackFrame(vprime, v)); } else { if (tarjan_node_list[vprime].on_stack && tarjan_node_list[vprime].index < tarjan_node_list[v].low_link) { tarjan_node_list[v].low_link = tarjan_node_list[vprime].index; } } } } else { processing_node_before_recursion[v] = true; tarjan_node_list[u].low_link = std::min(tarjan_node_list[u].low_link, tarjan_node_list[v].low_link); // after recursion, lets do cycle checking // Check if we found a cycle. This is the bottom part of the recursion if (tarjan_node_list[v].low_link == tarjan_node_list[v].index) { NodeID vprime; do { vprime = tarjan_stack.top(); tarjan_stack.pop(); tarjan_node_list[vprime].on_stack = false; components_index[vprime] = component_index; ++size_of_current_component; } while (v != vprime); component_size_vector.emplace_back(size_of_current_component); if (size_of_current_component > 1000) { ++large_component_count; util::Log(logDEBUG) << "large component [" << component_index << "]=" << size_of_current_component; } ++component_index; size_of_current_component = 0; } } } } TIMER_STOP(SCC_RUN); util::Log() << "Found " << component_index << " SCC (" << large_component_count << " large, " << (component_index - large_component_count) << " small)"; util::Log() << "SCC run took: " << TIMER_MSEC(SCC_RUN) / 1000. << "s"; size_one_counter = std::count_if(component_size_vector.begin(), component_size_vector.end(), [](unsigned value) { return 1 == value; }); } std::size_t GetNumberOfComponents() const { return component_size_vector.size(); } std::size_t GetSizeOneCount() const { return size_one_counter; } unsigned GetComponentSize(const unsigned component_id) const { return component_size_vector[component_id]; } unsigned GetComponentID(const NodeID node) const { return components_index[node]; } }; } // namespace osrm::util #endif /* TARJAN_SCC_HPP */