Renumber nodes after running osrm-partition
The new numbering uses the partition information to sort border nodes first to compactify storages that need access indexed by border node ID. We also get an optimized cache performance for free sincr we can also recursively sort the nodes by cell ID. This implements issue #3779.
This commit is contained in:
committed by
Patrick Niklaus
parent
a195d7dfd3
commit
0266c9d969
@@ -0,0 +1,86 @@
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "partition/renumber.hpp"
|
||||
|
||||
#include "../common/range_tools.hpp"
|
||||
|
||||
using namespace osrm;
|
||||
using namespace osrm::partition;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct MockEdge
|
||||
{
|
||||
NodeID start;
|
||||
NodeID target;
|
||||
};
|
||||
|
||||
auto makeGraph(const std::vector<MockEdge> &mock_edges)
|
||||
{
|
||||
struct EdgeData
|
||||
{
|
||||
EdgeWeight weight;
|
||||
bool forward;
|
||||
bool backward;
|
||||
};
|
||||
using InputEdge = DynamicEdgeBasedGraph::InputEdge;
|
||||
std::vector<InputEdge> edges;
|
||||
std::size_t max_id = 0;
|
||||
for (const auto &m : 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}});
|
||||
edges.push_back(InputEdge{
|
||||
m.target, m.start, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, false, true}});
|
||||
}
|
||||
std::sort(edges.begin(), edges.end());
|
||||
return DynamicEdgeBasedGraph(max_id + 1, edges);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(renumber_tests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(unsplitable_case)
|
||||
{
|
||||
// node: 0 1 2 3 4 5 6 7 8 9 10 11
|
||||
// border: x x x x x x x
|
||||
// permutation by cells: 0 1 2 5 6 10 11 7 8 9 3 4
|
||||
// order by cell: 0 1 2 10 11 3 4 7 8 9 5 6
|
||||
// x x x x x x x
|
||||
// border level: 3 3 3 2 2 1 1 0 0 0 0 0
|
||||
// order: 0 10 11 7 6 3 4 1 2 8 9 5
|
||||
// permutation: 0 7 8 5 6 11 4 3 9 10 1 2
|
||||
std::vector<CellID> l1{{0, 0, 1, 2, 3, 5, 5, 3, 4, 4, 1, 2}};
|
||||
std::vector<CellID> l2{{0, 0, 0, 1, 1, 3, 3, 1, 2, 2, 0, 1}};
|
||||
std::vector<CellID> l3{{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}};
|
||||
std::vector<CellID> l4{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
|
||||
std::vector<MockEdge> edges = {
|
||||
// edges sorted into border/internal by level
|
||||
// level: (1) (2) (3) (4)
|
||||
{0, 1}, // i i i i
|
||||
{2, 10}, // i i i i
|
||||
{10, 7}, // b b b i
|
||||
{11, 0}, // b b b i
|
||||
{11, 3}, // i i i i
|
||||
{3, 4}, // b i i i
|
||||
{4, 11}, // b i i i
|
||||
{4, 7}, // i i i i
|
||||
{7, 6}, // b b i i
|
||||
{8, 9}, // i i i i
|
||||
{9, 8}, // i i i i
|
||||
{5, 6}, // i i i i
|
||||
{6, 5} // i i i i
|
||||
};
|
||||
|
||||
auto graph = makeGraph(edges);
|
||||
std::vector<Partition> partitions{l1, l2, l3, l4};
|
||||
|
||||
auto permutation = makePermutation(graph, partitions);
|
||||
CHECK_EQUAL_RANGE(permutation, 0, 7, 8, 5, 6, 11, 4, 3, 9, 10, 1, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -64,4 +64,60 @@ BOOST_AUTO_TEST_CASE(find_test)
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(renumber_test)
|
||||
{
|
||||
/*
|
||||
* (0) -1-> (1)
|
||||
* ^ ^
|
||||
* 2 5
|
||||
* | |
|
||||
* (3) -3-> (4)
|
||||
* <-4-
|
||||
*/
|
||||
std::vector<TestInputEdge> input_edges = {TestInputEdge{0, 1, TestData{1}},
|
||||
TestInputEdge{3, 0, TestData{2}},
|
||||
TestInputEdge{3, 0, TestData{5}},
|
||||
TestInputEdge{3, 4, TestData{3}},
|
||||
TestInputEdge{4, 3, TestData{4}}};
|
||||
TestDynamicGraph simple_graph(5, input_edges);
|
||||
|
||||
/*
|
||||
* (1) -1-> (3)
|
||||
* ^ ^
|
||||
* 2 5
|
||||
* | |
|
||||
* (0) -3-> (2)
|
||||
* <-4-
|
||||
*/
|
||||
simple_graph.Renumber({1, 3, 4, 0, 2});
|
||||
|
||||
auto eit = simple_graph.FindEdge(1, 3);
|
||||
BOOST_CHECK(eit != SPECIAL_EDGEID);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 1);
|
||||
|
||||
eit = simple_graph.FindEdge(3, 1);
|
||||
BOOST_CHECK_EQUAL(eit, SPECIAL_EDGEID);
|
||||
|
||||
eit = simple_graph.FindEdgeInEitherDirection(3, 1);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 1);
|
||||
|
||||
bool reverse = false;
|
||||
eit = simple_graph.FindEdgeIndicateIfReverse(3, 1, reverse);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 1);
|
||||
BOOST_CHECK(reverse);
|
||||
|
||||
eit = simple_graph.FindEdge(0, 3);
|
||||
BOOST_CHECK_EQUAL(eit, SPECIAL_EDGEID);
|
||||
eit = simple_graph.FindEdge(1, 2);
|
||||
BOOST_CHECK_EQUAL(eit, SPECIAL_EDGEID);
|
||||
|
||||
eit = simple_graph.FindEdge(0, 2);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 3);
|
||||
eit = simple_graph.FindEdgeInEitherDirection(0, 2);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 3);
|
||||
|
||||
eit = simple_graph.FindEdge(0, 1);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "../common/range_tools.hpp"
|
||||
|
||||
#include "util/permutation.hpp"
|
||||
|
||||
#include <boost/test/test_case_template.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <random>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(permutation_test)
|
||||
|
||||
using namespace osrm;
|
||||
using namespace osrm::util;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(basic_permuation)
|
||||
{
|
||||
// cycles (0 3 2 1 4 8) (5) (6 9 7)
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
std::vector<std::uint32_t> values{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
const std::vector<std::uint32_t> permutation{3, 4, 1, 2, 8, 5, 9, 6, 0, 7};
|
||||
std::vector<std::uint32_t> reference{9, 3, 4, 1, 2, 6, 8, 10, 5, 7};
|
||||
|
||||
inplacePermutation(values.begin(), values.end(), permutation);
|
||||
|
||||
CHECK_EQUAL_COLLECTIONS(values, reference);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -150,4 +150,59 @@ BOOST_AUTO_TEST_CASE(find_test)
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(renumber_test)
|
||||
{
|
||||
/*
|
||||
* (0) -1-> (1)
|
||||
* ^ ^
|
||||
* 2 5
|
||||
* | |
|
||||
* (3) -3-> (4)
|
||||
* <-4-
|
||||
*/
|
||||
std::vector<TestInputEdge> input_edges = {TestInputEdge{0, 1, EdgeID{1}},
|
||||
TestInputEdge{3, 0, EdgeID{2}},
|
||||
TestInputEdge{3, 0, EdgeID{5}},
|
||||
TestInputEdge{3, 4, EdgeID{3}},
|
||||
TestInputEdge{4, 3, EdgeID{4}}};
|
||||
TestStaticGraph simple_graph(5, input_edges);
|
||||
/*
|
||||
* (1) -1-> (3)
|
||||
* ^ ^
|
||||
* 2 5
|
||||
* | |
|
||||
* (0) -3-> (2)
|
||||
* <-4-
|
||||
*/
|
||||
simple_graph.Renumber({1, 3, 4, 0, 2});
|
||||
|
||||
auto eit = simple_graph.FindEdge(1, 3);
|
||||
BOOST_CHECK(eit != SPECIAL_EDGEID);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 1);
|
||||
|
||||
eit = simple_graph.FindEdge(3, 1);
|
||||
BOOST_CHECK_EQUAL(eit, SPECIAL_EDGEID);
|
||||
|
||||
eit = simple_graph.FindEdgeInEitherDirection(3, 1);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 1);
|
||||
|
||||
bool reverse = false;
|
||||
eit = simple_graph.FindEdgeIndicateIfReverse(3, 1, reverse);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 1);
|
||||
BOOST_CHECK(reverse);
|
||||
|
||||
eit = simple_graph.FindEdge(0, 3);
|
||||
BOOST_CHECK_EQUAL(eit, SPECIAL_EDGEID);
|
||||
eit = simple_graph.FindEdge(1, 2);
|
||||
BOOST_CHECK_EQUAL(eit, SPECIAL_EDGEID);
|
||||
|
||||
eit = simple_graph.FindEdge(0, 2);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 3);
|
||||
eit = simple_graph.FindEdgeInEitherDirection(0, 2);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 3);
|
||||
|
||||
eit = simple_graph.FindEdge(0, 1);
|
||||
BOOST_CHECK_EQUAL(simple_graph.GetEdgeData(eit).id, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
Reference in New Issue
Block a user