Skip to content

Commit 9b87b8b

Browse files
TheMarexPatrick Niklaus
authored andcommitted
Replace deallocation vector with std::vector and different merge algorithm
1 parent 69db219 commit 9b87b8b

File tree

5 files changed

+87
-70
lines changed

5 files changed

+87
-70
lines changed

include/contractor/contracted_edge_container.hpp

Lines changed: 55 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22
#define OSRM_CONTRACTOR_CONTRACTED_EDGE_CONTAINER_HPP
33

44
#include "contractor/query_edge.hpp"
5-
#include "util/deallocating_vector.hpp"
65

6+
#include "util/integer_range.hpp"
7+
#include "util/permutation.hpp"
8+
9+
#include <tbb/parallel_sort.h>
10+
11+
#include <algorithm>
712
#include <climits>
13+
#include <cstdint>
14+
#include <numeric>
15+
#include <vector>
816

917
namespace osrm
1018
{
@@ -43,7 +51,7 @@ struct ContractedEdgeContainer
4351
}
4452

4553
public:
46-
void Insert(util::DeallocatingVector<QueryEdge> new_edges)
54+
void Insert(std::vector<QueryEdge> new_edges)
4755
{
4856
BOOST_ASSERT(edges.size() == 0);
4957
BOOST_ASSERT(flags.empty());
@@ -52,80 +60,68 @@ struct ContractedEdgeContainer
5260
flags.resize(edges.size(), ALL_FLAGS);
5361
}
5462

55-
void Merge(util::DeallocatingVector<QueryEdge> new_edges)
63+
void Merge(std::vector<QueryEdge> new_edges)
5664
{
5765
BOOST_ASSERT(index < sizeof(MergedFlags) * CHAR_BIT);
5866

5967
const MergedFlags flag = 1 << index++;
6068

61-
std::vector<MergedFlags> merged_flags;
62-
merged_flags.reserve(flags.size() * 1.1);
63-
util::DeallocatingVector<QueryEdge> merged_edges;
64-
merged_edges.reserve(edges.size() * 1.1);
65-
69+
auto edge_iter = edges.cbegin();
70+
auto edge_end = edges.cend();
6671
auto flags_iter = flags.begin();
67-
// destructive iterators, this is single-pass only
68-
// FIXME using dbegin() dend() will result in segfaults.
69-
auto edges_iter = edges.dbegin();
70-
auto edges_end = edges.dend();
71-
auto new_edges_iter = new_edges.dbegin();
72-
auto new_edges_end = new_edges.dend();
73-
74-
while (edges_iter != edges_end && new_edges_iter != new_edges_end)
75-
{
76-
while (edges_iter != edges_end && mergeCompare(*edges_iter, *new_edges_iter))
77-
{
78-
merged_edges.push_back(*edges_iter);
79-
merged_flags.push_back(*flags_iter);
80-
edges_iter++;
81-
flags_iter++;
82-
}
8372

84-
if (edges_iter == edges_end)
73+
// Remove all edges that are contained in the old set of edges and set the appropriate flag.
74+
auto new_end = std::remove_if(new_edges.begin(), new_edges.end(), [&](const auto &edge) {
75+
// check if the new edge would be sorted before the currend old edge
76+
// if so it is not contained yet in the set of old edges
77+
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
8578
{
86-
break;
79+
return false;
8780
}
8881

89-
while (new_edges_iter != new_edges_end && mergeCompare(*new_edges_iter, *edges_iter))
82+
// find the first old edge that is equal or greater then the new edge
83+
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
9084
{
91-
merged_edges.push_back(*new_edges_iter);
92-
merged_flags.push_back(flag);
93-
new_edges_iter++;
85+
BOOST_ASSERT(flags_iter != flags.end());
86+
edge_iter++;
87+
flags_iter++;
9488
}
9589

96-
if (new_edges_iter == new_edges_end)
90+
// all new edges will be sorted after the old edges
91+
if (edge_iter == edge_end)
9792
{
98-
break;
93+
return false;
9994
}
10095

101-
while (edges_iter != edges_end && new_edges_iter != new_edges_end &&
102-
mergable(*edges_iter, *new_edges_iter))
96+
BOOST_ASSERT(edge_iter != edge_end);
97+
if (mergable(edge, *edge_iter))
10398
{
104-
merged_edges.push_back(*edges_iter);
105-
merged_flags.push_back(*flags_iter | flag);
106-
107-
edges_iter++;
108-
flags_iter++;
109-
new_edges_iter++;
99+
*flags_iter = *flags_iter | flag;
100+
return true;
110101
}
111-
}
112-
113-
while (edges_iter != edges_end)
114-
{
115-
BOOST_ASSERT(new_edges_iter == new_edges_end);
116-
merged_edges.push_back(*edges_iter++);
117-
merged_flags.push_back(*flags_iter++);
118-
}
119-
120-
while (new_edges_iter != new_edges_end)
121-
{
122-
BOOST_ASSERT(edges_iter == edges_end);
123-
merged_edges.push_back(*new_edges_iter++);
124-
merged_flags.push_back(flag);
125-
}
126-
127-
flags = std::move(merged_flags);
128-
edges = std::move(merged_edges);
102+
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
103+
return false;
104+
});
105+
106+
// append new edges
107+
edges.insert(edges.end(), new_edges.begin(), new_end);
108+
auto edges_size = edges.size();
109+
auto new_edges_size = std::distance(new_edges.begin(), new_end);
110+
BOOST_ASSERT(edges_size >= new_edges_size);
111+
flags.resize(edges_size);
112+
std::fill(flags.begin() + edges_size - new_edges_size, flags.end(), flag);
113+
114+
// enforce sorting for next merge step
115+
std::vector<unsigned> ordering(edges_size);
116+
std::iota(ordering.begin(), ordering.end(), 0);
117+
tbb::parallel_sort(ordering.begin(), ordering.end(), [&](const auto lhs_idx, const auto rhs_idx) {
118+
return mergeCompare(edges[lhs_idx], edges[rhs_idx]);
119+
});
120+
auto permutation = util::orderingToPermutation(ordering);
121+
122+
util::inplacePermutation(edges.begin(), edges.end(), permutation);
123+
util::inplacePermutation(flags.begin(), flags.end(), permutation);
124+
BOOST_ASSERT(std::is_sorted(edges.begin(), edges.end(), mergeCompare));
129125
}
130126

