Add edge-based graph loading in MLD facade
This commit is contained in:
parent
53b0417e36
commit
f42136637d
@ -22,33 +22,33 @@ std::vector<ContractorEdge> adaptToContractorInput(InputEdgeContainer input_edge
|
|||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
const unsigned int constexpr DAY_IN_DECI_SECONDS = 24 * 60 * 60 * 10;
|
const unsigned int constexpr DAY_IN_DECI_SECONDS = 24 * 60 * 60 * 10;
|
||||||
if (static_cast<unsigned int>(std::max(input_edge.weight, 1)) > DAY_IN_DECI_SECONDS)
|
if (static_cast<unsigned int>(std::max(input_edge.data.weight, 1)) > DAY_IN_DECI_SECONDS)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Edge weight large -> "
|
util::Log(logWARNING) << "Edge weight large -> "
|
||||||
<< static_cast<unsigned int>(std::max(input_edge.weight, 1))
|
<< static_cast<unsigned int>(std::max(input_edge.data.weight, 1))
|
||||||
<< " : " << static_cast<unsigned int>(input_edge.source) << " -> "
|
<< " : " << static_cast<unsigned int>(input_edge.source) << " -> "
|
||||||
<< static_cast<unsigned int>(input_edge.target);
|
<< static_cast<unsigned int>(input_edge.target);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
edges.emplace_back(input_edge.source,
|
edges.emplace_back(input_edge.source,
|
||||||
input_edge.target,
|
input_edge.target,
|
||||||
std::max(input_edge.weight, 1),
|
std::max(input_edge.data.weight, 1),
|
||||||
input_edge.duration,
|
input_edge.data.duration,
|
||||||
1,
|
1,
|
||||||
input_edge.edge_id,
|
input_edge.data.edge_id,
|
||||||
false,
|
false,
|
||||||
input_edge.forward ? true : false,
|
input_edge.data.forward ? true : false,
|
||||||
input_edge.backward ? true : false);
|
input_edge.data.backward ? true : false);
|
||||||
|
|
||||||
edges.emplace_back(input_edge.target,
|
edges.emplace_back(input_edge.target,
|
||||||
input_edge.source,
|
input_edge.source,
|
||||||
std::max(input_edge.weight, 1),
|
std::max(input_edge.data.weight, 1),
|
||||||
input_edge.duration,
|
input_edge.data.duration,
|
||||||
1,
|
1,
|
||||||
input_edge.edge_id,
|
input_edge.data.edge_id,
|
||||||
false,
|
false,
|
||||||
input_edge.backward ? true : false,
|
input_edge.data.backward ? true : false,
|
||||||
input_edge.forward ? true : false);
|
input_edge.data.forward ? true : false);
|
||||||
}
|
}
|
||||||
// FIXME not sure if we need this
|
// FIXME not sure if we need this
|
||||||
edges.shrink_to_fit();
|
edges.shrink_to_fit();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define OSRM_ENGINE_DATAFACADE_ALGORITHM_DATAFACADE_HPP
|
#define OSRM_ENGINE_DATAFACADE_ALGORITHM_DATAFACADE_HPP
|
||||||
|
|
||||||
#include "contractor/query_edge.hpp"
|
#include "contractor/query_edge.hpp"
|
||||||
|
#include "extractor/edge_based_edge.hpp"
|
||||||
#include "engine/algorithm.hpp"
|
#include "engine/algorithm.hpp"
|
||||||
|
|
||||||
#include "partition/cell_storage.hpp"
|
#include "partition/cell_storage.hpp"
|
||||||
@ -66,6 +67,25 @@ template <> class AlgorithmDataFacade<algorithm::CoreCH>
|
|||||||
template <> class AlgorithmDataFacade<algorithm::MLD>
|
template <> class AlgorithmDataFacade<algorithm::MLD>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using EdgeData = extractor::EdgeBasedEdge::EdgeData;
|
||||||
|
|
||||||
|
// search graph access
|
||||||
|
virtual unsigned GetNumberOfNodes() const = 0;
|
||||||
|
|
||||||
|
virtual unsigned GetNumberOfEdges() const = 0;
|
||||||
|
|
||||||
|
virtual unsigned GetOutDegree(const NodeID n) const = 0;
|
||||||
|
|
||||||
|
virtual NodeID GetTarget(const EdgeID e) const = 0;
|
||||||
|
|
||||||
|
virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0;
|
||||||
|
|
||||||
|
virtual EdgeID BeginEdges(const NodeID n) const = 0;
|
||||||
|
|
||||||
|
virtual EdgeID EndEdges(const NodeID n) const = 0;
|
||||||
|
|
||||||
|
virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0;
|
||||||
|
|
||||||
virtual const partition::MultiLevelPartitionView &GetMultiLevelPartition() const = 0;
|
virtual const partition::MultiLevelPartitionView &GetMultiLevelPartition() const = 0;
|
||||||
|
|
||||||
virtual const partition::CellStorageView &GetCellStorage() const = 0;
|
virtual const partition::CellStorageView &GetCellStorage() const = 0;
|
||||||
|
@ -1200,12 +1200,67 @@ class ContiguousInternalMemoryDataFacade<algorithm::MLD>
|
|||||||
: public ContiguousInternalMemoryDataFacadeBase,
|
: public ContiguousInternalMemoryDataFacadeBase,
|
||||||
public ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
|
public ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
using QueryGraph = util::StaticGraph<EdgeData, true>;
|
||||||
|
using GraphNode = QueryGraph::NodeArrayEntry;
|
||||||
|
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
||||||
|
|
||||||
|
std::unique_ptr<QueryGraph> m_query_graph;
|
||||||
|
|
||||||
|
void InitializeGraphPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||||
|
{
|
||||||
|
auto graph_nodes_ptr = data_layout.GetBlockPtr<GraphNode>(
|
||||||
|
memory_block, storage::DataLayout::MLD_GRAPH_NODE_LIST);
|
||||||
|
|
||||||
|
auto graph_edges_ptr = data_layout.GetBlockPtr<GraphEdge>(
|
||||||
|
memory_block, storage::DataLayout::MLD_GRAPH_EDGE_LIST);
|
||||||
|
|
||||||
|
util::ShM<GraphNode, true>::vector node_list(
|
||||||
|
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_LIST]);
|
||||||
|
util::ShM<GraphEdge, true>::vector edge_list(
|
||||||
|
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_EDGE_LIST]);
|
||||||
|
|
||||||
|
m_query_graph.reset(new QueryGraph(node_list, edge_list));
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
|
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
|
||||||
: ContiguousInternalMemoryDataFacadeBase(allocator),
|
: ContiguousInternalMemoryDataFacadeBase(allocator),
|
||||||
ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>(allocator)
|
ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>(allocator)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
|
||||||
|
{
|
||||||
|
InitializeGraphPointer(data_layout, memory_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
// search graph access
|
||||||
|
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }
|
||||||
|
|
||||||
|
unsigned GetNumberOfEdges() const override final { return m_query_graph->GetNumberOfEdges(); }
|
||||||
|
|
||||||
|
unsigned GetOutDegree(const NodeID n) const override final
|
||||||
|
{
|
||||||
|
return m_query_graph->GetOutDegree(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeID GetTarget(const EdgeID e) const override final { return m_query_graph->GetTarget(e); }
|
||||||
|
|
||||||
|
EdgeData &GetEdgeData(const EdgeID e) const override final
|
||||||
|
{
|
||||||
|
return m_query_graph->GetEdgeData(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeID BeginEdges(const NodeID n) const override final { return m_query_graph->BeginEdges(n); }
|
||||||
|
|
||||||
|
EdgeID EndEdges(const NodeID n) const override final { return m_query_graph->EndEdges(n); }
|
||||||
|
|
||||||
|
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
|
||||||
|
{
|
||||||
|
return m_query_graph->GetAdjacentEdgeRange(node);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,29 @@ struct EdgeBasedEdge
|
|||||||
|
|
||||||
NodeID source;
|
NodeID source;
|
||||||
NodeID target;
|
NodeID target;
|
||||||
NodeID edge_id;
|
|
||||||
EdgeWeight weight;
|
struct EdgeData
|
||||||
EdgeWeight duration : 30;
|
{
|
||||||
std::uint32_t forward : 1;
|
EdgeData() : edge_id(0), weight(0), duration(0), forward(false), backward(false) {}
|
||||||
std::uint32_t backward : 1;
|
|
||||||
|
EdgeData(const NodeID edge_id,
|
||||||
|
const EdgeWeight weight,
|
||||||
|
const EdgeWeight duration,
|
||||||
|
const bool forward,
|
||||||
|
const bool backward)
|
||||||
|
: edge_id(edge_id), weight(weight), duration(duration), forward(forward),
|
||||||
|
backward(backward)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeID edge_id;
|
||||||
|
EdgeWeight weight;
|
||||||
|
EdgeWeight duration : 30;
|
||||||
|
std::uint32_t forward : 1;
|
||||||
|
std::uint32_t backward : 1;
|
||||||
|
|
||||||
|
auto is_unidirectional() const { return !forward || !backward; }
|
||||||
|
} data;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(extractor::EdgeBasedEdge) == 20,
|
static_assert(sizeof(extractor::EdgeBasedEdge) == 20,
|
||||||
"Size of extractor::EdgeBasedEdge type is "
|
"Size of extractor::EdgeBasedEdge type is "
|
||||||
@ -42,10 +60,7 @@ static_assert(sizeof(extractor::EdgeBasedEdge) == 20,
|
|||||||
|
|
||||||
// Impl.
|
// Impl.
|
||||||
|
|
||||||
inline EdgeBasedEdge::EdgeBasedEdge()
|
inline EdgeBasedEdge::EdgeBasedEdge() : source(0), target(0) {}
|
||||||
: source(0), target(0), edge_id(0), weight(0), duration(0), forward(false), backward(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
||||||
const NodeID target,
|
const NodeID target,
|
||||||
@ -54,19 +69,18 @@ inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
|||||||
const EdgeWeight duration,
|
const EdgeWeight duration,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward)
|
const bool backward)
|
||||||
: source(source), target(target), edge_id(edge_id), weight(weight), duration(duration),
|
: source(source), target(target), data{edge_id, weight, duration, forward, backward}
|
||||||
forward(forward), backward(backward)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
|
inline bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
|
||||||
{
|
{
|
||||||
const auto unidirectional = (!forward || !backward);
|
const auto unidirectional = data.is_unidirectional();
|
||||||
const auto other_is_unidirectional = (!other.forward || !other.backward);
|
const auto other_is_unidirectional = other.data.is_unidirectional();
|
||||||
// if all items are the same, we want to keep bidirectional edges. due to the `<` operator,
|
// if all items are the same, we want to keep bidirectional edges. due to the `<` operator,
|
||||||
// preferring 0 (false) over 1 (true), we need to compare the inverse of `bidirectional`
|
// preferring 0 (false) over 1 (true), we need to compare the inverse of `bidirectional`
|
||||||
return std::tie(source, target, weight, unidirectional) <
|
return std::tie(source, target, data.weight, unidirectional) <
|
||||||
std::tie(other.source, other.target, other.weight, other_is_unidirectional);
|
std::tie(other.source, other.target, other.data.weight, other_is_unidirectional);
|
||||||
}
|
}
|
||||||
} // ns extractor
|
} // ns extractor
|
||||||
} // ns osrm
|
} // ns osrm
|
||||||
|
@ -19,7 +19,7 @@ namespace osrm
|
|||||||
namespace partition
|
namespace partition
|
||||||
{
|
{
|
||||||
|
|
||||||
struct EdgeBasedGraphEdgeData : extractor::EdgeBasedEdge
|
struct EdgeBasedGraphEdgeData : extractor::EdgeBasedEdge::EdgeData
|
||||||
{
|
{
|
||||||
// We need to write out the full edge based graph again.
|
// We need to write out the full edge based graph again.
|
||||||
|
|
||||||
@ -38,6 +38,107 @@ struct EdgeBasedGraphEdge : EdgeBasedGraph::InputEdge
|
|||||||
using Base::Base;
|
using Base::Base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Bidirectional (s,t) to (s,t) and (t,s)
|
||||||
|
std::vector<extractor::EdgeBasedEdge>
|
||||||
|
SplitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
||||||
|
{
|
||||||
|
std::vector<extractor::EdgeBasedEdge> directed;
|
||||||
|
directed.reserve(edges.size() * 2);
|
||||||
|
|
||||||
|
for (const auto &edge : edges)
|
||||||
|
{
|
||||||
|
directed.emplace_back(edge.source,
|
||||||
|
edge.target,
|
||||||
|
edge.data.edge_id,
|
||||||
|
std::max(edge.data.weight, 1),
|
||||||
|
edge.data.duration,
|
||||||
|
edge.data.forward,
|
||||||
|
edge.data.backward);
|
||||||
|
|
||||||
|
directed.emplace_back(edge.target,
|
||||||
|
edge.source,
|
||||||
|
edge.data.edge_id,
|
||||||
|
std::max(edge.data.weight, 1),
|
||||||
|
edge.data.duration,
|
||||||
|
edge.data.backward,
|
||||||
|
edge.data.forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
return directed;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<EdgeBasedGraphEdge>
|
||||||
|
PrepareEdgesForUsageInGraph(std::vector<extractor::EdgeBasedEdge> edges)
|
||||||
|
{
|
||||||
|
std::sort(begin(edges), end(edges));
|
||||||
|
|
||||||
|
std::vector<EdgeBasedGraphEdge> graph_edges;
|
||||||
|
graph_edges.reserve(edges.size());
|
||||||
|
|
||||||
|
for (NodeID i = 0; i < edges.size();)
|
||||||
|
{
|
||||||
|
const NodeID source = edges[i].source;
|
||||||
|
const NodeID target = edges[i].target;
|
||||||
|
|
||||||
|
// remove eigenloops
|
||||||
|
if (source == target)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeBasedGraphEdge forward_edge;
|
||||||
|
EdgeBasedGraphEdge reverse_edge;
|
||||||
|
forward_edge.source = reverse_edge.source = source;
|
||||||
|
forward_edge.target = reverse_edge.target = target;
|
||||||
|
forward_edge.data.edge_id = reverse_edge.data.edge_id = edges[i].data.edge_id;
|
||||||
|
forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT;
|
||||||
|
forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION_INT_30;
|
||||||
|
forward_edge.data.forward = reverse_edge.data.backward = true;
|
||||||
|
forward_edge.data.backward = reverse_edge.data.forward = false;
|
||||||
|
|
||||||
|
// remove parallel edges
|
||||||
|
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
||||||
|
{
|
||||||
|
if (edges[i].data.forward)
|
||||||
|
{
|
||||||
|
forward_edge.data.weight = std::min(edges[i].data.weight, forward_edge.data.weight);
|
||||||
|
forward_edge.data.duration =
|
||||||
|
std::min(edges[i].data.duration, forward_edge.data.duration);
|
||||||
|
}
|
||||||
|
if (edges[i].data.backward)
|
||||||
|
{
|
||||||
|
reverse_edge.data.weight = std::min(edges[i].data.weight, reverse_edge.data.weight);
|
||||||
|
reverse_edge.data.duration =
|
||||||
|
std::min(edges[i].data.duration, reverse_edge.data.duration);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
// merge edges (s,t) and (t,s) into bidirectional edge
|
||||||
|
if (forward_edge.data.weight == reverse_edge.data.weight)
|
||||||
|
{
|
||||||
|
if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
forward_edge.data.backward = true;
|
||||||
|
graph_edges.push_back(forward_edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // insert seperate edges
|
||||||
|
if (((int)forward_edge.data.weight) != INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
graph_edges.push_back(forward_edge);
|
||||||
|
}
|
||||||
|
if ((int)reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
graph_edges.push_back(reverse_edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph_edges;
|
||||||
|
}
|
||||||
|
|
||||||
struct EdgeBasedGraphReader
|
struct EdgeBasedGraphReader
|
||||||
{
|
{
|
||||||
EdgeBasedGraphReader(storage::io::FileReader &reader)
|
EdgeBasedGraphReader(storage::io::FileReader &reader)
|
||||||
@ -74,107 +175,6 @@ struct EdgeBasedGraphReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Bidirectional (s,t) to (s,t) and (t,s)
|
|
||||||
std::vector<extractor::EdgeBasedEdge>
|
|
||||||
SplitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
|
||||||
{
|
|
||||||
std::vector<extractor::EdgeBasedEdge> directed;
|
|
||||||
directed.reserve(edges.size() * 2);
|
|
||||||
|
|
||||||
for (const auto &edge : edges)
|
|
||||||
{
|
|
||||||
directed.emplace_back(edge.source,
|
|
||||||
edge.target,
|
|
||||||
edge.edge_id,
|
|
||||||
std::max(edge.weight, 1),
|
|
||||||
edge.duration,
|
|
||||||
edge.forward,
|
|
||||||
edge.backward);
|
|
||||||
|
|
||||||
directed.emplace_back(edge.target,
|
|
||||||
edge.source,
|
|
||||||
edge.edge_id,
|
|
||||||
std::max(edge.weight, 1),
|
|
||||||
edge.duration,
|
|
||||||
edge.backward,
|
|
||||||
edge.forward);
|
|
||||||
}
|
|
||||||
|
|
||||||
return directed;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<EdgeBasedGraphEdge>
|
|
||||||
PrepareEdgesForUsageInGraph(std::vector<extractor::EdgeBasedEdge> edges)
|
|
||||||
{
|
|
||||||
std::sort(begin(edges), end(edges));
|
|
||||||
|
|
||||||
std::vector<EdgeBasedGraphEdge> graph_edges;
|
|
||||||
graph_edges.reserve(edges.size());
|
|
||||||
|
|
||||||
for (NodeID i = 0; i < edges.size();)
|
|
||||||
{
|
|
||||||
const NodeID source = edges[i].source;
|
|
||||||
const NodeID target = edges[i].target;
|
|
||||||
|
|
||||||
// remove eigenloops
|
|
||||||
if (source == target)
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeBasedGraphEdge forward_edge;
|
|
||||||
EdgeBasedGraphEdge reverse_edge;
|
|
||||||
forward_edge.source = reverse_edge.source = source;
|
|
||||||
forward_edge.target = reverse_edge.target = target;
|
|
||||||
forward_edge.data.edge_id = reverse_edge.data.edge_id = edges[i].edge_id;
|
|
||||||
forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT;
|
|
||||||
forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION_INT_30;
|
|
||||||
forward_edge.data.forward = reverse_edge.data.backward = true;
|
|
||||||
forward_edge.data.backward = reverse_edge.data.forward = false;
|
|
||||||
|
|
||||||
// remove parallel edges
|
|
||||||
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
|
||||||
{
|
|
||||||
if (edges[i].forward)
|
|
||||||
{
|
|
||||||
forward_edge.data.weight = std::min(edges[i].weight, forward_edge.data.weight);
|
|
||||||
forward_edge.data.duration =
|
|
||||||
std::min(edges[i].duration, forward_edge.data.duration);
|
|
||||||
}
|
|
||||||
if (edges[i].backward)
|
|
||||||
{
|
|
||||||
reverse_edge.data.weight = std::min(edges[i].weight, reverse_edge.data.weight);
|
|
||||||
reverse_edge.data.duration =
|
|
||||||
std::min(edges[i].duration, reverse_edge.data.duration);
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
// merge edges (s,t) and (t,s) into bidirectional edge
|
|
||||||
if (forward_edge.data.weight == reverse_edge.data.weight)
|
|
||||||
{
|
|
||||||
if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT)
|
|
||||||
{
|
|
||||||
forward_edge.data.backward = true;
|
|
||||||
graph_edges.push_back(forward_edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // insert seperate edges
|
|
||||||
if (((int)forward_edge.data.weight) != INVALID_EDGE_WEIGHT)
|
|
||||||
{
|
|
||||||
graph_edges.push_back(forward_edge);
|
|
||||||
}
|
|
||||||
if ((int)reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
|
|
||||||
{
|
|
||||||
graph_edges.push_back(reverse_edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph_edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<extractor::EdgeBasedEdge> edges;
|
std::vector<extractor::EdgeBasedEdge> edges;
|
||||||
std::size_t num_nodes;
|
std::size_t num_nodes;
|
||||||
};
|
};
|
||||||
|
@ -64,7 +64,9 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
|||||||
"MLD_CELL_SOURCE_BOUNDARY",
|
"MLD_CELL_SOURCE_BOUNDARY",
|
||||||
"MLD_CELL_DESTINATION_BOUNDARY",
|
"MLD_CELL_DESTINATION_BOUNDARY",
|
||||||
"MLD_CELLS",
|
"MLD_CELLS",
|
||||||
"MLD_CELL_LEVEL_OFFSETS"};
|
"MLD_CELL_LEVEL_OFFSETS",
|
||||||
|
"MLD_GRAPH_NODE_LIST",
|
||||||
|
"MLD_GRAPH_EDGE_LIST"};
|
||||||
|
|
||||||
struct DataLayout
|
struct DataLayout
|
||||||
{
|
{
|
||||||
@ -117,6 +119,8 @@ struct DataLayout
|
|||||||
MLD_CELL_DESTINATION_BOUNDARY,
|
MLD_CELL_DESTINATION_BOUNDARY,
|
||||||
MLD_CELLS,
|
MLD_CELLS,
|
||||||
MLD_CELL_LEVEL_OFFSETS,
|
MLD_CELL_LEVEL_OFFSETS,
|
||||||
|
MLD_GRAPH_NODE_LIST,
|
||||||
|
MLD_GRAPH_EDGE_LIST,
|
||||||
NUM_BLOCKS
|
NUM_BLOCKS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ struct StorageConfig final
|
|||||||
boost::filesystem::path turn_lane_description_path;
|
boost::filesystem::path turn_lane_description_path;
|
||||||
boost::filesystem::path mld_partition_path;
|
boost::filesystem::path mld_partition_path;
|
||||||
boost::filesystem::path mld_storage_path;
|
boost::filesystem::path mld_storage_path;
|
||||||
|
boost::filesystem::path edge_based_graph_path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,18 @@ template <typename DataT> class SharedMemoryWrapper
|
|||||||
return m_ptr[index];
|
return m_ptr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DataT &front() const {
|
||||||
|
BOOST_ASSERT_MSG(m_size > 0, "invalid size");
|
||||||
|
return m_ptr[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const DataT &back() const {
|
||||||
|
BOOST_ASSERT_MSG(m_size > 0, "invalid size");
|
||||||
|
return m_ptr[m_size - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data() const { return m_ptr; }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
friend void swap(SharedMemoryWrapper<T> &, SharedMemoryWrapper<T> &) noexcept;
|
friend void swap(SharedMemoryWrapper<T> &, SharedMemoryWrapper<T> &) noexcept;
|
||||||
};
|
};
|
||||||
|
@ -134,8 +134,11 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
|
|||||||
StaticGraph(typename ShM<NodeArrayEntry, UseSharedMemory>::vector &nodes,
|
StaticGraph(typename ShM<NodeArrayEntry, UseSharedMemory>::vector &nodes,
|
||||||
typename ShM<EdgeArrayEntry, UseSharedMemory>::vector &edges)
|
typename ShM<EdgeArrayEntry, UseSharedMemory>::vector &edges)
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(!nodes.empty());
|
||||||
|
|
||||||
number_of_nodes = static_cast<decltype(number_of_nodes)>(nodes.size() - 1);
|
number_of_nodes = static_cast<decltype(number_of_nodes)>(nodes.size() - 1);
|
||||||
number_of_edges = static_cast<decltype(number_of_edges)>(edges.size());
|
number_of_edges = static_cast<decltype(number_of_edges)>(nodes.back().first_edge);
|
||||||
|
BOOST_ASSERT(number_of_edges <= edges.size());
|
||||||
|
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(node_array, nodes);
|
swap(node_array, nodes);
|
||||||
|
@ -147,8 +147,8 @@ void CheckWeightsConsistency(
|
|||||||
|
|
||||||
for (auto &edge : edge_based_edge_list)
|
for (auto &edge : edge_based_edge_list)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(edge.edge_id < current_edge_data.size());
|
BOOST_ASSERT(edge.data.edge_id < current_edge_data.size());
|
||||||
auto geometry_id = current_edge_data[edge.edge_id].via_geometry;
|
auto geometry_id = current_edge_data[edge.data.edge_id].via_geometry;
|
||||||
BOOST_ASSERT(geometry_id.id < geometry_indices.size());
|
BOOST_ASSERT(geometry_id.id < geometry_indices.size());
|
||||||
|
|
||||||
const auto &weights = geometry_id.forward ? forward_weight_list : reverse_weight_list;
|
const auto &weights = geometry_id.forward ? forward_weight_list : reverse_weight_list;
|
||||||
@ -157,7 +157,7 @@ void CheckWeightsConsistency(
|
|||||||
const auto last = weights.begin() + geometry_indices.at(geometry_id.id + 1) - 1 + shift;
|
const auto last = weights.begin() + geometry_indices.at(geometry_id.id + 1) - 1 + shift;
|
||||||
EdgeWeight weight = std::accumulate(first, last, 0);
|
EdgeWeight weight = std::accumulate(first, last, 0);
|
||||||
|
|
||||||
BOOST_ASSERT(weight <= edge.weight);
|
BOOST_ASSERT(weight <= edge.data.weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,8 +908,8 @@ Contractor::LoadEdgeExpandedGraph(const ContractorConfig &config,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update edge weight
|
// Update edge weight
|
||||||
inbuffer.weight = new_weight + turn_weight_penalty;
|
inbuffer.data.weight = new_weight + turn_weight_penalty;
|
||||||
inbuffer.duration = new_duration + turn_duration_penalty;
|
inbuffer.data.duration = new_duration + turn_duration_penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
edge_based_edge_list.emplace_back(std::move(inbuffer));
|
edge_based_edge_list.emplace_back(std::move(inbuffer));
|
||||||
|
@ -333,16 +333,16 @@ void Extractor::FindComponents(unsigned max_edge_id,
|
|||||||
|
|
||||||
for (const auto &edge : input_edge_list)
|
for (const auto &edge : input_edge_list)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(edge.weight, 1)) > 0,
|
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(edge.data.weight, 1)) > 0,
|
||||||
"edge distance < 1");
|
"edge distance < 1");
|
||||||
BOOST_ASSERT(edge.source <= max_edge_id);
|
BOOST_ASSERT(edge.source <= max_edge_id);
|
||||||
BOOST_ASSERT(edge.target <= max_edge_id);
|
BOOST_ASSERT(edge.target <= max_edge_id);
|
||||||
if (edge.forward)
|
if (edge.data.forward)
|
||||||
{
|
{
|
||||||
edges.push_back({edge.source, edge.target});
|
edges.push_back({edge.source, edge.target});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (edge.backward)
|
if (edge.data.backward)
|
||||||
{
|
{
|
||||||
edges.push_back({edge.target, edge.source});
|
edges.push_back({edge.target, edge.source});
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,13 @@ int Partitioner::Run(const PartitionConfig &config)
|
|||||||
config.minimum_cell_size * 32 * 16,
|
config.minimum_cell_size * 32 * 16,
|
||||||
config.minimum_cell_size * 32 * 16 * 32});
|
config.minimum_cell_size * 32 * 16 * 32});
|
||||||
|
|
||||||
|
util::Log() << "Edge-based-graph annotation:";
|
||||||
|
for (std::size_t level = 0; level < level_to_num_cells.size(); ++level)
|
||||||
|
{
|
||||||
|
util::Log() << " level " << level + 1 << " #cells " << level_to_num_cells[level]
|
||||||
|
<< " bit size " << std::ceil(std::log2(level_to_num_cells[level] + 1));
|
||||||
|
}
|
||||||
|
|
||||||
TIMER_START(packed_mlp);
|
TIMER_START(packed_mlp);
|
||||||
MultiLevelPartition mlp{partitions, level_to_num_cells};
|
MultiLevelPartition mlp{partitions, level_to_num_cells};
|
||||||
TIMER_STOP(packed_mlp);
|
TIMER_STOP(packed_mlp);
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
#include "storage/storage.hpp"
|
#include "storage/storage.hpp"
|
||||||
#include "contractor/query_edge.hpp"
|
#include "contractor/query_edge.hpp"
|
||||||
#include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
|
#include "extractor/edge_based_edge.hpp"
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
#include "extractor/original_edge_data.hpp"
|
#include "extractor/original_edge_data.hpp"
|
||||||
#include "extractor/profile_properties.hpp"
|
#include "extractor/profile_properties.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
#include "extractor/travel_mode.hpp"
|
#include "extractor/travel_mode.hpp"
|
||||||
#include "partition/cell_storage.hpp"
|
#include "partition/cell_storage.hpp"
|
||||||
|
#include "partition/edge_based_graph_reader.hpp"
|
||||||
#include "partition/multi_level_partition.hpp"
|
#include "partition/multi_level_partition.hpp"
|
||||||
#include "storage/io.hpp"
|
#include "storage/io.hpp"
|
||||||
#include "storage/serialization.hpp"
|
#include "storage/serialization.hpp"
|
||||||
@ -54,6 +56,7 @@ using RTreeLeaf = engine::datafacade::BaseDataFacade::RTreeLeaf;
|
|||||||
using RTreeNode =
|
using RTreeNode =
|
||||||
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, true>::vector, true>::TreeNode;
|
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, true>::vector, true>::TreeNode;
|
||||||
using QueryGraph = util::StaticGraph<contractor::QueryEdge::EdgeData>;
|
using QueryGraph = util::StaticGraph<contractor::QueryEdge::EdgeData>;
|
||||||
|
using EdgeBasedGraph = util::StaticGraph<extractor::EdgeBasedEdge::EdgeData>;
|
||||||
|
|
||||||
using Monitor = SharedMonitor<SharedDataTimestamp>;
|
using Monitor = SharedMonitor<SharedDataTimestamp>;
|
||||||
|
|
||||||
@ -237,6 +240,7 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
layout.SetBlockSize<EntryClassID>(DataLayout::ENTRY_CLASSID, number_of_original_edges);
|
layout.SetBlockSize<EntryClassID>(DataLayout::ENTRY_CLASSID, number_of_original_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (boost::filesystem::exists(config.hsgr_data_path))
|
||||||
{
|
{
|
||||||
io::FileReader hsgr_file(config.hsgr_data_path, io::FileReader::VerifyFingerprint);
|
io::FileReader hsgr_file(config.hsgr_data_path, io::FileReader::VerifyFingerprint);
|
||||||
|
|
||||||
@ -247,6 +251,12 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
layout.SetBlockSize<QueryGraph::EdgeArrayEntry>(DataLayout::CH_GRAPH_EDGE_LIST,
|
layout.SetBlockSize<QueryGraph::EdgeArrayEntry>(DataLayout::CH_GRAPH_EDGE_LIST,
|
||||||
hsgr_header.number_of_edges);
|
hsgr_header.number_of_edges);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.SetBlockSize<unsigned>(DataLayout::HSGR_CHECKSUM, 0);
|
||||||
|
layout.SetBlockSize<QueryGraph::NodeArrayEntry>(DataLayout::CH_GRAPH_NODE_LIST, 0);
|
||||||
|
layout.SetBlockSize<QueryGraph::EdgeArrayEntry>(DataLayout::CH_GRAPH_EDGE_LIST, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// load rsearch tree size
|
// load rsearch tree size
|
||||||
{
|
{
|
||||||
@ -270,11 +280,16 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load core marker size
|
// load core marker size
|
||||||
|
if (boost::filesystem::exists(config.core_data_path))
|
||||||
{
|
{
|
||||||
io::FileReader core_marker_file(config.core_data_path, io::FileReader::HasNoFingerprint);
|
io::FileReader core_marker_file(config.core_data_path, io::FileReader::HasNoFingerprint);
|
||||||
const auto number_of_core_markers = core_marker_file.ReadElementCount32();
|
const auto number_of_core_markers = core_marker_file.ReadElementCount32();
|
||||||
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER, number_of_core_markers);
|
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER, number_of_core_markers);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// load turn weight penalties
|
// load turn weight penalties
|
||||||
{
|
{
|
||||||
@ -326,24 +341,25 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
number_of_compressed_geometries);
|
number_of_compressed_geometries);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load datasource sizes. This file is optional, and it's non-fatal if it doesn't
|
// load datasource sizes. This file is optional, and it's non-fatal if it doesn't exist.
|
||||||
// exist.
|
if (boost::filesystem::exists(config.datasource_indexes_path))
|
||||||
{
|
{
|
||||||
io::FileReader geometry_datasource_file(config.datasource_indexes_path,
|
io::FileReader reader(config.datasource_indexes_path, io::FileReader::HasNoFingerprint);
|
||||||
io::FileReader::HasNoFingerprint);
|
const auto number_of_datasources = reader.ReadElementCount64();
|
||||||
const auto number_of_compressed_datasources = geometry_datasource_file.ReadElementCount64();
|
layout.SetBlockSize<uint8_t>(DataLayout::DATASOURCES_LIST, number_of_datasources);
|
||||||
layout.SetBlockSize<uint8_t>(DataLayout::DATASOURCES_LIST,
|
}
|
||||||
number_of_compressed_datasources);
|
else
|
||||||
|
{
|
||||||
|
layout.SetBlockSize<uint8_t>(DataLayout::DATASOURCES_LIST, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load datasource name sizes. This file is optional, and it's non-fatal if it doesn't
|
// Load datasource name sizes. This file is optional, and it's non-fatal if it doesn't exist
|
||||||
// exist
|
if (boost::filesystem::exists(config.datasource_names_path))
|
||||||
{
|
{
|
||||||
io::FileReader datasource_names_file(config.datasource_names_path,
|
io::FileReader reader(config.datasource_names_path, io::FileReader::HasNoFingerprint);
|
||||||
io::FileReader::HasNoFingerprint);
|
|
||||||
|
|
||||||
const serialization::DatasourceNamesData datasource_names_data =
|
const serialization::DatasourceNamesData datasource_names_data =
|
||||||
serialization::readDatasourceNames(datasource_names_file);
|
serialization::readDatasourceNames(reader);
|
||||||
|
|
||||||
layout.SetBlockSize<char>(DataLayout::DATASOURCE_NAME_DATA,
|
layout.SetBlockSize<char>(DataLayout::DATASOURCE_NAME_DATA,
|
||||||
datasource_names_data.names.size());
|
datasource_names_data.names.size());
|
||||||
@ -352,6 +368,12 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
layout.SetBlockSize<std::size_t>(DataLayout::DATASOURCE_NAME_LENGTHS,
|
layout.SetBlockSize<std::size_t>(DataLayout::DATASOURCE_NAME_LENGTHS,
|
||||||
datasource_names_data.lengths.size());
|
datasource_names_data.lengths.size());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.SetBlockSize<char>(DataLayout::DATASOURCE_NAME_DATA, 0);
|
||||||
|
layout.SetBlockSize<std::size_t>(DataLayout::DATASOURCE_NAME_OFFSETS, 0);
|
||||||
|
layout.SetBlockSize<std::size_t>(DataLayout::DATASOURCE_NAME_LENGTHS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
io::FileReader intersection_file(config.intersection_class_path,
|
io::FileReader intersection_file(config.intersection_class_path,
|
||||||
@ -446,6 +468,25 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
layout.SetBlockSize<char>(DataLayout::MLD_CELLS, 0);
|
layout.SetBlockSize<char>(DataLayout::MLD_CELLS, 0);
|
||||||
layout.SetBlockSize<char>(DataLayout::MLD_CELL_LEVEL_OFFSETS, 0);
|
layout.SetBlockSize<char>(DataLayout::MLD_CELL_LEVEL_OFFSETS, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (boost::filesystem::exists(config.edge_based_graph_path))
|
||||||
|
{
|
||||||
|
io::FileReader ebg_file(config.edge_based_graph_path,
|
||||||
|
io::FileReader::VerifyFingerprint);
|
||||||
|
|
||||||
|
const auto num_edges = ebg_file.ReadElementCount64();
|
||||||
|
const auto num_nodes = ebg_file.ReadOne<EdgeID>() + 1;
|
||||||
|
|
||||||
|
layout.SetBlockSize<EdgeBasedGraph::NodeArrayEntry>(DataLayout::MLD_GRAPH_NODE_LIST,
|
||||||
|
num_nodes + 1);
|
||||||
|
layout.SetBlockSize<EdgeBasedGraph::EdgeArrayEntry>(DataLayout::MLD_GRAPH_EDGE_LIST,
|
||||||
|
2 * num_edges);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.SetBlockSize<char>(DataLayout::MLD_GRAPH_NODE_LIST, 0);
|
||||||
|
layout.SetBlockSize<char>(DataLayout::MLD_GRAPH_EDGE_LIST, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,6 +497,7 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
// read actual data into shared memory object //
|
// read actual data into shared memory object //
|
||||||
|
|
||||||
// Load the HSGR file
|
// Load the HSGR file
|
||||||
|
if (boost::filesystem::exists(config.hsgr_data_path))
|
||||||
{
|
{
|
||||||
io::FileReader hsgr_file(config.hsgr_data_path, io::FileReader::VerifyFingerprint);
|
io::FileReader hsgr_file(config.hsgr_data_path, io::FileReader::VerifyFingerprint);
|
||||||
auto hsgr_header = serialization::readHSGRHeader(hsgr_file);
|
auto hsgr_header = serialization::readHSGRHeader(hsgr_file);
|
||||||
@ -479,6 +521,14 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
graph_edge_list_ptr,
|
graph_edge_list_ptr,
|
||||||
hsgr_header.number_of_edges);
|
hsgr_header.number_of_edges);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.GetBlockPtr<unsigned, true>(memory_ptr, DataLayout::HSGR_CHECKSUM);
|
||||||
|
layout.GetBlockPtr<QueryGraph::NodeArrayEntry, true>(memory_ptr,
|
||||||
|
DataLayout::CH_GRAPH_NODE_LIST);
|
||||||
|
layout.GetBlockPtr<QueryGraph::EdgeArrayEntry, true>(memory_ptr,
|
||||||
|
DataLayout::CH_GRAPH_EDGE_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
// store the filename of the on-disk portion of the RTree
|
// store the filename of the on-disk portion of the RTree
|
||||||
{
|
{
|
||||||
@ -643,6 +693,7 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
geometry_input_file.ReadInto(geometries_rev_duration_list_ptr, geometry_node_lists_count);
|
geometry_input_file.ReadInto(geometries_rev_duration_list_ptr, geometry_node_lists_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (boost::filesystem::exists(config.datasource_indexes_path))
|
||||||
{
|
{
|
||||||
io::FileReader geometry_datasource_file(config.datasource_indexes_path,
|
io::FileReader geometry_datasource_file(config.datasource_indexes_path,
|
||||||
io::FileReader::HasNoFingerprint);
|
io::FileReader::HasNoFingerprint);
|
||||||
@ -657,9 +708,13 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
geometry_datasource_file, datasources_list_ptr, number_of_compressed_datasources);
|
geometry_datasource_file, datasources_list_ptr, number_of_compressed_datasources);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.GetBlockPtr<uint8_t, true>(memory_ptr, DataLayout::DATASOURCES_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boost::filesystem::exists(config.datasource_names_path))
|
||||||
{
|
{
|
||||||
/* Load names */
|
|
||||||
io::FileReader datasource_names_file(config.datasource_names_path,
|
io::FileReader datasource_names_file(config.datasource_names_path,
|
||||||
io::FileReader::HasNoFingerprint);
|
io::FileReader::HasNoFingerprint);
|
||||||
|
|
||||||
@ -706,6 +761,12 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
datasource_name_lengths_ptr);
|
datasource_name_lengths_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.GetBlockPtr<char, true>(memory_ptr, DataLayout::DATASOURCE_NAME_DATA);
|
||||||
|
layout.GetBlockPtr<std::size_t, true>(memory_ptr, DataLayout::DATASOURCE_NAME_OFFSETS);
|
||||||
|
layout.GetBlockPtr<std::size_t, true>(memory_ptr, DataLayout::DATASOURCE_NAME_LENGTHS);
|
||||||
|
}
|
||||||
|
|
||||||
// Loading list of coordinates
|
// Loading list of coordinates
|
||||||
{
|
{
|
||||||
@ -768,6 +829,7 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
tree_node_file.ReadInto(rtree_ptr, layout.num_entries[DataLayout::R_SEARCH_TREE]);
|
tree_node_file.ReadInto(rtree_ptr, layout.num_entries[DataLayout::R_SEARCH_TREE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (boost::filesystem::exists(config.core_data_path))
|
||||||
{
|
{
|
||||||
io::FileReader core_marker_file(config.core_data_path, io::FileReader::HasNoFingerprint);
|
io::FileReader core_marker_file(config.core_data_path, io::FileReader::HasNoFingerprint);
|
||||||
const auto number_of_core_markers = core_marker_file.ReadElementCount32();
|
const auto number_of_core_markers = core_marker_file.ReadElementCount32();
|
||||||
@ -939,6 +1001,40 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
reader.ReadInto(mld_cell_level_offsets_ptr,
|
reader.ReadInto(mld_cell_level_offsets_ptr,
|
||||||
layout.GetBlockEntries(DataLayout::MLD_CELL_LEVEL_OFFSETS));
|
layout.GetBlockEntries(DataLayout::MLD_CELL_LEVEL_OFFSETS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (boost::filesystem::exists(config.edge_based_graph_path))
|
||||||
|
{
|
||||||
|
io::FileReader reader(config.edge_based_graph_path, io::FileReader::VerifyFingerprint);
|
||||||
|
|
||||||
|
const auto number_of_edges = reader.ReadElementCount64();
|
||||||
|
const auto number_of_nodes = reader.ReadOne<EdgeID>() + 1;
|
||||||
|
std::vector<extractor::EdgeBasedEdge> original_edges(number_of_edges);
|
||||||
|
reader.ReadInto(original_edges);
|
||||||
|
|
||||||
|
original_edges = partition::SplitBidirectionalEdges(std::move(original_edges));
|
||||||
|
auto edges = partition::PrepareEdgesForUsageInGraph(std::move(original_edges));
|
||||||
|
BOOST_ASSERT(edges.size() <= 2 * number_of_edges);
|
||||||
|
|
||||||
|
auto nodes_ptr = layout.GetBlockPtr<EdgeBasedGraph::NodeArrayEntry, true>(
|
||||||
|
memory_ptr, DataLayout::MLD_GRAPH_NODE_LIST);
|
||||||
|
auto edges_ptr = layout.GetBlockPtr<EdgeBasedGraph::EdgeArrayEntry, true>(
|
||||||
|
memory_ptr, DataLayout::MLD_GRAPH_EDGE_LIST);
|
||||||
|
|
||||||
|
EdgeBasedGraph::EdgeIterator edge = 0;
|
||||||
|
for (const auto node : util::irange(0u, number_of_nodes + 1))
|
||||||
|
{
|
||||||
|
EdgeBasedGraph::EdgeIterator last_edge = edge;
|
||||||
|
while (edge < edges.size() && edges[edge].source == node)
|
||||||
|
{
|
||||||
|
edges_ptr[edge].target = edges[edge].target;
|
||||||
|
edges_ptr[edge].data = edges[edge].data;
|
||||||
|
++edge;
|
||||||
|
}
|
||||||
|
nodes_ptr[node].first_edge = last_edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT(edge == edges.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,22 @@ namespace osrm
|
|||||||
{
|
{
|
||||||
namespace storage
|
namespace storage
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool CheckFileList(const std::vector<boost::filesystem::path> &files)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
for (auto &path : files)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::is_regular_file(path))
|
||||||
|
{
|
||||||
|
util::Log(logWARNING) << "Missing/Broken File: " << path.string();
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StorageConfig::StorageConfig(const boost::filesystem::path &base)
|
StorageConfig::StorageConfig(const boost::filesystem::path &base)
|
||||||
: ram_index_path{base.string() + ".ramIndex"}, file_index_path{base.string() + ".fileIndex"},
|
: ram_index_path{base.string() + ".ramIndex"}, file_index_path{base.string() + ".fileIndex"},
|
||||||
@ -20,40 +36,40 @@ StorageConfig::StorageConfig(const boost::filesystem::path &base)
|
|||||||
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
|
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
|
||||||
intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"},
|
intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"},
|
||||||
turn_lane_description_path{base.string() + ".tls"},
|
turn_lane_description_path{base.string() + ".tls"},
|
||||||
mld_partition_path{base.string() + ".partition"}, mld_storage_path{base.string() + ".cells"}
|
mld_partition_path{base.string() + ".partition"}, mld_storage_path{base.string() + ".cells"},
|
||||||
|
edge_based_graph_path{base.string() + ".ebg"}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StorageConfig::IsValid() const
|
bool StorageConfig::IsValid() const
|
||||||
{
|
{
|
||||||
const constexpr auto num_files = 15;
|
const constexpr auto num_files = 15;
|
||||||
const boost::filesystem::path paths[num_files] = {ram_index_path,
|
|
||||||
file_index_path,
|
|
||||||
hsgr_data_path,
|
|
||||||
nodes_data_path,
|
|
||||||
edges_data_path,
|
|
||||||
core_data_path,
|
|
||||||
geometries_path,
|
|
||||||
timestamp_path,
|
|
||||||
turn_weight_penalties_path,
|
|
||||||
turn_duration_penalties_path,
|
|
||||||
datasource_names_path,
|
|
||||||
datasource_indexes_path,
|
|
||||||
names_data_path,
|
|
||||||
properties_path,
|
|
||||||
intersection_class_path};
|
|
||||||
|
|
||||||
bool success = true;
|
// Common files
|
||||||
for (auto path = paths; path != paths + num_files; ++path)
|
if (!CheckFileList({ram_index_path,
|
||||||
|
file_index_path,
|
||||||
|
nodes_data_path,
|
||||||
|
edges_data_path,
|
||||||
|
geometries_path,
|
||||||
|
timestamp_path,
|
||||||
|
turn_weight_penalties_path,
|
||||||
|
turn_duration_penalties_path,
|
||||||
|
names_data_path,
|
||||||
|
properties_path,
|
||||||
|
intersection_class_path}))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_regular_file(*path))
|
return false;
|
||||||
{
|
|
||||||
util::Log(logWARNING) << "Missing/Broken File: " << path->string();
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
// TODO: add algorithm checks
|
||||||
|
|
||||||
|
// CH files
|
||||||
|
CheckFileList({hsgr_data_path, core_data_path, datasource_names_path, datasource_indexes_path});
|
||||||
|
|
||||||
|
// MLD files
|
||||||
|
CheckFileList({mld_partition_path, mld_storage_path, edge_based_graph_path});
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomArrayEntryFixture
|
|||||||
}
|
}
|
||||||
std::sort(offsets.begin(), offsets.end());
|
std::sort(offsets.begin(), offsets.end());
|
||||||
// add sentinel
|
// add sentinel
|
||||||
offsets.push_back(offsets.back());
|
offsets.push_back(TEST_NUM_EDGES);
|
||||||
|
|
||||||
// extract interval lengths
|
// extract interval lengths
|
||||||
for (unsigned i = 0; i < offsets.size() - 1; i++)
|
for (unsigned i = 0; i < offsets.size() - 1; i++)
|
||||||
|
Loading…
Reference in New Issue
Block a user