No longer requires edges to have a .data member in static graph

some fixes to make branch compilable
Removes unneeded edge data from components search
This commit is contained in:
Daniel J. Hofmann 2017-01-27 17:06:37 +01:00 committed by Patrick Niklaus
parent c3cc79f798
commit e316dad1cb
3 changed files with 50 additions and 34 deletions

View File

@ -11,6 +11,7 @@
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -31,24 +32,30 @@ struct NodeArrayEntry
EdgeIterator first_edge; EdgeIterator first_edge;
}; };
template <typename EdgeDataT> struct EdgeArrayEntry;
template <typename EdgeDataT> struct EdgeArrayEntry template <typename EdgeDataT> struct EdgeArrayEntry
{ {
NodeID target; NodeID target;
EdgeDataT data; EdgeDataT data;
}; };
template <typename EdgeDataT> class SortableEdgeWithData template <> struct EdgeArrayEntry<void>
{
NodeID target;
};
template <typename EdgeDataT> struct SortableEdgeWithData;
template <> struct SortableEdgeWithData<void>
{ {
public:
NodeIterator source; NodeIterator source;
NodeIterator target; NodeIterator target;
EdgeDataT data;
template <typename... Ts> SortableEdgeWithData(NodeIterator source, NodeIterator target) : source(source), target(target)
SortableEdgeWithData(NodeIterator source, NodeIterator target, Ts &&... data)
: source(source), target(target), data(std::forward<Ts>(data)...)
{ {
} }
bool operator<(const SortableEdgeWithData &right) const bool operator<(const SortableEdgeWithData &right) const
{ {
if (source != right.source) if (source != right.source)
@ -59,19 +66,31 @@ template <typename EdgeDataT> class SortableEdgeWithData
} }
}; };
template <typename EdgeDataT> struct SortableEdgeWithData : SortableEdgeWithData<void>
{
using Base = SortableEdgeWithData<void>;
EdgeDataT data;
template <typename... Ts>
SortableEdgeWithData(NodeIterator source, NodeIterator target, Ts &&... data)
: Base{source, target}, data{std::forward<Ts>(data)...}
{
}
};
} // namespace static_graph_details } // namespace static_graph_details
template <typename NodeT, typename EdgeT, bool UseSharedMemory = false> class FlexibleStaticGraph template <typename NodeT, typename EdgeT, bool UseSharedMemory = false> class FlexibleStaticGraph
{ {
static_assert(traits::HasFirstEdgeMember<NodeT>::value, static_assert(traits::HasFirstEdgeMember<NodeT>::value,
"Model for compatible Node type requires .first_edge member attribute"); "Model for compatible Node type requires .first_edge member attribute");
static_assert(traits::HasDataAndTargetMember<EdgeT>::value, static_assert(traits::HasTargetMember<EdgeT>(),
"Model for compatible Edge type requires .data and .target member attribute"); "Model for compatible Node type requires .target member attribute");
public: public:
using NodeIterator = static_graph_details::NodeIterator; using NodeIterator = static_graph_details::NodeIterator;
using EdgeIterator = static_graph_details::EdgeIterator; using EdgeIterator = static_graph_details::EdgeIterator;
using EdgeData = decltype(EdgeT::data);
using EdgeRange = range<EdgeIterator>; using EdgeRange = range<EdgeIterator>;
using NodeArrayEntry = NodeT; using NodeArrayEntry = NodeT;
using EdgeArrayEntry = EdgeT; using EdgeArrayEntry = EdgeT;
@ -109,7 +128,7 @@ template <typename NodeT, typename EdgeT, bool UseSharedMemory = false> class Fl
for (const auto i : irange(node_array[node].first_edge, e)) for (const auto i : irange(node_array[node].first_edge, e))
{ {
edge_array[i].target = graph[edge].target; edge_array[i].target = graph[edge].target;
edge_array[i].data = graph[edge].data; CopyDataIfAvailable(edge_array[i], graph[edge], traits::HasDataMember<EdgeT>{});
edge++; edge++;
} }
} }
@ -179,6 +198,9 @@ template <typename NodeT, typename EdgeT, bool UseSharedMemory = false> class Fl
EdgeIterator EdgeIterator
FindSmallestEdge(const NodeIterator from, const NodeIterator to, FilterFunction &&filter) const FindSmallestEdge(const NodeIterator from, const NodeIterator to, FilterFunction &&filter) const
{ {
static_assert(traits::HasDataMember<EdgeT>::value,
"Filtering on .data not possible without .data member attribute");
EdgeIterator smallest_edge = SPECIAL_EDGEID; EdgeIterator smallest_edge = SPECIAL_EDGEID;
EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT; EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT;
for (auto edge : GetAdjacentEdgeRange(from)) for (auto edge : GetAdjacentEdgeRange(from))
@ -220,6 +242,20 @@ template <typename NodeT, typename EdgeT, bool UseSharedMemory = false> class Fl
const EdgeArrayEntry &GetEdge(const EdgeID eid) const { return edge_array[eid]; } const EdgeArrayEntry &GetEdge(const EdgeID eid) const { return edge_array[eid]; }
private: private:
template <typename OtherEdge>
void CopyDataIfAvailable(EdgeT &into, const OtherEdge &from, std::true_type)
{
into.data = from.data;
}
template <typename OtherEdge>
void CopyDataIfAvailable(EdgeT &into, const OtherEdge &from, std::false_type)
{
// Graph has no .data member, never copy even if `from` has a .data member.
(void)into;
(void)from;
}
NodeIterator number_of_nodes; NodeIterator number_of_nodes;
EdgeIterator number_of_edges; EdgeIterator number_of_edges;

View File

@ -260,7 +260,6 @@ std::vector<NodeID> DinicMaxFlow::GetAugmentingPath(LevelGraph &levels,
// check if the edge is valid // check if the edge is valid
const auto has_capacity = flow[target].count(path.back()) == 0; const auto has_capacity = flow[target].count(path.back()) == 0;
const auto descends_level_graph = levels[target] + 1 == levels[path.back()]; const auto descends_level_graph = levels[target] + 1 == levels[path.back()];
if (has_capacity && descends_level_graph) if (has_capacity && descends_level_graph)

View File

@ -28,21 +28,8 @@ namespace osrm
namespace tools namespace tools
{ {
struct TarjanEdgeData using TarjanGraph = util::StaticGraph<void>;
{ using TarjanEdge = util::static_graph_details::SortableEdgeWithData<void>;
TarjanEdgeData() : distance(INVALID_EDGE_WEIGHT), name_id(INVALID_NAMEID) {}
TarjanEdgeData(std::uint32_t distance, std::uint32_t name_id)
: distance(distance), name_id(name_id)
{
}
std::uint32_t distance;
std::uint32_t name_id;
};
using TarjanGraph = util::StaticGraph<TarjanEdgeData>;
using TarjanEdge = util::static_graph_details::SortableEdgeWithData<TarjanEdgeData>;
std::size_t loadGraph(const std::string &path, std::size_t loadGraph(const std::string &path,
std::vector<extractor::QueryNode> &coordinate_list, std::vector<extractor::QueryNode> &coordinate_list,
@ -68,18 +55,12 @@ std::size_t loadGraph(const std::string &path,
if (input_edge.forward) if (input_edge.forward)
{ {
graph_edge_list.emplace_back(input_edge.source, graph_edge_list.emplace_back(input_edge.source, input_edge.target);
input_edge.target,
(std::max)(input_edge.weight, 1),
input_edge.name_id);
} }
if (input_edge.backward) if (input_edge.backward)
{ {
graph_edge_list.emplace_back(input_edge.target, graph_edge_list.emplace_back(input_edge.target, input_edge.source);
input_edge.source,
(std::max)(input_edge.weight, 1),
input_edge.name_id);
} }
} }