131127
auto MakeEdgeFilters() const
@@ -145,7 +141,7 @@ struct ContractedEdgeContainer
145141

146142
std::size_t index = 0;
147143
std::vector<MergedFlags> flags;
148-
util::DeallocatingVector<QueryEdge> edges;
144+
std::vector<QueryEdge> edges;
149145
};
150146
}
151147
}

include/contractor/graph_contractor_adaptors.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define OSRM_CONTRACTOR_GRAPH_CONTRACTION_ADAPTORS_HPP_
33

44
#include "contractor/contractor_graph.hpp"
5+
56
#include "util/log.hpp"
67
#include "util/percent.hpp"
78

@@ -125,9 +126,10 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
125126
return ContractorGraph{number_of_nodes, edges};
126127
}
127128

128-
template <class Edge, typename GraphT> inline util::DeallocatingVector<Edge> toEdges(GraphT graph)
129+
template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT graph)
129130
{
130-
util::DeallocatingVector<Edge> edges;
131+
std::vector<Edge> edges;
132+
edges.reserve(graph.GetNumberOfEdges());
131133

132134
util::UnbufferedLog log;
133135
log << "Getting edges of minimized graph ";
@@ -163,6 +165,7 @@ template <class Edge, typename GraphT> inline util::DeallocatingVector<Edge> toE
163165
tbb::parallel_sort(edges.begin(), edges.end());
164166
auto new_end = std::unique(edges.begin(), edges.end());
165167
edges.resize(new_end - edges.begin());
168+
edges.shrink_to_fit();
166169

167170
return edges;
168171
}

include/util/permutation.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@ void inplacePermutation(RandomAccesIterator begin,
2323
for (auto index : util::irange<IndexT>(0, size))
2424
{
2525
if (was_replaced[index])
26+
{
27+
continue;
28+
}
29+
30+
if (old_to_new[index] == index)
31+
{
32+
was_replaced[index] = true;
2633
continue;
34+
}
2735

2836
// iterate over a cycle in the permutation
2937
auto buffer = begin[index];
@@ -38,6 +46,18 @@ void inplacePermutation(RandomAccesIterator begin,
3846
std::swap(buffer, begin[index]);
3947
}
4048
}
49+
50+
template <typename IndexT>
51+
std::vector<IndexT> orderingToPermutation(const std::vector<IndexT> &ordering)
52+
{
53+
std::vector<std::uint32_t> permutation(ordering.size());
54+
for (auto index : util::irange<std::uint32_t>(0, ordering.size()))
55+
permutation[ordering[index]] = index;
56+
57+
return permutation;
58+
}
59+
60+
4161
}
4262
}
4363

src/partition/renumber.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "partition/renumber.hpp"
22

3+
#include "util/permutation.hpp"
4+
35
#include <tbb/parallel_sort.h>
46

57
namespace osrm
@@ -64,11 +66,7 @@ std::vector<std::uint32_t> makePermutation(const DynamicEdgeBasedGraph &graph,
6466
return border_level[lhs] > border_level[rhs];
6567
});
6668

67-
std::vector<std::uint32_t> permutation(ordering.size());
68-
for (auto index : util::irange<std::uint32_t>(0, ordering.size()))
69-
permutation[ordering[index]] = index;
70-
71-
return permutation;
69+
return util::orderingToPermutation(ordering);
7270
}
7371
}
7472
}

unit_tests/contractor/contracted_edge_container.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
3535
{
3636
ContractedEdgeContainer container;
3737

38-
util::DeallocatingVector<QueryEdge> edges;
38+
std::vector<QueryEdge> edges;
3939
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
4040
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
4141
edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
5353
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
5454
container.Merge(edges);
5555

56-
util::DeallocatingVector<QueryEdge> reference_edges;
56+
std::vector<QueryEdge> reference_edges;
5757
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
5858
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
5959
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
@@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
7777
{
7878
ContractedEdgeContainer container;
7979

80-
util::DeallocatingVector<QueryEdge> edges;
80+
std::vector<QueryEdge> edges;
8181
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
8282
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
8383
edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
@@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
8888
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
8989
container.Merge(edges);
9090

91-
util::DeallocatingVector<QueryEdge> reference_edges;
91+
std::vector<QueryEdge> reference_edges;
9292
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
9393
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
9494
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});

0 commit comments

Comments
 (0)