#ifndef STATIC_GRAPH_HPP #define STATIC_GRAPH_HPP #include "util/percent.hpp" #include "util/shared_memory_vector_wrapper.hpp" #include "util/integer_range.hpp" #include "util/typedefs.hpp" #include #include #include #include #include namespace osrm { namespace util { template class StaticGraph { public: using NodeIterator = NodeID; using EdgeIterator = NodeID; using EdgeData = EdgeDataT; using EdgeRange = range; class InputEdge { public: NodeIterator source; NodeIterator target; EdgeDataT data; template InputEdge(NodeIterator source, NodeIterator target, Ts &&... data) : source(source), target(target), data(std::forward(data)...) { } bool operator<(const InputEdge &right) const { if (source != right.source) { return source < right.source; } return target < right.target; } }; struct NodeArrayEntry { // index of the first edge EdgeIterator first_edge; }; struct EdgeArrayEntry { NodeID target; EdgeDataT data; }; EdgeRange GetAdjacentEdgeRange(const NodeID node) const { return irange(BeginEdges(node), EndEdges(node)); } template StaticGraph(const int nodes, const ContainerT &graph) { BOOST_ASSERT(std::is_sorted(const_cast(graph).begin(), const_cast(graph).end())); number_of_nodes = nodes; number_of_edges = static_cast(graph.size()); node_array.resize(number_of_nodes + 1); EdgeIterator edge = 0; EdgeIterator position = 0; for (const auto node : irange(0u, number_of_nodes + 1)) { EdgeIterator last_edge = edge; while (edge < number_of_edges && graph[edge].source == node) { ++edge; } node_array[node].first_edge = position; //=edge position += edge - last_edge; // remove } edge_array.resize(position); //(edge) edge = 0; for (const auto node : irange(0u, number_of_nodes)) { EdgeIterator e = node_array[node + 1].first_edge; for (const auto i : irange(node_array[node].first_edge, e)) { edge_array[i].target = graph[edge].target; edge_array[i].data = graph[edge].data; edge++; } } } StaticGraph(typename ShM::vector &nodes, typename ShM::vector &edges) { number_of_nodes = static_cast(nodes.size() - 1); number_of_edges = static_cast(edges.size()); using std::swap; swap(node_array, nodes); swap(edge_array, edges); } unsigned GetNumberOfNodes() const { return number_of_nodes; } unsigned GetNumberOfEdges() const { return number_of_edges; } unsigned GetOutDegree(const NodeIterator n) const { return EndEdges(n) - BeginEdges(n); } inline NodeIterator GetTarget(const EdgeIterator e) const { return NodeIterator(edge_array[e].target); } EdgeDataT &GetEdgeData(const EdgeIterator e) { return edge_array[e].data; } const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return edge_array[e].data; } EdgeIterator BeginEdges(const NodeIterator n) const { return EdgeIterator(node_array.at(n).first_edge); } EdgeIterator EndEdges(const NodeIterator n) const { return EdgeIterator(node_array.at(n + 1).first_edge); } // searches for a specific edge EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const { for (const auto i : irange(BeginEdges(from), EndEdges(from))) { if (to == edge_array[i].target) { return i; } } return SPECIAL_EDGEID; } // searches for a specific edge EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to) const { EdgeIterator smallest_edge = SPECIAL_EDGEID; EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT; for (auto edge : GetAdjacentEdgeRange(from)) { const NodeID target = GetTarget(edge); const EdgeWeight weight = GetEdgeData(edge).distance; if (target == to && weight < smallest_weight) { smallest_edge = edge; smallest_weight = weight; } } return smallest_edge; } EdgeIterator FindEdgeInEitherDirection(const NodeIterator from, const NodeIterator to) const { EdgeIterator tmp = FindEdge(from, to); return (SPECIAL_NODEID != tmp ? tmp : FindEdge(to, from)); } EdgeIterator FindEdgeIndicateIfReverse(const NodeIterator from, const NodeIterator to, bool &result) const { EdgeIterator current_iterator = FindEdge(from, to); if (SPECIAL_NODEID == current_iterator) { current_iterator = FindEdge(to, from); if (SPECIAL_NODEID != current_iterator) { result = true; } } return current_iterator; } private: NodeIterator number_of_nodes; EdgeIterator number_of_edges; typename ShM::vector node_array; typename ShM::vector edge_array; }; } } #endif // STATIC_GRAPH_HPP