Replace dynamic distance calculation for table plugin with pre-calculated distances on shortcuts, avoiding unpacking cost.

Adds approx 10% to total data size.  Speeds up large table requests by 2 orders of magnitude.

Co-authored-by: Kajari Ghosh <ghoshkaj@gmail.com>
This commit is contained in:
Daniel Patterson
2018-10-29 21:47:49 -07:00
parent 5327f8da4e
commit 498259b220
48 changed files with 767 additions and 995 deletions
@@ -17,7 +17,8 @@ bool operator!=(const QueryEdge &lhs, const QueryEdge &rhs) { return !(lhs == rh
std::ostream &operator<<(std::ostream &out, const QueryEdge::EdgeData &data)
{
out << "{" << data.turn_id << ", " << data.shortcut << ", " << data.duration << ", "
<< data.weight << ", " << data.forward << ", " << data.backward << "}";
<< data.distance << ", " << data.weight << ", " << data.forward << ", " << data.backward
<< "}";
return out;
}
@@ -36,31 +37,31 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
ContractedEdgeContainer container;
std::vector<QueryEdge> edges;
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
edges.push_back(QueryEdge{0, 1, {1, false, 3, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 3, 3, 6, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 3, 3, 6, false, true}});
container.Insert(edges);
edges.clear();
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
edges.push_back(QueryEdge{0, 1, {1, false, 3, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 12, 12, 24, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 12, 12, 24, false, true}});
container.Merge(edges);
edges.clear();
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 4, {5, false, 3, 3, 6, true, false}});
container.Merge(edges);
std::vector<QueryEdge> reference_edges;
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 3, 3, 6, false, true}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 3, 3, 6, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 12, 24, false, true}});
CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
auto filters = container.MakeEdgeFilters();
@@ -78,22 +79,22 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
ContractedEdgeContainer container;
std::vector<QueryEdge> edges;
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
edges.push_back(QueryEdge{0, 1, {1, false, 3, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 12, 12, 24, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 12, 12, 24, false, true}});
container.Merge(edges);
edges.clear();
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 4, {5, false, 3, 3, 6, true, false}});
container.Merge(edges);
std::vector<QueryEdge> reference_edges;
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 12, 24, false, true}});
CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
auto filters = container.MakeEdgeFilters();
+1 -1
View File
@@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(contract_graph)
reference_graph.DeleteEdgesTo(1, 3);
reference_graph.DeleteEdgesTo(4, 3);
// Insert shortcut
reference_graph.InsertEdge(4, 1, {2, 4, 3, 0, true, true, false});
reference_graph.InsertEdge(4, 1, {2, 4, 1.0, 3, 0, true, true, false});
/* After contracting 4:
*
+6 -2
View File
@@ -20,15 +20,19 @@ inline contractor::ContractorGraph makeGraph(const std::vector<TestEdge> &edges)
unsigned target;
int weight;
std::tie(start, target, weight) = edge;
int duration = weight * 2;
float distance = 1.0;
max_id = std::max(std::max(start, target), max_id);
input_edges.push_back(contractor::ContractorEdge{
start,
target,
contractor::ContractorEdgeData{weight, weight * 2, id++, 0, false, true, false}});
contractor::ContractorEdgeData{
weight, duration, distance, id++, 0, false, true, false}});
input_edges.push_back(contractor::ContractorEdge{
target,
start,
contractor::ContractorEdgeData{weight, weight * 2, id++, 0, false, false, true}});
contractor::ContractorEdgeData{
weight, duration, distance, id++, 0, false, false, true}});
}
std::sort(input_edges.begin(), input_edges.end());
+15 -2
View File
@@ -27,6 +27,7 @@ auto makeGraph(const MultiLevelPartition &mlp, const std::vector<MockEdge> &mock
{
EdgeWeight weight;
EdgeDuration duration;
EdgeDistance distance;
bool forward;
bool backward;
};
@@ -36,8 +37,20 @@ auto makeGraph(const MultiLevelPartition &mlp, const std::vector<MockEdge> &mock
for (const auto &m : mock_edges)
{
max_id = std::max<std::size_t>(max_id, std::max(m.start, m.target));
edges.push_back(Edge{m.start, m.target, m.weight, 2 * m.weight, true, false});
edges.push_back(Edge{m.target, m.start, m.weight, 2 * m.weight, false, true});
edges.push_back(Edge{m.start,
m.target,
m.weight,
2 * m.weight,
static_cast<EdgeDistance>(1.0),
true,
false});
edges.push_back(Edge{m.target,
m.start,
m.weight,
2 * m.weight,
static_cast<EdgeDistance>(1.0),
false,
true});
}
std::sort(edges.begin(), edges.end());
return partitioner::MultiLevelGraph<EdgeData, osrm::storage::Ownership::Container>(
@@ -31,6 +31,7 @@ inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
to, // target
1, // weight
1, // duration
1, // distance
GeometryID{0, false}, // geometry_id
false, // reversed
NodeBasedEdgeClassification(), // default flags
@@ -47,6 +47,7 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
to,
1,
1,
1,
GeometryID{0, false},
!allowed,
NodeBasedEdgeClassification(),
@@ -174,6 +175,7 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
to,
1,
1,
1,
GeometryID{0, false},
!allowed,
NodeBasedEdgeClassification{
@@ -277,7 +279,7 @@ BOOST_AUTO_TEST_CASE(skip_degree_two_nodes)
//
const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) {
return InputEdge{
from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0};
from, to, 1, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0};
};
std::vector<InputEdge> edges = {unit_edge(0, 1, true), // 0
unit_edge(1, 0, true),
+2 -2
View File
@@ -32,9 +32,9 @@ auto makeGraph(const std::vector<MockEdge> &mock_edges)
max_id = std::max<std::size_t>(max_id, std::max(m.start, m.target));
edges.push_back(InputEdge{
m.start, m.target, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, true, false}});
m.start, m.target, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, 1, true, false}});
edges.push_back(InputEdge{
m.target, m.start, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, false, true}});
m.target, m.start, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, 1, false, true}});
}
std::sort(edges.begin(), edges.end());
return DynamicEdgeBasedGraph(max_id + 1, edges);