Don't return edge list in contractor but modify graph in-place

This commit is contained in:
Patrick Niklaus 2017-08-19 11:01:32 +00:00 committed by Patrick Niklaus
parent 247f1c120f
commit 421dc5b6ec
4 changed files with 58 additions and 63 deletions

View File

@ -95,74 +95,24 @@ class GraphContractor
}; };
public: public:
GraphContractor(ContractorGraph graph); GraphContractor(ContractorGraph &graph);
GraphContractor(ContractorGraph graph, GraphContractor(ContractorGraph &graph,
std::vector<float> node_levels_, std::vector<float> node_levels_,
std::vector<EdgeWeight> node_weights_); std::vector<EdgeWeight> node_weights_);
void RenumberGraph(ThreadDataContainer &thread_data_list,
std::vector<RemainingNodeData> &remaining_nodes,
std::vector<float> &node_priorities);
void Run(double core_factor = 1.0); void Run(double core_factor = 1.0);
std::vector<bool> GetCoreMarker(); std::vector<bool> GetCoreMarker();
std::vector<float> GetNodeLevels(); std::vector<float> GetNodeLevels();
template <class Edge> inline util::DeallocatingVector<Edge> GetEdges()
{
util::DeallocatingVector<Edge> edges;
util::UnbufferedLog log;
log << "Getting edges of minimized graph ";
util::Percent p(log, graph.GetNumberOfNodes());
const NodeID number_of_nodes = graph.GetNumberOfNodes();
if (graph.GetNumberOfNodes())
{
Edge new_edge;
for (const auto node : util::irange(0u, number_of_nodes))
{
p.PrintStatus(node);
for (auto edge : graph.GetAdjacentEdgeRange(node))
{
const NodeID target = graph.GetTarget(edge);
const ContractorGraph::EdgeData &data = graph.GetEdgeData(edge);
new_edge.source = orig_node_id_from_new_node_id_map[node];
new_edge.target = orig_node_id_from_new_node_id_map[target];
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
new_edge.data.weight = data.weight;
new_edge.data.duration = data.duration;
new_edge.data.shortcut = data.shortcut;
if (data.shortcut)
{
// tranlate the _node id_ of the shortcutted node
new_edge.data.turn_id = orig_node_id_from_new_node_id_map[data.id];
}
else
{
new_edge.data.turn_id = data.id;
}
BOOST_ASSERT_MSG(new_edge.data.turn_id != INT_MAX, // 2^31
"edge id invalid");
new_edge.data.forward = data.forward;
new_edge.data.backward = data.backward;
edges.push_back(new_edge);
}
}
}
graph = ContractorGraph{};
// sort and remove duplicates
tbb::parallel_sort(edges.begin(), edges.end());
auto new_end = std::unique(edges.begin(), edges.end());
edges.resize(new_end - edges.begin());
return edges;
}
private: private:
void RenumberGraph(ThreadDataContainer &thread_data_list,
std::vector<RemainingNodeData> &remaining_nodes,
std::vector<float> &node_priorities);
float EvaluateNodePriority(ContractorThreadData *const data, float EvaluateNodePriority(ContractorThreadData *const data,
const NodeDepth node_depth, const NodeDepth node_depth,
const NodeID node); const NodeID node);
@ -386,7 +336,7 @@ class GraphContractor
// This bias function takes up 22 assembly instructions in total on X86 // This bias function takes up 22 assembly instructions in total on X86
bool Bias(const NodeID a, const NodeID b) const; bool Bias(const NodeID a, const NodeID b) const;
ContractorGraph graph; ContractorGraph &graph;
std::vector<NodeID> orig_node_id_from_new_node_id_map; std::vector<NodeID> orig_node_id_from_new_node_id_map;
std::vector<float> node_levels; std::vector<float> node_levels;

View File

