Replace deallocation vector with std::vector and different merge algorithm
This commit is contained in:
parent
69db219423
commit
9b87b8b7b1
@ -2,9 +2,17 @@
|
||||
#define OSRM_CONTRACTOR_CONTRACTED_EDGE_CONTAINER_HPP
|
||||
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "util/deallocating_vector.hpp"
|
||||
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/permutation.hpp"
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -43,7 +51,7 @@ struct ContractedEdgeContainer
|
||||
}
|
||||
|
||||
public:
|
||||
void Insert(util::DeallocatingVector<QueryEdge> new_edges)
|
||||
void Insert(std::vector<QueryEdge> new_edges)
|
||||
{
|
||||
BOOST_ASSERT(edges.size() == 0);
|
||||
BOOST_ASSERT(flags.empty());
|
||||
@ -52,80 +60,68 @@ struct ContractedEdgeContainer
|
||||
flags.resize(edges.size(), ALL_FLAGS);
|
||||
}
|
||||
|
||||
void Merge(util::DeallocatingVector<QueryEdge> new_edges)
|
||||
void Merge(std::vector<QueryEdge> new_edges)
|
||||
{
|
||||
BOOST_ASSERT(index < sizeof(MergedFlags) * CHAR_BIT);
|
||||
|
||||
const MergedFlags flag = 1 << index++;
|
||||
|
||||
std::vector<MergedFlags> merged_flags;
|
||||
merged_flags.reserve(flags.size() * 1.1);
|
||||
util::DeallocatingVector<QueryEdge> merged_edges;
|
||||
merged_edges.reserve(edges.size() * 1.1);
|
||||
|
||||
auto edge_iter = edges.cbegin();
|
||||
auto edge_end = edges.cend();
|
||||
auto flags_iter = flags.begin();
|
||||
// destructive iterators, this is single-pass only
|
||||
// FIXME using dbegin() dend() will result in segfaults.
|
||||
auto edges_iter = edges.dbegin();
|
||||
auto edges_end = edges.dend();
|
||||
auto new_edges_iter = new_edges.dbegin();
|
||||
auto new_edges_end = new_edges.dend();
|
||||
|
||||
while (edges_iter != edges_end && new_edges_iter != new_edges_end)
|
||||
{
|
||||
while (edges_iter != edges_end && mergeCompare(*edges_iter, *new_edges_iter))
|
||||
// Remove all edges that are contained in the old set of edges and set the appropriate flag.
|
||||
auto new_end = std::remove_if(new_edges.begin(), new_edges.end(), [&](const auto &edge) {
|
||||
// check if the new edge would be sorted before the currend old edge
|
||||
// if so it is not contained yet in the set of old edges
|
||||
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
|
||||
{
|
||||
merged_edges.push_back(*edges_iter);
|
||||
merged_flags.push_back(*flags_iter);
|
||||
edges_iter++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// find the first old edge that is equal or greater then the new edge
|
||||
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
|
||||
{
|
||||
BOOST_ASSERT(flags_iter != flags.end());
|
||||
edge_iter++;
|
||||
flags_iter++;
|
||||
}
|
||||
|
||||
if (edges_iter == edges_end)
|
||||
// all new edges will be sorted after the old edges
|
||||
if (edge_iter == edge_end)
|
||||
{
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (new_edges_iter != new_edges_end && mergeCompare(*new_edges_iter, *edges_iter))
|
||||
BOOST_ASSERT(edge_iter != edge_end);
|
||||
if (mergable(edge, *edge_iter))
|
||||
{
|
||||
merged_edges.push_back(*new_edges_iter);
|
||||
merged_flags.push_back(flag);
|
||||
new_edges_iter++;
|
||||
*flags_iter = *flags_iter | flag;
|
||||
return true;
|
||||
}
|
||||
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
|
||||
return false;
|
||||
});
|
||||
|
||||
if (new_edges_iter == new_edges_end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// append new edges
|
||||
edges.insert(edges.end(), new_edges.begin(), new_end);
|
||||
auto edges_size = edges.size();
|
||||
auto new_edges_size = std::distance(new_edges.begin(), new_end);
|
||||
BOOST_ASSERT(edges_size >= new_edges_size);
|
||||
flags.resize(edges_size);
|
||||
std::fill(flags.begin() + edges_size - new_edges_size, flags.end(), flag);
|
||||
|
||||
while (edges_iter != edges_end && new_edges_iter != new_edges_end &&
|
||||
mergable(*edges_iter, *new_edges_iter))
|
||||
{
|
||||
merged_edges.push_back(*edges_iter);
|
||||
merged_flags.push_back(*flags_iter | flag);
|
||||
// enforce sorting for next merge step
|
||||
std::vector<unsigned> ordering(edges_size);
|
||||
std::iota(ordering.begin(), ordering.end(), 0);
|
||||
tbb::parallel_sort(ordering.begin(), ordering.end(), [&](const auto lhs_idx, const auto rhs_idx) {
|
||||
return mergeCompare(edges[lhs_idx], edges[rhs_idx]);
|
||||
});
|
||||
auto permutation = util::orderingToPermutation(ordering);
|
||||
|
||||
edges_iter++;
|
||||
flags_iter++;
|
||||
new_edges_iter++;
|
||||
}
|
||||
}
|
||||
|
||||
while (edges_iter != edges_end)
|
||||
{
|
||||
BOOST_ASSERT(new_edges_iter == new_edges_end);
|
||||
merged_edges.push_back(*edges_iter++);
|
||||
merged_flags.push_back(*flags_iter++);
|
||||
}
|
||||
|
||||
while (new_edges_iter != new_edges_end)
|
||||
{
|
||||
BOOST_ASSERT(edges_iter == edges_end);
|
||||
merged_edges.push_back(*new_edges_iter++);
|
||||
merged_flags.push_back(flag);
|
||||
}
|
||||
|
||||
flags = std::move(merged_flags);
|
||||
edges = std::move(merged_edges);
|
||||
util::inplacePermutation(edges.begin(), edges.end(), permutation);
|
||||
util::inplacePermutation(flags.begin(), flags.end(), permutation);
|
||||
BOOST_ASSERT(std::is_sorted(edges.begin(), edges.end(), mergeCompare));
|
||||
}
|
||||
|
||||
auto MakeEdgeFilters() const
|
||||
@ -145,7 +141,7 @@ struct ContractedEdgeContainer
|
||||
|
||||
std::size_t index = 0;
|
||||
std::vector<MergedFlags> flags;
|
||||
util::DeallocatingVector<QueryEdge> edges;
|
||||
std::vector<QueryEdge> edges;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define OSRM_CONTRACTOR_GRAPH_CONTRACTION_ADAPTORS_HPP_
|
||||
|
||||
#include "contractor/contractor_graph.hpp"
|
||||
|
||||
#include "util/log.hpp"
|
||||
#include "util/percent.hpp"
|
||||
|
||||
@ -125,9 +126,10 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
||||
return ContractorGraph{number_of_nodes, edges};
|
||||
}
|
||||
|
||||
template <class Edge, typename GraphT> inline util::DeallocatingVector<Edge> toEdges(GraphT graph)
|
||||
template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT graph)
|
||||
{
|
||||
util::DeallocatingVector<Edge> edges;
|
||||
std::vector<Edge> edges;
|
||||
edges.reserve(graph.GetNumberOfEdges());
|
||||
|
||||
util::UnbufferedLog log;
|
||||
log << "Getting edges of minimized graph ";
|
||||
@ -163,6 +165,7 @@ template <class Edge, typename GraphT> inline util::DeallocatingVector<Edge> toE
|
||||
tbb::parallel_sort(edges.begin(), edges.end());
|
||||
auto new_end = std::unique(edges.begin(), edges.end());
|
||||
edges.resize(new_end - edges.begin());
|
||||
edges.shrink_to_fit();
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
@ -23,7 +23,15 @@ void inplacePermutation(RandomAccesIterator begin,
|
||||
for (auto index : util::irange<IndexT>(0, size))
|
||||
{
|
||||
if (was_replaced[index])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (old_to_new[index] == index)
|
||||
{
|
||||
was_replaced[index] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// iterate over a cycle in the permutation
|
||||
auto buffer = begin[index];
|
||||
@ -38,6 +46,18 @@ void inplacePermutation(RandomAccesIterator begin,
|
||||
std::swap(buffer, begin[index]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename IndexT>
|
||||
std::vector<IndexT> orderingToPermutation(const std::vector<IndexT> &ordering)
|
||||
{
|
||||
std::vector<std::uint32_t> permutation(ordering.size());
|
||||
for (auto index : util::irange<std::uint32_t>(0, ordering.size()))
|
||||
permutation[ordering[index]] = index;
|
||||
|
||||
return permutation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "partition/renumber.hpp"
|
||||
|
||||
#include "util/permutation.hpp"
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
namespace osrm
|
||||
@ -64,11 +66,7 @@ std::vector<std::uint32_t> makePermutation(const DynamicEdgeBasedGraph &graph,
|
||||
return border_level[lhs] > border_level[rhs];
|
||||
});
|
||||
|
||||
std::vector<std::uint32_t> permutation(ordering.size());
|
||||
for (auto index : util::irange<std::uint32_t>(0, ordering.size()))
|
||||
permutation[ordering[index]] = index;
|
||||
|
||||
return permutation;
|
||||
return util::orderingToPermutation(ordering);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
|
||||
{
|
||||
ContractedEdgeContainer container;
|
||||
|
||||
util::DeallocatingVector<QueryEdge> edges;
|
||||
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}});
|
||||
@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
|
||||
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
||||
container.Merge(edges);
|
||||
|
||||
util::DeallocatingVector<QueryEdge> reference_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}});
|
||||
@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
|
||||
{
|
||||
ContractedEdgeContainer container;
|
||||
|
||||
util::DeallocatingVector<QueryEdge> edges;
|
||||
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}});
|
||||
@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
|
||||
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
||||
container.Merge(edges);
|
||||
|
||||
util::DeallocatingVector<QueryEdge> reference_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}});
|
||||
|
Loading…
Reference in New Issue
Block a user