@ -3,6 +3,7 @@
#include "contractor/contractor_graph.hpp" #include "contractor/contractor_graph.hpp"
#include "util/log.hpp" #include "util/log.hpp"
#include "util/percent.hpp"
#include <tbb/parallel_sort.h> #include <tbb/parallel_sort.h>
@ -123,6 +124,48 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
return ContractorGraph{number_of_nodes, edges}; return ContractorGraph{number_of_nodes, edges};
} }
template <class Edge> inline util::DeallocatingVector<Edge> toEdges(ContractorGraph graph)
{
util::DeallocatingVector<Edge> edges;
util::UnbufferedLog log;
log << "Getting edges of minimized graph ";
util::Percent p(log, graph.GetNumberOfNodes());
const NodeID number_of_nodes = graph.GetNumberOfNodes();
if (graph.GetNumberOfNodes())
{
Edge new_edge;
for (const auto node : util::irange(0u, number_of_nodes))
{
p.PrintStatus(node);
for (auto edge : graph.GetAdjacentEdgeRange(node))
{
const NodeID target = graph.GetTarget(edge);
const ContractorGraph::EdgeData &data = graph.GetEdgeData(edge);
new_edge.source = node;
new_edge.target = target;
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
new_edge.data.weight = data.weight;
new_edge.data.duration = data.duration;
new_edge.data.shortcut = data.shortcut;
new_edge.data.turn_id = data.id;
BOOST_ASSERT_MSG(new_edge.data.turn_id != INT_MAX, // 2^31
"edge id invalid");
new_edge.data.forward = data.forward;
new_edge.data.backward = data.backward;
edges.push_back(new_edge);
}
}
}
// sort and remove duplicates
tbb::parallel_sort(edges.begin(), edges.end());
auto new_end = std::unique(edges.begin(), edges.end());
edges.resize(new_end - edges.begin());
return edges;
}
} // namespace contractor } // namespace contractor
} // namespace osrm } // namespace osrm

View File

@ -72,12 +72,13 @@ int Contractor::Run()
util::DeallocatingVector<QueryEdge> contracted_edge_list; util::DeallocatingVector<QueryEdge> contracted_edge_list;
{ // own scope to not keep the contractor around { // own scope to not keep the contractor around
GraphContractor graph_contractor(toContractorGraph(max_edge_id+1, std::move(edge_based_edge_list)), auto contractor_graph = toContractorGraph(max_edge_id+1, std::move(edge_based_edge_list));
GraphContractor graph_contractor(contractor_graph,
std::move(node_levels), std::move(node_levels),
std::move(node_weights)); std::move(node_weights));
graph_contractor.Run(config.core_factor); graph_contractor.Run(config.core_factor);
contracted_edge_list = graph_contractor.GetEdges<QueryEdge>(); contracted_edge_list = toEdges<QueryEdge>(std::move(contractor_graph));
is_core_node = graph_contractor.GetCoreMarker(); is_core_node = graph_contractor.GetCoreMarker();
node_levels = graph_contractor.GetNodeLevels(); node_levels = graph_contractor.GetNodeLevels();
} }

View File

@ -5,15 +5,15 @@ namespace osrm
namespace contractor namespace contractor
{ {
GraphContractor::GraphContractor(ContractorGraph graph_) GraphContractor::GraphContractor(ContractorGraph &graph)
: GraphContractor(std::move(graph_), {}, {}) : GraphContractor(graph, {}, {})
{ {
} }
GraphContractor::GraphContractor(ContractorGraph graph_, GraphContractor::GraphContractor(ContractorGraph &graph,
std::vector<float> node_levels_, std::vector<float> node_levels_,
std::vector<EdgeWeight> node_weights_) std::vector<EdgeWeight> node_weights_)
: graph(std::move(graph_)), orig_node_id_from_new_node_id_map(graph.GetNumberOfNodes()), : graph(graph), orig_node_id_from_new_node_id_map(graph.GetNumberOfNodes()),
node_levels(std::move(node_levels_)), node_weights(std::move(node_weights_)) node_levels(std::move(node_levels_)), node_weights(std::move(node_weights_))
{ {
// Fill the map with an identiy mapping // Fill the map with an identiy mapping
@ -307,6 +307,7 @@ void GraphContractor::Run(double core_factor)
util::inplacePermutation(node_levels.begin(), node_levels.end(), orig_node_id_from_new_node_id_map); util::inplacePermutation(node_levels.begin(), node_levels.end(), orig_node_id_from_new_node_id_map);
util::inplacePermutation(is_core_node.begin(), is_core_node.end(), orig_node_id_from_new_node_id_map); util::inplacePermutation(is_core_node.begin(), is_core_node.end(), orig_node_id_from_new_node_id_map);
graph.Renumber(orig_node_id_from_new_node_id_map);
thread_data_list.data.clear(); thread_data_list.data.clear();
} }