migrate DataStructures to C++11

This commit is contained in:
Dennis Luxen 2014-05-07 18:39:16 +02:00
parent 6abbb06ff6
commit e12ad48822
34 changed files with 1147 additions and 1168 deletions

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef CONCURRENTQUEUE_H_ #ifndef CONCURRENT_QUEUE_H
#define CONCURRENTQUEUE_H_ #define CONCURRENT_QUEUE_H
#include "../typedefs.h" #include "../typedefs.h"
@ -36,64 +36,59 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
template<typename Data> template <typename Data> class ConcurrentQueue
class ConcurrentQueue { {
public: public:
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { } explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) {}
inline void push(const Data & data) { inline void push(const Data &data)
{
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait( m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this));
lock,
boost::bind(&ConcurrentQueue<Data>::is_not_full, this)
);
m_internal_queue.push_back(data); m_internal_queue.push_back(data);
lock.unlock(); lock.unlock();
m_not_empty.notify_one(); m_not_empty.notify_one();
} }
inline bool empty() const { inline bool empty() const { return m_internal_queue.empty(); }
return m_internal_queue.empty();
}
inline void wait_and_pop(Data & popped_value) { inline void wait_and_pop(Data &popped_value)
{
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
m_not_empty.wait( m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this));
lock,
boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)
);
popped_value = m_internal_queue.front(); popped_value = m_internal_queue.front();
m_internal_queue.pop_front(); m_internal_queue.pop_front();
lock.unlock(); lock.unlock();
m_not_full.notify_one(); m_not_full.notify_one();
} }
inline bool try_pop(Data& popped_value) { inline bool try_pop(Data &popped_value)
{
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
if(m_internal_queue.empty()) { if (m_internal_queue.empty())
{
return false; return false;
} }
popped_value=m_internal_queue.front(); popped_value = m_internal_queue.front();
m_internal_queue.pop_front(); m_internal_queue.pop_front();
lock.unlock(); lock.unlock();
m_not_full.notify_one(); m_not_full.notify_one();
return true; return true;
} }
private: private:
inline bool is_not_empty() const { inline bool is_not_empty() const { return !m_internal_queue.empty(); }
return !m_internal_queue.empty();
}
inline bool is_not_full() const { inline bool is_not_full() const
{
return m_internal_queue.size() < m_internal_queue.capacity(); return m_internal_queue.size() < m_internal_queue.capacity();
} }
boost::circular_buffer<Data> m_internal_queue; boost::circular_buffer<Data> m_internal_queue;
boost::mutex m_mutex; boost::mutex m_mutex;
boost::condition m_not_empty; boost::condition m_not_empty;
boost::condition m_not_full; boost::condition m_not_full;
}; };
#endif /* CONCURRENTQUEUE_H_ */ #endif // CONCURRENT_QUEUE_H

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef DYNAMICGRAPH_H_INCLUDED #ifndef DYNAMICGRAPH_H
#define DYNAMICGRAPH_H_INCLUDED #define DYNAMICGRAPH_H
#include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DeallocatingVector.h"
@ -38,211 +38,224 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits> #include <limits>
#include <vector> #include <vector>
template< typename EdgeDataT> template <typename EdgeDataT> class DynamicGraph
class DynamicGraph { {
public: public:
typedef EdgeDataT EdgeData; typedef EdgeDataT EdgeData;
typedef unsigned NodeIterator; typedef unsigned NodeIterator;
typedef unsigned EdgeIterator; typedef unsigned EdgeIterator;
class InputEdge { class InputEdge
public: {
NodeIterator source; public:
NodeIterator target; NodeIterator source;
EdgeDataT data; NodeIterator target;
bool operator<( const InputEdge& right ) const { EdgeDataT data;
if ( source != right.source ) bool operator<(const InputEdge &right) const
return source < right.source; {
return target < right.target; if (source != right.source)
} return source < right.source;
}; return target < right.target;
//Constructs an empty graph with a given number of nodes.
explicit DynamicGraph( int32_t nodes ) : m_numNodes(nodes), m_numEdges(0) {
m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes );
m_edges.reserve( m_numNodes * 1.1 );
m_edges.resize( m_numNodes );
} }
};
template<class ContainerT> // Constructs an empty graph with a given number of nodes.
DynamicGraph( const int32_t nodes, const ContainerT &graph ) { explicit DynamicGraph(int32_t nodes) : m_numNodes(nodes), m_numEdges(0)
m_numNodes = nodes; {
m_numEdges = ( EdgeIterator ) graph.size(); m_nodes.reserve(m_numNodes);
m_nodes.reserve( m_numNodes +1); m_nodes.resize(m_numNodes);
m_nodes.resize( m_numNodes +1);
EdgeIterator edge = 0; m_edges.reserve(m_numNodes * 1.1);
EdgeIterator position = 0; m_edges.resize(m_numNodes);
for ( NodeIterator node = 0; node < m_numNodes; ++node ) { }
EdgeIterator lastEdge = edge;
while ( edge < m_numEdges && graph[edge].source == node ) { template <class ContainerT> DynamicGraph(const int32_t nodes, const ContainerT &graph)
++edge; {
} m_numNodes = nodes;
m_nodes[node].firstEdge = position; m_numEdges = (EdgeIterator)graph.size();
m_nodes[node].edges = edge - lastEdge; m_nodes.reserve(m_numNodes + 1);
position += m_nodes[node].edges; m_nodes.resize(m_numNodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (NodeIterator node = 0; node < m_numNodes; ++node)
{
EdgeIterator lastEdge = edge;
while (edge < m_numEdges && graph[edge].source == node)
{
++edge;
} }
m_nodes.back().firstEdge = position; m_nodes[node].firstEdge = position;
m_edges.reserve( position * 1.1 ); m_nodes[node].edges = edge - lastEdge;
m_edges.resize( position ); position += m_nodes[node].edges;
edge = 0; }
for ( NodeIterator node = 0; node < m_numNodes; ++node ) { m_nodes.back().firstEdge = position;
for ( EdgeIterator i = m_nodes[node].firstEdge, e = m_nodes[node].firstEdge + m_nodes[node].edges; i != e; ++i ) { m_edges.reserve(position * 1.1);
m_edges[i].target = graph[edge].target; m_edges.resize(position);
m_edges[i].data = graph[edge].data; edge = 0;
BOOST_ASSERT_MSG( for (NodeIterator node = 0; node < m_numNodes; ++node)
graph[edge].data.distance > 0, {
"edge distance invalid" for (EdgeIterator i = m_nodes[node].firstEdge,
); e = m_nodes[node].firstEdge + m_nodes[node].edges;
++edge; i != e;
++i)
{
m_edges[i].target = graph[edge].target;
m_edges[i].data = graph[edge].data;
BOOST_ASSERT_MSG(graph[edge].data.distance > 0, "edge distance invalid");
++edge;
}
}
}
~DynamicGraph() {}
unsigned GetNumberOfNodes() const { return m_numNodes; }
unsigned GetNumberOfEdges() const { return m_numEdges; }
unsigned GetOutDegree(const NodeIterator n) const { return m_nodes[n].edges; }
NodeIterator GetTarget(const EdgeIterator e) const { return NodeIterator(m_edges[e].target); }
void SetTarget(const EdgeIterator e, const NodeIterator n) { m_edges[e].target = n; }
EdgeDataT &GetEdgeData(const EdgeIterator e) { return m_edges[e].data; }
const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return m_edges[e].data; }
EdgeIterator BeginEdges(const NodeIterator n) const
{
return EdgeIterator(m_nodes[n].firstEdge);
}
EdgeIterator EndEdges(const NodeIterator n) const
{
return EdgeIterator(m_nodes[n].firstEdge + m_nodes[n].edges);
}
// adds an edge. Invalidates edge iterators for the source node
EdgeIterator InsertEdge(const NodeIterator from, const NodeIterator to, const EdgeDataT &data)
{
Node &node = m_nodes[from];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
if (newFirstEdge >= m_edges.size() || !isDummy(newFirstEdge))
{
if (node.firstEdge != 0 && isDummy(node.firstEdge - 1))
{
node.firstEdge--;
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
}
else
{
EdgeIterator newFirstEdge = (EdgeIterator)m_edges.size();
unsigned newSize = node.edges * 1.1 + 2;
EdgeIterator requiredCapacity = newSize + m_edges.size();
EdgeIterator oldCapacity = m_edges.capacity();
if (requiredCapacity >= oldCapacity)
{
m_edges.reserve(requiredCapacity * 1.1);
} }
m_edges.resize(m_edges.size() + newSize);
for (EdgeIterator i = 0; i < node.edges; ++i)
{
m_edges[newFirstEdge + i] = m_edges[node.firstEdge + i];
makeDummy(node.firstEdge + i);
}
for (EdgeIterator i = node.edges + 1; i < newSize; ++i)
makeDummy(newFirstEdge + i);
node.firstEdge = newFirstEdge;
}
}
Edge &edge = m_edges[node.firstEdge + node.edges];
edge.target = to;
edge.data = data;
++m_numEdges;
++node.edges;
return EdgeIterator(node.firstEdge + node.edges);
}
// removes an edge. Invalidates edge iterators for the source node
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
{
Node &node = m_nodes[source];
#pragma omp atomic
--m_numEdges;
--node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
const unsigned last = node.firstEdge + node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != last);
// swap with last edge
m_edges[e] = m_edges[last];
makeDummy(last);
}
// removes all edges (source,target)
int32_t DeleteEdgesTo(const NodeIterator source, const NodeIterator target)
{
int32_t deleted = 0;
for (EdgeIterator i = BeginEdges(source), iend = EndEdges(source); i < iend - deleted; ++i)
{
if (m_edges[i].target == target)
{
do
{
deleted++;
m_edges[i] = m_edges[iend - deleted];
makeDummy(iend - deleted);
} while (i < iend - deleted && m_edges[i].target == target);
} }
} }
~DynamicGraph(){ } #pragma omp atomic
m_numEdges -= deleted;
m_nodes[source].edges -= deleted;
unsigned GetNumberOfNodes() const { return deleted;
return m_numNodes; }
}
unsigned GetNumberOfEdges() const { // searches for a specific edge
return m_numEdges; EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const
} {
for (EdgeIterator i = BeginEdges(from), iend = EndEdges(from); i != iend; ++i)
unsigned GetOutDegree( const NodeIterator n ) const { {
return m_nodes[n].edges; if (to == m_edges[i].target)
} {
return i;
NodeIterator GetTarget( const EdgeIterator e ) const {
return NodeIterator( m_edges[e].target );
}
void SetTarget( const EdgeIterator e, const NodeIterator n ) {
m_edges[e].target = n;
}
EdgeDataT &GetEdgeData( const EdgeIterator e ) {
return m_edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator e ) const {
return m_edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator n ) const {
return EdgeIterator( m_nodes[n].firstEdge );
}
EdgeIterator EndEdges( const NodeIterator n ) const {
return EdgeIterator( m_nodes[n].firstEdge + m_nodes[n].edges );
}
//adds an edge. Invalidates edge iterators for the source node
EdgeIterator InsertEdge( const NodeIterator from, const NodeIterator to, const EdgeDataT &data ) {
Node &node = m_nodes[from];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
if ( newFirstEdge >= m_edges.size() || !isDummy( newFirstEdge ) ) {
if ( node.firstEdge != 0 && isDummy( node.firstEdge - 1 ) ) {
node.firstEdge--;
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
} else {
EdgeIterator newFirstEdge = ( EdgeIterator ) m_edges.size();
unsigned newSize = node.edges * 1.1 + 2;
EdgeIterator requiredCapacity = newSize + m_edges.size();
EdgeIterator oldCapacity = m_edges.capacity();
if ( requiredCapacity >= oldCapacity ) {
m_edges.reserve( requiredCapacity * 1.1 );
}
m_edges.resize( m_edges.size() + newSize );
for ( EdgeIterator i = 0; i < node.edges; ++i ) {
m_edges[newFirstEdge + i ] = m_edges[node.firstEdge + i];
makeDummy( node.firstEdge + i );
}
for ( EdgeIterator i = node.edges + 1; i < newSize; ++i )
makeDummy( newFirstEdge + i );
node.firstEdge = newFirstEdge;
}
} }
Edge &edge = m_edges[node.firstEdge + node.edges];
edge.target = to;
edge.data = data;
++m_numEdges;
++node.edges;
return EdgeIterator( node.firstEdge + node.edges );
} }
return EndEdges(from);
}
//removes an edge. Invalidates edge iterators for the source node protected:
void DeleteEdge( const NodeIterator source, const EdgeIterator e ) { bool isDummy(const EdgeIterator edge) const
Node &node = m_nodes[source]; {
#pragma omp atomic return m_edges[edge].target == (std::numeric_limits<NodeIterator>::max)();
--m_numEdges; }
--node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
const unsigned last = node.firstEdge + node.edges;
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != last);
//swap with last edge
m_edges[e] = m_edges[last];
makeDummy( last );
}
//removes all edges (source,target) void makeDummy(const EdgeIterator edge)
int32_t DeleteEdgesTo( const NodeIterator source, const NodeIterator target ) { {
int32_t deleted = 0; m_edges[edge].target = (std::numeric_limits<NodeIterator>::max)();
for ( EdgeIterator i = BeginEdges( source ), iend = EndEdges( source ); i < iend - deleted; ++i ) { }
if ( m_edges[i].target == target ) {
do {
deleted++;
m_edges[i] = m_edges[iend - deleted];
makeDummy( iend - deleted );
} while ( i < iend - deleted && m_edges[i].target == target );
}
}
#pragma omp atomic struct Node
m_numEdges -= deleted; {
m_nodes[source].edges -= deleted; // index of the first edge
EdgeIterator firstEdge;
// amount of edges
unsigned edges;
};
return deleted; struct Edge
} {
NodeIterator target;
EdgeDataT data;
};
//searches for a specific edge NodeIterator m_numNodes;
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const { EdgeIterator m_numEdges;
for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) {
if ( to == m_edges[i].target ) {
return i;
}
}
return EndEdges( from );
}
protected: std::vector<Node> m_nodes;
DeallocatingVector<Edge> m_edges;
bool isDummy( const EdgeIterator edge ) const {
return m_edges[edge].target == (std::numeric_limits< NodeIterator >::max)();
}
void makeDummy( const EdgeIterator edge ) {
m_edges[edge].target = (std::numeric_limits< NodeIterator >::max)();
}
struct Node {
//index of the first edge
EdgeIterator firstEdge;
//amount of edges
unsigned edges;
};
struct Edge {
NodeIterator target;
EdgeDataT data;
};
NodeIterator m_numNodes;
EdgeIterator m_numEdges;
std::vector< Node > m_nodes;
DeallocatingVector< Edge > m_edges;
}; };
#endif // DYNAMICGRAPH_H_INCLUDED #endif // DYNAMICGRAPH_H

View File

@ -10,7 +10,8 @@
#include <limits> #include <limits>
struct EdgeBasedNode { struct EdgeBasedNode
{
EdgeBasedNode() : EdgeBasedNode() :
forward_edge_based_node_id(SPECIAL_NODEID), forward_edge_based_node_id(SPECIAL_NODEID),
@ -24,7 +25,7 @@ struct EdgeBasedNode {
reverse_offset(0), reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID), packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ), fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
belongsToTinyComponent(false) is_in_tiny_cc(false)
{ } { }
explicit EdgeBasedNode( explicit EdgeBasedNode(
@ -52,18 +53,14 @@ struct EdgeBasedNode {
reverse_offset(reverse_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id), packed_geometry_id(packed_geometry_id),
fwd_segment_position(fwd_segment_position), fwd_segment_position(fwd_segment_position),
belongsToTinyComponent(belongs_to_tiny_component) is_in_tiny_cc(belongs_to_tiny_component)
{ {
BOOST_ASSERT( BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
( forward_edge_based_node_id != SPECIAL_NODEID ) || (reverse_edge_based_node_id != SPECIAL_NODEID));
( reverse_edge_based_node_id != SPECIAL_NODEID )
);
} }
static inline FixedPointCoordinate Centroid( static inline FixedPointCoordinate Centroid(const FixedPointCoordinate & a, const FixedPointCoordinate & b)
const FixedPointCoordinate & a, {
const FixedPointCoordinate & b
) {
FixedPointCoordinate centroid; FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by: //The coordinates of the midpoint are given by:
centroid.lat = (a.lat + b.lat)/2; centroid.lat = (a.lat + b.lat)/2;
@ -71,7 +68,8 @@ struct EdgeBasedNode {
return centroid; return centroid;
} }
bool IsCompressed() { bool IsCompressed() const
{
return packed_geometry_id != SPECIAL_EDGEID; return packed_geometry_id != SPECIAL_EDGEID;
} }
@ -86,7 +84,7 @@ struct EdgeBasedNode {
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned short fwd_segment_position; // segment id in a compressed geometry unsigned short fwd_segment_position; // segment id in a compressed geometry
bool belongsToTinyComponent; bool is_in_tiny_cc;
}; };
#endif //EDGE_BASED_NODE_H #endif //EDGE_BASED_NODE_H

View File

@ -33,15 +33,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp> #include <boost/assert.hpp>
class NodeBasedEdge { class NodeBasedEdge
{
public: public:
bool operator< (const NodeBasedEdge& e) const { bool operator<(const NodeBasedEdge &e) const
if (source() == e.source()) { {
if (target() == e.target()) { if (source() == e.source())
if (weight() == e.weight()) { {
return (isForward() && isBackward() && if (target() == e.target())
((! e.isForward()) || (! e.isBackward()))); {
if (weight() == e.weight())
{
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
} }
return (weight() < e.weight()); return (weight() < e.weight());
} }
@ -50,80 +54,77 @@ public:
return (source() < e.source()); return (source() < e.source());
} }
explicit NodeBasedEdge( explicit NodeBasedEdge(NodeID s,
NodeID s, NodeID t,
NodeID t, NodeID n,
NodeID n, EdgeWeight w,
EdgeWeight w, bool f,
bool f, bool b,
bool b, short ty,
short ty, bool ra,
bool ra, bool ig,
bool ig, bool ar,
bool ar, bool cf,
bool cf, bool is_split)
bool is_split : _source(s), _target(t), _name(n), _weight(w), _type(ty), forward(f), backward(b),
) : _source(s), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf),
_target(t), is_split(is_split)
_name(n),
_weight(w),
_type(ty),
forward(f),
backward(b),
_roundabout(ra),
_ignoreInGrid(ig),
_accessRestricted(ar),
_contraFlow(cf),
is_split(is_split)
{ {
if(ty < 0) { if (ty < 0)
{
throw OSRMException("negative edge type"); throw OSRMException("negative edge type");
} }
} }
NodeID target() const {return _target; } NodeID target() const { return _target; }
NodeID source() const {return _source; } NodeID source() const { return _source; }
NodeID name() const { return _name; } NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; } EdgeWeight weight() const { return _weight; }
short type() const { short type() const
{
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid"); BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
return _type; } return _type;
bool isBackward() const { return backward; } }
bool isForward() const { return forward; } bool isBackward() const { return backward; }
bool isLocatable() const { return _type != 14; } bool isForward() const { return forward; }
bool isRoundabout() const { return _roundabout; } bool isLocatable() const { return _type != 14; }
bool ignoreInGrid() const { return _ignoreInGrid; } bool isRoundabout() const { return _roundabout; }
bool isAccessRestricted() const { return _accessRestricted; } bool ignoreInGrid() const { return _ignoreInGrid; }
bool isContraFlow() const { return _contraFlow; } bool isAccessRestricted() const { return _accessRestricted; }
bool IsSplit() const { return is_split; } bool isContraFlow() const { return _contraFlow; }
bool IsSplit() const { return is_split; }
//TODO: names need to be fixed. // TODO: names need to be fixed.
NodeID _source; NodeID _source;
NodeID _target; NodeID _target;
NodeID _name; NodeID _name;
EdgeWeight _weight; EdgeWeight _weight;
short _type; short _type;
bool forward:1; bool forward : 1;
bool backward:1; bool backward : 1;
bool _roundabout:1; bool _roundabout : 1;
bool _ignoreInGrid:1; bool _ignoreInGrid : 1;
bool _accessRestricted:1; bool _accessRestricted : 1;
bool _contraFlow:1; bool _contraFlow : 1;
bool is_split:1; bool is_split : 1;
private: private:
NodeBasedEdge() { } NodeBasedEdge() {}
}; };
class EdgeBasedEdge { class EdgeBasedEdge
{
public: public:
bool operator< (const EdgeBasedEdge& e) const { bool operator<(const EdgeBasedEdge &e) const
if (source() == e.source()) { {
if (target() == e.target()) { if (source() == e.source())
if (weight() == e.weight()) { {
return (isForward() && isBackward() && if (target() == e.target())
((! e.isForward()) || (! e.isBackward()))); {
if (weight() == e.weight())
{
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
} }
return (weight() < e.weight()); return (weight() < e.weight());
} }
@ -132,56 +133,44 @@ public:
return (source() < e.source()); return (source() < e.source());
} }
template<class EdgeT> template <class EdgeT>
explicit EdgeBasedEdge(const EdgeT & myEdge ) : explicit EdgeBasedEdge(const EdgeT &myEdge)
m_source(myEdge.source), : m_source(myEdge.source), m_target(myEdge.target), m_edgeID(myEdge.data.via),
m_target(myEdge.target), m_weight(myEdge.data.distance), m_forward(myEdge.data.forward),
m_edgeID(myEdge.data.via), m_backward(myEdge.data.backward)
m_weight(myEdge.data.distance), {
m_forward(myEdge.data.forward), }
m_backward(myEdge.data.backward)
{ }
/** Default constructor. target and weight are set to 0.*/ /** Default constructor. target and weight are set to 0.*/
EdgeBasedEdge() : EdgeBasedEdge()
m_source(0), : m_source(0), m_target(0), m_edgeID(0), m_weight(0), m_forward(false), m_backward(false)
m_target(0), {
m_edgeID(0), }
m_weight(0),
m_forward(false),
m_backward(false)
{ }
explicit EdgeBasedEdge( explicit EdgeBasedEdge(const NodeID s,
const NodeID s, const NodeID t,
const NodeID t, const NodeID v,
const NodeID v, const EdgeWeight w,
const EdgeWeight w, const bool f,
const bool f, const bool b)
const bool b : m_source(s), m_target(t), m_edgeID(v), m_weight(w), m_forward(f), m_backward(b)
) : {
m_source(s), }
m_target(t),
m_edgeID(v),
m_weight(w),
m_forward(f),
m_backward(b)
{ }
NodeID target() const { return m_target; } NodeID target() const { return m_target; }
NodeID source() const { return m_source; } NodeID source() const { return m_source; }
EdgeWeight weight() const { return m_weight; } EdgeWeight weight() const { return m_weight; }
NodeID id() const { return m_edgeID; } NodeID id() const { return m_edgeID; }
bool isBackward() const { return m_backward; } bool isBackward() const { return m_backward; }
bool isForward() const { return m_forward; } bool isForward() const { return m_forward; }
private: private:
NodeID m_source; NodeID m_source;
NodeID m_target; NodeID m_target;
NodeID m_edgeID; NodeID m_edgeID;
EdgeWeight m_weight:30; EdgeWeight m_weight : 30;
bool m_forward:1; bool m_forward : 1;
bool m_backward:1; bool m_backward : 1;
}; };
typedef NodeBasedEdge ImportEdge; typedef NodeBasedEdge ImportEdge;

View File

@ -31,55 +31,45 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "QueryNode.h" #include "QueryNode.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
struct ExternalMemoryNode : NodeInfo
struct ExternalMemoryNode : NodeInfo { {
ExternalMemoryNode( ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light)
int lat, : NodeInfo(lat, lon, id), bollard(bollard), trafficLight(traffic_light)
int lon, {
unsigned int id,
bool bollard,
bool traffic_light
) :
NodeInfo(lat, lon, id),
bollard(bollard),
trafficLight(traffic_light)
{ }
ExternalMemoryNode()
:
bollard(false),
trafficLight(false)
{ }
static ExternalMemoryNode min_value() {
return ExternalMemoryNode(0,0,0, false, false);
} }
static ExternalMemoryNode max_value() { ExternalMemoryNode() : bollard(false), trafficLight(false) {}
return ExternalMemoryNode(
std::numeric_limits<int>::max(), static ExternalMemoryNode min_value() { return ExternalMemoryNode(0, 0, 0, false, false); }
std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(), static ExternalMemoryNode max_value()
false, {
false return ExternalMemoryNode(std::numeric_limits<int>::max(),
); std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(),
false,
false);
} }
NodeID key() const { NodeID key() const { return id; }
return id;
}
bool bollard; bool bollard;
bool trafficLight; bool trafficLight;
}; };
struct ImportNode : public ExternalMemoryNode { struct ImportNode : public ExternalMemoryNode
{
HashTable<std::string, std::string> keyVals; HashTable<std::string, std::string> keyVals;
inline void Clear() { inline void Clear()
keyVals.clear(); {
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false; keyVals.clear();
} lat = 0;
lon = 0;
id = 0;
bollard = false;
trafficLight = false;
}
}; };
#endif /* IMPORTNODE_H_ */ #endif /* IMPORTNODE_H_ */

View File

@ -25,80 +25,99 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef INPUT_READER_FACTORY_H
#ifndef INPUTREADERFACTORY_H #define INPUT_READER_FACTORY_H
#define INPUTREADERFACTORY_H
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <bzlib.h> #include <bzlib.h>
#include <libxml/xmlreader.h> #include <libxml/xmlreader.h>
struct BZ2Context { struct BZ2Context
FILE* file; {
BZFILE* bz2; FILE *file;
BZFILE *bz2;
int error; int error;
int nUnused; int nUnused;
char unused[BZ_MAX_UNUSED]; char unused[BZ_MAX_UNUSED];
}; };
int readFromBz2Stream( void* pointer, char* buffer, int len ) { int readFromBz2Stream(void *pointer, char *buffer, int len)
void *unusedTmpVoid=NULL; {
char *unusedTmp=NULL; void *unusedTmpVoid = NULL;
BZ2Context* context = (BZ2Context*) pointer; char *unusedTmp = NULL;
BZ2Context *context = (BZ2Context *)pointer;
int read = 0; int read = 0;
while(0 == read && !(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file))) { while (0 == read &&
!(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file)))
{
read = BZ2_bzRead(&context->error, context->bz2, buffer, len); read = BZ2_bzRead(&context->error, context->bz2, buffer, len);
if(BZ_OK == context->error) { if (BZ_OK == context->error)
{
return read; return read;
} else if(BZ_STREAM_END == context->error) { }
else if (BZ_STREAM_END == context->error)
{
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused); BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused"); BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
unusedTmp = (char*)unusedTmpVoid; unusedTmp = (char *)unusedTmpVoid;
for(int i=0;i<context->nUnused;i++) { for (int i = 0; i < context->nUnused; i++)
{
context->unused[i] = unusedTmp[i]; context->unused[i] = unusedTmp[i];
} }
BZ2_bzReadClose(&context->error, context->bz2); BZ2_bzReadClose(&context->error, context->bz2);
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose"); BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
context->error = BZ_STREAM_END; // set to the stream end for next call to this function context->error = BZ_STREAM_END; // set to the stream end for next call to this function
if(0 == context->nUnused && feof(context->file)) { if (0 == context->nUnused && feof(context->file))
{
return read; return read;
} else { }
context->bz2 = BZ2_bzReadOpen(&context->error, context->file, 0, 0, context->unused, context->nUnused); else
{
context->bz2 = BZ2_bzReadOpen(
&context->error, context->file, 0, 0, context->unused, context->nUnused);
BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file"); BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file");
} }
} else { BOOST_ASSERT_MSG(false, "Could not read bz2 file"); } }
else
{
BOOST_ASSERT_MSG(false, "Could not read bz2 file");
}
} }
return read; return read;
} }
int closeBz2Stream( void *pointer ) int closeBz2Stream(void *pointer)
{ {
BZ2Context* context = (BZ2Context*) pointer; BZ2Context *context = (BZ2Context *)pointer;
fclose( context->file ); fclose(context->file);
delete context; delete context;
return 0; return 0;
} }
xmlTextReaderPtr inputReaderFactory( const char* name ) xmlTextReaderPtr inputReaderFactory(const char *name)
{ {
std::string inputName(name); std::string inputName(name);
if(inputName.find(".osm.bz2")!=std::string::npos) if (inputName.find(".osm.bz2") != std::string::npos)
{ {
BZ2Context* context = new BZ2Context(); BZ2Context *context = new BZ2Context();
context->error = false; context->error = false;
context->file = fopen( name, "r" ); context->file = fopen(name, "r");
int error; int error;
context->bz2 = BZ2_bzReadOpen( &error, context->file, 0, 0, context->unused, context->nUnused ); context->bz2 =
if ( context->bz2 == NULL || context->file == NULL ) { BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused);
if (context->bz2 == NULL || context->file == NULL)
{
delete context; delete context;
return NULL; return NULL;
} }
return xmlReaderForIO( readFromBz2Stream, closeBz2Stream, (void*) context, NULL, NULL, 0 ); return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, NULL, NULL, 0);
} else { }
else
{
return xmlNewTextReaderFilename(name); return xmlNewTextReaderFilename(name);
} }
} }
#endif // INPUTREADERFACTORY_H #endif // INPUT_READER_FACTORY_H

View File

@ -29,61 +29,69 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define LRUCACHE_H #define LRUCACHE_H
#include <list> #include <list>
#include <boost/unordered_map.hpp> #include <unordered_map>
template<typename KeyT, typename ValueT> template <typename KeyT, typename ValueT> class LRUCache
class LRUCache { {
private: private:
struct CacheEntry { struct CacheEntry
{
CacheEntry(KeyT k, ValueT v) : key(k), value(v) {} CacheEntry(KeyT k, ValueT v) : key(k), value(v) {}
KeyT key; KeyT key;
ValueT value; ValueT value;
}; };
unsigned capacity; unsigned capacity;
std::list<CacheEntry> itemsInCache; std::list<CacheEntry> itemsInCache;
boost::unordered_map<KeyT, typename std::list<CacheEntry>::iterator > positionMap; std::unordered_map<KeyT, typename std::list<CacheEntry>::iterator> positionMap;
public:
public:
explicit LRUCache(unsigned c) : capacity(c) {} explicit LRUCache(unsigned c) : capacity(c) {}
bool Holds(KeyT key) { bool Holds(KeyT key)
if(positionMap.find(key) != positionMap.end()) { {
if (positionMap.find(key) != positionMap.end())
{
return true; return true;
} }
return false; return false;
} }
void Insert(const KeyT key, ValueT &value) { void Insert(const KeyT key, ValueT &value)
{
itemsInCache.push_front(CacheEntry(key, value)); itemsInCache.push_front(CacheEntry(key, value));
positionMap.insert(std::make_pair(key, itemsInCache.begin())); positionMap.insert(std::make_pair(key, itemsInCache.begin()));
if(itemsInCache.size() > capacity) { if (itemsInCache.size() > capacity)
{
positionMap.erase(itemsInCache.back().key); positionMap.erase(itemsInCache.back().key);
itemsInCache.pop_back(); itemsInCache.pop_back();
} }
} }
void Insert(const KeyT key, ValueT value) { void Insert(const KeyT key, ValueT value)
{
itemsInCache.push_front(CacheEntry(key, value)); itemsInCache.push_front(CacheEntry(key, value));
positionMap.insert(std::make_pair(key, itemsInCache.begin())); positionMap.insert(std::make_pair(key, itemsInCache.begin()));
if(itemsInCache.size() > capacity) { if (itemsInCache.size() > capacity)
{
positionMap.erase(itemsInCache.back().key); positionMap.erase(itemsInCache.back().key);
itemsInCache.pop_back(); itemsInCache.pop_back();
} }
} }
bool Fetch(const KeyT key, ValueT& result) { bool Fetch(const KeyT key, ValueT &result)
if(Holds(key)) { {
if (Holds(key))
{
CacheEntry e = *(positionMap.find(key)->second); CacheEntry e = *(positionMap.find(key)->second);
result = e.value; result = e.value;
//move to front // move to front
itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin()); itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin());
positionMap.find(key)->second = itemsInCache.begin(); positionMap.find(key)->second = itemsInCache.begin();
return true; return true;
} }
return false; return false;
} }
unsigned Size() const { unsigned Size() const { return itemsInCache.size(); }
return itemsInCache.size();
}
}; };
#endif //LRUCACHE_H #endif // LRUCACHE_H

View File

@ -33,25 +33,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits> #include <limits>
struct OriginalEdgeData{ struct OriginalEdgeData
explicit OriginalEdgeData( {
NodeID via_node, explicit OriginalEdgeData(NodeID via_node,
unsigned name_id, unsigned name_id,
TurnInstruction turn_instruction, TurnInstruction turn_instruction,
bool compressed_geometry bool compressed_geometry)
) : : via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
via_node( via_node ), compressed_geometry(compressed_geometry)
name_id( name_id ), {
turn_instruction( turn_instruction ), }
compressed_geometry( compressed_geometry )
{ }
OriginalEdgeData() : OriginalEdgeData()
via_node( std::numeric_limits<unsigned>::max() ), : via_node(std::numeric_limits<unsigned>::max()),
name_id( std::numeric_limits<unsigned>::max() ), name_id(std::numeric_limits<unsigned>::max()),
turn_instruction( std::numeric_limits<unsigned char>::max() ), turn_instruction(std::numeric_limits<unsigned char>::max()), compressed_geometry(false)
compressed_geometry( false ) {
{ } }
NodeID via_node; NodeID via_node;
unsigned name_id; unsigned name_id;
@ -59,4 +57,4 @@ struct OriginalEdgeData{
bool compressed_geometry; bool compressed_geometry;
}; };
#endif //ORIGINAL_EDGE_DATA_H #endif // ORIGINAL_EDGE_DATA_H

View File

@ -31,64 +31,68 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/OpenMPWrapper.h" #include "../Util/OpenMPWrapper.h"
#include <iostream> #include <iostream>
class Percent { class Percent
public: {
/** public:
* Constructor. explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); }
* @param maxValue the value that corresponds to 100%
* @param step the progress is shown in steps of 'step' percent // Reinitializes
*/ void reinit(unsigned max_value, unsigned step = 5)
explicit Percent(unsigned maxValue, unsigned step = 5) { {
reinit(maxValue, step); m_max_value = max_value;
m_current_value = 0;
m_percent_interval = m_max_value / 100;
m_next_threshold = m_percent_interval;
m_last_percent = 0;
m_step = step;
} }
/** Reinitializes this object. */ // If there has been significant progress, display it.
void reinit(unsigned maxValue, unsigned step = 5) { void printStatus(unsigned current_value)
_maxValue = maxValue; {
_current_value = 0; if (current_value >= m_next_threshold)
_intervalPercent = _maxValue / 100; {
_nextThreshold = _intervalPercent; m_next_threshold += m_percent_interval;
_lastPercent = 0; printPercent(current_value / (double)m_max_value * 100);
_step = step;
}
/** If there has been significant progress, display it. */
void printStatus(unsigned currentValue) {
if (currentValue >= _nextThreshold) {
_nextThreshold += _intervalPercent;
printPercent( currentValue / (double)_maxValue * 100 );
} }
if (currentValue + 1 == _maxValue) if (current_value + 1 == m_max_value)
std::cout << " 100%" << std::endl; std::cout << " 100%" << std::endl;
} }
void printIncrement() { void printIncrement()
{
#pragma omp atomic #pragma omp atomic
++_current_value; ++m_current_value;
printStatus(_current_value); printStatus(m_current_value);
} }
void printAddition(const unsigned addition) { void printAddition(const unsigned addition)
{
#pragma omp atomic #pragma omp atomic
_current_value += addition; m_current_value += addition;
printStatus(_current_value); printStatus(m_current_value);
} }
private:
unsigned _current_value;
unsigned _maxValue;
unsigned _intervalPercent;
unsigned _nextThreshold;
unsigned _lastPercent;
unsigned _step;
/** Displays the new progress. */ private:
void printPercent(double percent) { unsigned m_current_value;
while (percent >= _lastPercent+_step) { unsigned m_max_value;
_lastPercent+=_step; unsigned m_percent_interval;
if (_lastPercent % 10 == 0) { unsigned m_next_threshold;
std::cout << " " << _lastPercent << "% "; unsigned m_last_percent;
unsigned m_step;
// Displays progress.
void printPercent(double percent)
{
while (percent >= m_last_percent + m_step)
{
m_last_percent += m_step;
if (m_last_percent % 10 == 0)
{
std::cout << " " << m_last_percent << "% ";
} }
else { else
{
std::cout << "."; std::cout << ".";
} }
std::cout.flush(); std::cout.flush();

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef PHANTOMNODES_H_ #ifndef PHANTOM_NODES_H
#define PHANTOMNODES_H_ #define PHANTOM_NODES_H
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
@ -171,4 +171,4 @@ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
return out; return out;
} }
#endif /* PHANTOMNODES_H_ */ #endif // PHANTOM_NODES_H

View File

@ -30,34 +30,34 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h" #include "../typedefs.h"
struct QueryEdge { struct QueryEdge
{
NodeID source; NodeID source;
NodeID target; NodeID target;
struct EdgeData { struct EdgeData
NodeID id:31; {
bool shortcut:1; NodeID id : 31;
int distance:30; bool shortcut : 1;
bool forward:1; int distance : 30;
bool backward:1; bool forward : 1;
bool backward : 1;
} data; } data;
bool operator<( const QueryEdge& right ) const { bool operator<(const QueryEdge &right) const
if ( source != right.source ) { {
if (source != right.source)
{
return source < right.source; return source < right.source;
} }
return target < right.target; return target < right.target;
} }
bool operator== ( const QueryEdge& right ) const { bool operator==(const QueryEdge &right) const
return ( {
source == right.source && return (source == right.source && target == right.target &&
target == right.target && data.distance == right.data.distance && data.shortcut == right.data.shortcut &&
data.distance == right.data.distance && data.forward == right.data.forward && data.backward == right.data.backward &&
data.shortcut == right.data.shortcut && data.id == right.data.id);
data.forward == right.data.forward &&
data.backward == right.data.backward &&
data.id == right.data.id
);
} }
}; };

View File

@ -36,52 +36,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits> #include <limits>
struct NodeInfo { struct NodeInfo
typedef NodeID key_type; //type of NodeID {
typedef int value_type; //type of lat,lons typedef NodeID key_type; // type of NodeID
typedef int value_type; // type of lat,lons
NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) { } NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) {}
NodeInfo() NodeInfo()
: : lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
lat(std::numeric_limits<int>::max()), id(std::numeric_limits<unsigned>::max())
lon(std::numeric_limits<int>::max()), {
id(std::numeric_limits<unsigned>::max()) }
{ }
int lat; int lat;
int lon; int lon;
NodeID id; NodeID id;
static NodeInfo min_value() { static NodeInfo min_value()
return NodeInfo( {
-90*COORDINATE_PRECISION, return NodeInfo(-90 * COORDINATE_PRECISION,
-180*COORDINATE_PRECISION, -180 * COORDINATE_PRECISION,
std::numeric_limits<NodeID>::min() std::numeric_limits<NodeID>::min());
); }
}
static NodeInfo max_value() { static NodeInfo max_value()
return NodeInfo( {
90*COORDINATE_PRECISION, return NodeInfo(90 * COORDINATE_PRECISION,
180*COORDINATE_PRECISION, 180 * COORDINATE_PRECISION,
std::numeric_limits<NodeID>::max() std::numeric_limits<NodeID>::max());
); }
}
value_type operator[](const std::size_t n) const { value_type operator[](const std::size_t n) const
switch(n) { {
case 1: switch (n)
return lat; {
// break; case 1:
case 0: return lat;
return lon; case 0:
// break; return lon;
default: default:
break; break;
} }
BOOST_ASSERT_MSG(false, "should not happen"); BOOST_ASSERT_MSG(false, "should not happen");
return std::numeric_limits<unsigned>::max(); return std::numeric_limits<unsigned>::max();
} }
}; };
#endif //QUERY_NODE_H #endif // QUERY_NODE_H

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef RAWROUTEDATA_H_ #ifndef RAW_ROUTE_DATA_H
#define RAWROUTEDATA_H_ #define RAW_ROUTE_DATA_H
#include "../DataStructures/PhantomNodes.h" #include "../DataStructures/PhantomNodes.h"
#include "../typedefs.h" #include "../typedefs.h"
@ -37,53 +37,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector> #include <vector>
struct PathData { struct PathData
PathData() : {
node(UINT_MAX), PathData()
name_id(UINT_MAX), : node(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
durationOfSegment(UINT_MAX), segment_duration(std::numeric_limits<unsigned>::max()),
turnInstruction(UCHAR_MAX) turn_instruction(std::numeric_limits<unsigned char>::max())
{ } {
}
PathData( PathData(NodeID no, unsigned na, unsigned tu, unsigned dur)
NodeID no, : node(no), name_id(na), segment_duration(dur), turn_instruction(tu)
unsigned na, {
unsigned tu, }
unsigned dur
) :
node(no),
name_id(na),
durationOfSegment(dur),
turnInstruction(tu)
{ }
NodeID node; NodeID node;
unsigned name_id; unsigned name_id;
unsigned durationOfSegment; unsigned segment_duration;
short turnInstruction; short turn_instruction;
}; };
struct RawRouteData { struct RawRouteData
std::vector< std::vector<PathData> > unpacked_path_segments; {
std::vector< PathData > unpacked_alternative; std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector< PhantomNodes > segmentEndCoordinates; std::vector<PathData> unpacked_alternative;
std::vector< FixedPointCoordinate > rawViaNodeCoordinates; std::vector<PhantomNodes> segment_end_coordinates;
unsigned checkSum; std::vector<FixedPointCoordinate> raw_via_node_coordinates;
int lengthOfShortestPath; unsigned check_sum;
int lengthOfAlternativePath; int shortest_path_length;
int alternative_path_length;
bool source_traversed_in_reverse; bool source_traversed_in_reverse;
bool target_traversed_in_reverse; bool target_traversed_in_reverse;
bool alt_source_traversed_in_reverse; bool alt_source_traversed_in_reverse;
bool alt_target_traversed_in_reverse; bool alt_target_traversed_in_reverse;
RawRouteData() : RawRouteData()
checkSum(UINT_MAX), : check_sum(std::numeric_limits<unsigned>::max()),
lengthOfShortestPath(INT_MAX), shortest_path_length(std::numeric_limits<int>::max()),
lengthOfAlternativePath(INT_MAX), alternative_path_length(std::numeric_limits<int>::max()),
source_traversed_in_reverse(false), source_traversed_in_reverse(false), target_traversed_in_reverse(false),
target_traversed_in_reverse(false), alt_source_traversed_in_reverse(false), alt_target_traversed_in_reverse(false)
alt_source_traversed_in_reverse(false), {
alt_target_traversed_in_reverse(false) }
{ }
}; };
#endif /* RAWROUTEDATA_H_ */ #endif // RAW_ROUTE_DATA_H

View File

@ -33,7 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RouteParameters::RouteParameters() RouteParameters::RouteParameters()
: zoomLevel(18), printInstructions(false), alternateRoute(true), geometry(true), : zoomLevel(18), printInstructions(false), alternateRoute(true), geometry(true),
compression(true), deprecatedAPI(false), checkSum(-1) compression(true), deprecatedAPI(false), check_sum(-1)
{ {
} }
@ -49,7 +49,7 @@ void RouteParameters::setAlternateRouteFlag(const bool b) { alternateRoute = b;
void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; } void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }
void RouteParameters::setChecksum(const unsigned c) { checkSum = c; } void RouteParameters::setChecksum(const unsigned c) { check_sum = c; }
void RouteParameters::setInstructionFlag(const bool b) { printInstructions = b; } void RouteParameters::setInstructionFlag(const bool b) { printInstructions = b; }

View File

@ -29,40 +29,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SEARCHENGINE_H #define SEARCHENGINE_H
#include "SearchEngineData.h" #include "SearchEngineData.h"
#include "PhantomNodes.h"
#include "QueryEdge.h"
#include "../RoutingAlgorithms/AlternativePathRouting.h" #include "../RoutingAlgorithms/AlternativePathRouting.h"
#include "../RoutingAlgorithms/ShortestPathRouting.h" #include "../RoutingAlgorithms/ShortestPathRouting.h"
#include "../Util/StringUtil.h" template <class DataFacadeT> class SearchEngine
#include "../typedefs.h" {
private:
#include <osrm/Coordinate.h> DataFacadeT *facade;
#include <boost/assert.hpp>
#include <climits>
#include <string>
#include <vector>
template<class DataFacadeT>
class SearchEngine {
private:
DataFacadeT * facade;
SearchEngineData engine_working_data; SearchEngineData engine_working_data;
public:
ShortestPathRouting<DataFacadeT> shortest_path;
AlternativeRouting <DataFacadeT> alternative_path;
explicit SearchEngine( DataFacadeT * facade ) public:
: ShortestPathRouting<DataFacadeT> shortest_path;
facade (facade), AlternativeRouting<DataFacadeT> alternative_path;
shortest_path (facade, engine_working_data),
alternative_path (facade, engine_working_data) explicit SearchEngine(DataFacadeT *facade)
{} : facade(facade), shortest_path(facade, engine_working_data),
alternative_path(facade, engine_working_data)
{
}
~SearchEngine() {} ~SearchEngine() {}
}; };
#endif // SEARCHENGINE_H #endif // SEARCHENGINE_H

View File

@ -44,8 +44,6 @@ struct HeapData
/* explicit */ HeapData(NodeID p) : parent(p) {} /* explicit */ HeapData(NodeID p) : parent(p) {}
}; };
// typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
struct SearchEngineData struct SearchEngineData
{ {
typedef BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>> QueryHeap; typedef BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>> QueryHeap;

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SEGMENTINFORMATION_H_ #ifndef SEGMENT_INFORMATION_H
#define SEGMENTINFORMATION_H_ #define SEGMENT_INFORMATION_H
#include "TurnInstructions.h" #include "TurnInstructions.h"
@ -35,47 +35,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
// Struct fits everything in one cache line // Struct fits everything in one cache line
struct SegmentInformation { struct SegmentInformation
{
FixedPointCoordinate location; FixedPointCoordinate location;
NodeID name_id; NodeID name_id;
unsigned duration; unsigned duration;
double length; double length;
short bearing; //more than enough [0..3600] fits into 12 bits short bearing; // more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction; TurnInstruction turn_instruction;
bool necessary; bool necessary;
explicit SegmentInformation( explicit SegmentInformation(const FixedPointCoordinate &location,
const FixedPointCoordinate & location, const NodeID name_id,
const NodeID name_id, const unsigned duration,
const unsigned duration, const double length,
const double length, const TurnInstruction turn_instruction,
const TurnInstruction turn_instruction, const bool necessary)
const bool necessary : location(location), name_id(name_id), duration(duration), length(length), bearing(0),
) : turn_instruction(turn_instruction), necessary(necessary)
location(location), {
name_id(name_id), }
duration(duration),
length(length),
bearing(0),
turn_instruction(turn_instruction),
necessary(necessary)
{ }
explicit SegmentInformation( explicit SegmentInformation(const FixedPointCoordinate &location,
const FixedPointCoordinate & location, const NodeID name_id,
const NodeID name_id, const unsigned duration,
const unsigned duration, const double length,
const double length, const TurnInstruction turn_instruction)
const TurnInstruction turn_instruction : location(location), name_id(name_id), duration(duration), length(length), bearing(0),
) : turn_instruction(turn_instruction), necessary(turn_instruction != 0)
location(location), {
name_id(name_id), }
duration(duration),
length(length),
bearing(0),
turn_instruction(turn_instruction),
necessary(turn_instruction != 0)
{ }
}; };
#endif /* SEGMENTINFORMATION_H_ */ #endif /* SEGMENT_INFORMATION_H */

View File

@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/OSRMException.h" #include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/noncopyable.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/interprocess/mapped_region.hpp> #include <boost/interprocess/mapped_region.hpp>
@ -42,207 +41,191 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/shm.h> #include <sys/shm.h>
#endif #endif
#include <cstring> // #include <cstring>
#include <cstdint> #include <cstdint>
#include <algorithm> #include <algorithm>
#include <exception> #include <exception>
struct OSRMLockFile { struct OSRMLockFile
boost::filesystem::path operator()() { {
boost::filesystem::path temp_dir = boost::filesystem::path operator()()
boost::filesystem::temp_directory_path(); {
boost::filesystem::path lock_file = temp_dir / "osrm.lock"; boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
return lock_file; boost::filesystem::path lock_file = temp_dir / "osrm.lock";
} return lock_file;
}
}; };
class SharedMemory : boost::noncopyable { class SharedMemory
{
//Remove shared memory on destruction // Remove shared memory on destruction
class shm_remove : boost::noncopyable { class shm_remove
private: {
int m_shmid; private:
bool m_initialized; int m_shmid;
public: bool m_initialized;
void SetID(int shmid) {
m_shmid = shmid;
m_initialized = true;
}
shm_remove() : m_shmid(INT_MIN), m_initialized(false) {} public:
void SetID(int shmid)
{
m_shmid = shmid;
m_initialized = true;
}
~shm_remove(){ shm_remove() : m_shmid(INT_MIN), m_initialized(false) {}
if(m_initialized) { shm_remove(const shm_remove &) = delete;
SimpleLogger().Write(logDEBUG) << ~shm_remove()
"automatic memory deallocation"; {
if(!boost::interprocess::xsi_shared_memory::remove(m_shmid)) { if (m_initialized)
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid; {
} SimpleLogger().Write(logDEBUG) << "automatic memory deallocation";
} if (!boost::interprocess::xsi_shared_memory::remove(m_shmid))
} {
}; SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
}
}
}
};
public: public:
void * Ptr() const { void *Ptr() const { return region.get_address(); }
return region.get_address();
}
template<typename IdentifierT > SharedMemory() = delete;
SharedMemory( SharedMemory(const SharedMemory &) = delete;
const boost::filesystem::path & lock_file,
const IdentifierT id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true
) : key(
lock_file.string().c_str(),
id
) {
if( 0 == size ){ //read_only
shm = boost::interprocess::xsi_shared_memory (
boost::interprocess::open_only,
key
);
region = boost::interprocess::mapped_region ( template <typename IdentifierT>
shm, SharedMemory(const boost::filesystem::path &lock_file,
( const IdentifierT id,
read_write ? const uint64_t size = 0,
boost::interprocess::read_write : bool read_write = false,
boost::interprocess::read_only bool remove_prev = true)
) : key(lock_file.string().c_str(), id)
); {
} else { //writeable pointer if (0 == size)
//remove previously allocated mem { // read_only
if( remove_prev ) { shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key);
Remove(key);
} region = boost::interprocess::mapped_region(
shm = boost::interprocess::xsi_shared_memory ( shm,
boost::interprocess::open_or_create, (read_write ? boost::interprocess::read_write : boost::interprocess::read_only));
key, }
size else
); { // writeable pointer
// remove previously allocated mem
if (remove_prev)
{
Remove(key);
}
shm = boost::interprocess::xsi_shared_memory(
boost::interprocess::open_or_create, key, size);
#ifdef __linux__ #ifdef __linux__
if( -1 == shmctl(shm.get_shmid(), SHM_LOCK, 0) ) { if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, 0))
if( ENOMEM == errno ) { {
SimpleLogger().Write(logWARNING) << if (ENOMEM == errno)
"could not lock shared memory to RAM"; {
} SimpleLogger().Write(logWARNING) << "could not lock shared memory to RAM";
} }
}
#endif #endif
region = boost::interprocess::mapped_region ( region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
shm,
boost::interprocess::read_write
);
remover.SetID( shm.get_shmid() ); remover.SetID(shm.get_shmid());
SimpleLogger().Write(logDEBUG) << SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
"writeable memory allocated " << size << " bytes"; }
} }
}
template<typename IdentifierT > template <typename IdentifierT> static bool RegionExists(const IdentifierT id)
static bool RegionExists( {
const IdentifierT id bool result = true;
) { try
bool result = true; {
try { OSRMLockFile lock_file;
OSRMLockFile lock_file; boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
boost::interprocess::xsi_key key( lock_file().string().c_str(), id ); result = RegionExists(key);
result = RegionExists(key); }
} catch(...) { catch (...) { result = false; }
result = false; return result;
} }
return result;
}
template<typename IdentifierT > template <typename IdentifierT> static bool Remove(const IdentifierT id)
static bool Remove( {
const IdentifierT id OSRMLockFile lock_file;
) { boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
OSRMLockFile lock_file; return Remove(key);
boost::interprocess::xsi_key key( lock_file().string().c_str(), id ); }
return Remove(key);
}
private: private:
static bool RegionExists( const boost::interprocess::xsi_key &key ) { static bool RegionExists(const boost::interprocess::xsi_key &key)
bool result = true; {
try { bool result = true;
boost::interprocess::xsi_shared_memory shm( try { boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); }
boost::interprocess::open_only, catch (...) { result = false; }
key return result;
); }
} catch(...) {
result = false;
}
return result;
}
static bool Remove( static bool Remove(const boost::interprocess::xsi_key &key)
const boost::interprocess::xsi_key &key {
) { bool ret = false;
bool ret = false; try
try{ {
SimpleLogger().Write(logDEBUG) << "deallocating prev memory"; SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
boost::interprocess::xsi_shared_memory xsi( boost::interprocess::xsi_shared_memory xsi(boost::interprocess::open_only, key);
boost::interprocess::open_only, ret = boost::interprocess::xsi_shared_memory::remove(xsi.get_shmid());
key }
); catch (const boost::interprocess::interprocess_exception &e)
ret = boost::interprocess::xsi_shared_memory::remove(xsi.get_shmid()); {
} catch(const boost::interprocess::interprocess_exception &e){ if (e.get_error_code() != boost::interprocess::not_found_error)
if(e.get_error_code() != boost::interprocess::not_found_error) { {
throw; throw;
} }
} }
return ret; return ret;
} }
boost::interprocess::xsi_key key; boost::interprocess::xsi_key key;
boost::interprocess::xsi_shared_memory shm; boost::interprocess::xsi_shared_memory shm;
boost::interprocess::mapped_region region; boost::interprocess::mapped_region region;
shm_remove remover; shm_remove remover;
}; };
template<class LockFileT = OSRMLockFile> template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
class SharedMemoryFactory_tmpl : boost::noncopyable { {
public: public:
template <typename IdentifierT>
static SharedMemory *Get(const IdentifierT &id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true)
{
try
{
LockFileT lock_file;
if (!boost::filesystem::exists(lock_file()))
{
if (0 == size)
{
throw OSRMException("lock file does not exist, exiting");
}
else
{
boost::filesystem::ofstream ofs(lock_file());
ofs.close();
}
}
return new SharedMemory(lock_file(), id, size, read_write, remove_prev);
}
catch (const boost::interprocess::interprocess_exception &e)
{
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what() << ", code "
<< e.get_error_code();
throw OSRMException(e.what());
}
}
template<typename IdentifierT > SharedMemoryFactory_tmpl() = delete;
static SharedMemory * Get( SharedMemoryFactory_tmpl(const SharedMemoryFactory_tmpl &) = delete;
const IdentifierT & id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true
) {
try {
LockFileT lock_file;
if(!boost::filesystem::exists(lock_file()) ) {
if( 0 == size ) {
throw OSRMException("lock file does not exist, exiting");
} else {
boost::filesystem::ofstream ofs(lock_file());
ofs.close();
}
}
return new SharedMemory(
lock_file(),
id,
size,
read_write,
remove_prev
);
} catch(const boost::interprocess::interprocess_exception &e){
SimpleLogger().Write(logWARNING) <<
"caught exception: " << e.what() <<
", code " << e.get_error_code();
throw OSRMException(e.what());
}
}
private:
SharedMemoryFactory_tmpl() {}
}; };
typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory; typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory;

View File

@ -31,153 +31,114 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/type_traits.hpp>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <type_traits>
#include <vector> #include <vector>
template<typename DataT> template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT> { {
DataT * p; DataT *p;
public:
explicit ShMemIterator(DataT * x) : p(x) {} public:
ShMemIterator(const ShMemIterator & mit) : p(mit.p) {} explicit ShMemIterator(DataT *x) : p(x) {}
ShMemIterator& operator++() { ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
ShMemIterator &operator++()
{
++p; ++p;
return *this; return *this;
} }
ShMemIterator operator++(int) { ShMemIterator operator++(int)
{
ShMemIterator tmp(*this); ShMemIterator tmp(*this);
operator++(); operator++();
return tmp; return tmp;
} }
ShMemIterator operator+(std::ptrdiff_t diff) { ShMemIterator operator+(std::ptrdiff_t diff)
ShMemIterator tmp(p+diff); {
ShMemIterator tmp(p + diff);
return tmp; return tmp;
} }
bool operator==(const ShMemIterator& rhs) { bool operator==(const ShMemIterator &rhs) { return p == rhs.p; }
return p==rhs.p; bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
} DataT &operator*() { return *p; }
bool operator!=(const ShMemIterator& rhs) {
return p!=rhs.p;
}
DataT& operator*() {
return *p;
}
}; };
template<typename DataT> template <typename DataT> class SharedMemoryWrapper
class SharedMemoryWrapper { {
private: private:
DataT * m_ptr; DataT *m_ptr;
std::size_t m_size; std::size_t m_size;
public: public:
SharedMemoryWrapper() : SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
m_ptr(NULL),
m_size(0)
{ }
SharedMemoryWrapper(DataT * ptr, std::size_t size) : SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
m_ptr(ptr),
m_size(size)
{ }
void swap( SharedMemoryWrapper<DataT> & other ) { void swap(SharedMemoryWrapper<DataT> &other)
{
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid"); BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
std::swap( m_size, other.m_size); std::swap(m_size, other.m_size);
std::swap( m_ptr , other.m_ptr ); std::swap(m_ptr, other.m_ptr);
} }
// void SetData(const DataT * ptr, const std::size_t size) { DataT &at(const std::size_t index) { return m_ptr[index]; }
// BOOST_ASSERT_MSG( 0 == m_size, "vector not empty");
// BOOST_ASSERT_MSG( 0 < size , "new vector empty");
// m_ptr.reset(ptr);
// m_size = size;
// }
DataT & at(const std::size_t index) { const DataT &at(const std::size_t index) const { return m_ptr[index]; }
return m_ptr[index];
}
const DataT & at(const std::size_t index) const { ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }
return m_ptr[index];
}
ShMemIterator<DataT> begin() const { ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }
return ShMemIterator<DataT>(m_ptr);
}
ShMemIterator<DataT> end() const {
return ShMemIterator<DataT>(m_ptr+m_size);
}
std::size_t size() const { return m_size; } std::size_t size() const { return m_size; }
bool empty() const { return 0 == size(); } bool empty() const { return 0 == size(); }
DataT & operator[](const unsigned index) { DataT &operator[](const unsigned index)
{
BOOST_ASSERT_MSG(index < m_size, "invalid size"); BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index]; return m_ptr[index];
} }
const DataT & operator[](const unsigned index) const { const DataT &operator[](const unsigned index) const
{
BOOST_ASSERT_MSG(index < m_size, "invalid size"); BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index]; return m_ptr[index];
} }
}; };
template<> template <> class SharedMemoryWrapper<bool>
class SharedMemoryWrapper<bool> { {
private: private:
unsigned * m_ptr; unsigned *m_ptr;
std::size_t m_size; std::size_t m_size;
public: public:
SharedMemoryWrapper() : SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
m_ptr(NULL),
m_size(0)
{ }
SharedMemoryWrapper(unsigned * ptr, std::size_t size) : SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
m_ptr(ptr),
m_size(size)
{ }
void swap( SharedMemoryWrapper<bool> & other ) { void swap(SharedMemoryWrapper<bool> &other)
{
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid"); BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
std::swap( m_size, other.m_size); std::swap(m_size, other.m_size);
std::swap( m_ptr , other.m_ptr ); std::swap(m_ptr, other.m_ptr);
} }
// void SetData(const DataT * ptr, const std::size_t size) { bool at(const std::size_t index) const
// BOOST_ASSERT_MSG( 0 == m_size, "vector not empty"); {
// BOOST_ASSERT_MSG( 0 < size , "new vector empty");
// m_ptr.reset(ptr);
// m_size = size;
// }
bool at(const std::size_t index) const {
// BOOST_ASSERT_MSG(index < m_size, "invalid size");
const unsigned bucket = index / 32; const unsigned bucket = index / 32;
const unsigned offset = index % 32; const unsigned offset = index % 32;
return m_ptr[bucket] & (1 << offset); return m_ptr[bucket] & (1 << offset);
} }
// ShMemIterator<DataT> begin() const {
// return ShMemIterator<DataT>(m_ptr);
// }
// ShMemIterator<DataT> end() const {
// return ShMemIterator<DataT>(m_ptr+m_size);
// }
std::size_t size() const { return m_size; } std::size_t size() const { return m_size; }
bool empty() const { return 0 == size(); } bool empty() const { return 0 == size(); }
bool operator[](const unsigned index) { bool operator[](const unsigned index)
{
BOOST_ASSERT_MSG(index < m_size, "invalid size"); BOOST_ASSERT_MSG(index < m_size, "invalid size");
const unsigned bucket = index / 32; const unsigned bucket = index / 32;
const unsigned offset = index % 32; const unsigned offset = index % 32;
@ -185,13 +146,11 @@ public:
} }
}; };
template<typename DataT, bool UseSharedMemory> template <typename DataT, bool UseSharedMemory> struct ShM
struct ShM { {
typedef typename boost::conditional< typedef typename std::conditional<UseSharedMemory,
UseSharedMemory, SharedMemoryWrapper<DataT>,
SharedMemoryWrapper<DataT>, std::vector<DataT>>::type vector;
std::vector<DataT> };
>::type vector;
};
#endif //SHARED_MEMORY_VECTOR_WRAPPER_H #endif // SHARED_MEMORY_VECTOR_WRAPPER_H

View File

@ -36,17 +36,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stack> #include <stack>
#include <limits> #include <limits>
namespace KDTree { namespace KDTree
{
#define KDTREE_BASESIZE (8) #define KDTREE_BASESIZE (8)
template< unsigned k, typename T > template <unsigned k, typename T> class BoundingBox
class BoundingBox { {
public: public:
BoundingBox() { BoundingBox()
for ( unsigned dim = 0; dim < k; ++dim ) { {
min[dim] = std::numeric_limits< T >::min(); for (unsigned dim = 0; dim < k; ++dim)
max[dim] = std::numeric_limits< T >::max(); {
min[dim] = std::numeric_limits<T>::min();
max[dim] = std::numeric_limits<T>::max();
} }
} }
@ -54,102 +57,118 @@ public:
T max[k]; T max[k];
}; };
struct NoData {}; struct NoData
{
};
template< unsigned k, typename T > template <unsigned k, typename T> class EuclidianMetric
class EuclidianMetric { {
public: public:
double operator() ( const T left[k], const T right[k] ) { double operator()(const T left[k], const T right[k])
{
double result = 0; double result = 0;
for ( unsigned i = 0; i < k; ++i ) { for (unsigned i = 0; i < k; ++i)
{
double temp = (double)left[i] - (double)right[i]; double temp = (double)left[i] - (double)right[i];
result += temp * temp; result += temp * temp;
} }
return result; return result;
} }
double operator() ( const BoundingBox< k, T > &box, const T point[k] ) { double operator()(const BoundingBox<k, T> &box, const T point[k])
{
T nearest[k]; T nearest[k];
for ( unsigned dim = 0; dim < k; ++dim ) { for (unsigned dim = 0; dim < k; ++dim)
if ( point[dim] < box.min[dim] ) {
if (point[dim] < box.min[dim])
nearest[dim] = box.min[dim]; nearest[dim] = box.min[dim];
else if ( point[dim] > box.max[dim] ) else if (point[dim] > box.max[dim])
nearest[dim] = box.max[dim]; nearest[dim] = box.max[dim];
else else
nearest[dim] = point[dim]; nearest[dim] = point[dim];
} }
return operator() ( point, nearest ); return operator()(point, nearest);
} }
}; };
template < unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric< k, T > > template <unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric<k, T>>
class StaticKDTree { class StaticKDTree
public: {
public:
struct InputPoint { struct InputPoint
{
T coordinates[k]; T coordinates[k];
Data data; Data data;
bool operator==( const InputPoint& right ) bool operator==(const InputPoint &right)
{ {
for ( int i = 0; i < k; i++ ) { for (int i = 0; i < k; i++)
if ( coordinates[i] != right.coordinates[i] ) {
if (coordinates[i] != right.coordinates[i])
return false; return false;
} }
return true; return true;
} }
}; };
explicit StaticKDTree( std::vector< InputPoint > * points ){ explicit StaticKDTree(std::vector<InputPoint> *points)
BOOST_ASSERT( k > 0 ); {
BOOST_ASSERT ( points->size() > 0 ); BOOST_ASSERT(k > 0);
BOOST_ASSERT(points->size() > 0);
size = points->size(); size = points->size();
kdtree = new InputPoint[size]; kdtree = new InputPoint[size];
for ( Iterator i = 0; i != size; ++i ) { for (Iterator i = 0; i != size; ++i)
{
kdtree[i] = points->at(i); kdtree[i] = points->at(i);
for ( unsigned dim = 0; dim < k; ++dim ) { for (unsigned dim = 0; dim < k; ++dim)
if ( kdtree[i].coordinates[dim] < boundingBox.min[dim] ) {
if (kdtree[i].coordinates[dim] < boundingBox.min[dim])
boundingBox.min[dim] = kdtree[i].coordinates[dim]; boundingBox.min[dim] = kdtree[i].coordinates[dim];
if ( kdtree[i].coordinates[dim] > boundingBox.max[dim] ) if (kdtree[i].coordinates[dim] > boundingBox.max[dim])
boundingBox.max[dim] = kdtree[i].coordinates[dim]; boundingBox.max[dim] = kdtree[i].coordinates[dim];
} }
} }
std::stack< Tree > s; std::stack<Tree> s;
s.push ( Tree ( 0, size, 0 ) ); s.push(Tree(0, size, 0));
while ( !s.empty() ) { while (!s.empty())
{
Tree tree = s.top(); Tree tree = s.top();
s.pop(); s.pop();
if ( tree.right - tree.left < KDTREE_BASESIZE ) if (tree.right - tree.left < KDTREE_BASESIZE)
continue; continue;
Iterator middle = tree.left + ( tree.right - tree.left ) / 2; Iterator middle = tree.left + (tree.right - tree.left) / 2;
std::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) ); std::nth_element(
s.push( Tree( tree.left, middle, ( tree.dimension + 1 ) % k ) ); kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less(tree.dimension));
s.push( Tree( middle + 1, tree.right, ( tree.dimension + 1 ) % k ) ); s.push(Tree(tree.left, middle, (tree.dimension + 1) % k));
s.push(Tree(middle + 1, tree.right, (tree.dimension + 1) % k));
} }
} }
~StaticKDTree(){ ~StaticKDTree() { delete[] kdtree; }
delete[] kdtree;
}
bool NearestNeighbor( InputPoint* result, const InputPoint& point ) { bool NearestNeighbor(InputPoint *result, const InputPoint &point)
{
Metric distance; Metric distance;
bool found = false; bool found = false;
double nearestDistance = std::numeric_limits< T >::max(); double nearestDistance = std::numeric_limits<T>::max();
std::stack< NNTree > s; std::stack<NNTree> s;
s.push ( NNTree ( 0, size, 0, boundingBox ) ); s.push(NNTree(0, size, 0, boundingBox));
while ( !s.empty() ) { while (!s.empty())
{
NNTree tree = s.top(); NNTree tree = s.top();
s.pop(); s.pop();
if ( distance( tree.box, point.coordinates ) >= nearestDistance ) if (distance(tree.box, point.coordinates) >= nearestDistance)
continue; continue;
if ( tree.right - tree.left < KDTREE_BASESIZE ) { if (tree.right - tree.left < KDTREE_BASESIZE)
for ( unsigned i = tree.left; i < tree.right; i++ ) { {
double newDistance = distance( kdtree[i].coordinates, point.coordinates ); for (unsigned i = tree.left; i < tree.right; i++)
if ( newDistance < nearestDistance ) { {
double newDistance = distance(kdtree[i].coordinates, point.coordinates);
if (newDistance < nearestDistance)
{
nearestDistance = newDistance; nearestDistance = newDistance;
*result = kdtree[i]; *result = kdtree[i];
found = true; found = true;
@ -158,73 +177,84 @@ public:
continue; continue;
} }
Iterator middle = tree.left + ( tree.right - tree.left ) / 2; Iterator middle = tree.left + (tree.right - tree.left) / 2;
double newDistance = distance( kdtree[middle].coordinates, point.coordinates ); double newDistance = distance(kdtree[middle].coordinates, point.coordinates);
if ( newDistance < nearestDistance ) { if (newDistance < nearestDistance)
{
nearestDistance = newDistance; nearestDistance = newDistance;
*result = kdtree[middle]; *result = kdtree[middle];
found = true; found = true;
} }
Less comperator( tree.dimension ); Less comperator(tree.dimension);
if ( !comperator( point, kdtree[middle] ) ) { if (!comperator(point, kdtree[middle]))
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box ); {
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box ); NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension]; first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension]; second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( second ); s.push(second);
s.push( first ); s.push(first);
} }
else { else
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box ); {
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box ); NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension]; first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension]; second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( first ); s.push(first);
s.push( second ); s.push(second);
} }
} }
return found; return found;
} }
private: private:
typedef unsigned Iterator; typedef unsigned Iterator;
struct Tree { struct Tree
{
Iterator left; Iterator left;
Iterator right; Iterator right;
unsigned dimension; unsigned dimension;
Tree() {} Tree() {}
Tree( Iterator l, Iterator r, unsigned d ): left( l ), right( r ), dimension( d ) {} Tree(Iterator l, Iterator r, unsigned d) : left(l), right(r), dimension(d) {}
}; };
struct NNTree { struct NNTree
{
Iterator left; Iterator left;
Iterator right; Iterator right;
unsigned dimension; unsigned dimension;
BoundingBox< k, T > box; BoundingBox<k, T> box;
NNTree() {} NNTree() {}
NNTree( Iterator l, Iterator r, unsigned d, const BoundingBox< k, T >& b ): left( l ), right( r ), dimension( d ), box ( b ) {} NNTree(Iterator l, Iterator r, unsigned d, const BoundingBox<k, T> &b)
: left(l), right(r), dimension(d), box(b)
{
}
}; };
class Less { class Less
public: {
explicit Less( unsigned d ) { public:
explicit Less(unsigned d)
{
dimension = d; dimension = d;
BOOST_ASSERT( dimension < k ); BOOST_ASSERT(dimension < k);
} }
bool operator() ( const InputPoint& left, const InputPoint& right ) { bool operator()(const InputPoint &left, const InputPoint &right)
BOOST_ASSERT( dimension < k ); {
BOOST_ASSERT(dimension < k);
return left.coordinates[dimension] < right.coordinates[dimension]; return left.coordinates[dimension] < right.coordinates[dimension];
} }
private:
private:
unsigned dimension; unsigned dimension;
}; };
BoundingBox< k, T > boundingBox; BoundingBox<k, T> boundingBox;
InputPoint* kdtree; InputPoint *kdtree;
Iterator size; Iterator size;
}; };
} }
#endif // STATICKDTREE_H_INCLUDED #endif // STATICKDTREE_H_INCLUDED

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef STATICRTREE_H_ #ifndef STATICRTREE_H
#define STATICRTREE_H_ #define STATICRTREE_H
#include "DeallocatingVector.h" #include "DeallocatingVector.h"
#include "HilbertValue.h" #include "HilbertValue.h"
@ -45,7 +45,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
@ -67,7 +66,7 @@ static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtre
template <class DataT, template <class DataT,
class CoordinateListT = std::vector<FixedPointCoordinate>, class CoordinateListT = std::vector<FixedPointCoordinate>,
bool UseSharedMemory = false> bool UseSharedMemory = false>
class StaticRTree : boost::noncopyable class StaticRTree
{ {
public: public:
struct RectangleInt2D struct RectangleInt2D
@ -269,6 +268,9 @@ class StaticRTree : boost::noncopyable
boost::shared_ptr<CoordinateListT> m_coordinate_list; boost::shared_ptr<CoordinateListT> m_coordinate_list;
public: public:
StaticRTree() = delete;
StaticRTree(const StaticRTree &) = delete;
// Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1] // Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
explicit StaticRTree(std::vector<DataT> &input_data_vector, explicit StaticRTree(std::vector<DataT> &input_data_vector,
const std::string tree_node_filename, const std::string tree_node_filename,
@ -524,7 +526,7 @@ class StaticRTree : boost::noncopyable
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i) for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
{ {
DataT const &current_edge = current_leaf_node.objects[i]; DataT const &current_edge = current_leaf_node.objects[i];
if (ignore_tiny_components && current_edge.belongsToTinyComponent) if (ignore_tiny_components && current_edge.is_in_tiny_cc)
{ {
continue; continue;
} }
@ -637,7 +639,7 @@ class StaticRTree : boost::noncopyable
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i) for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
{ {
DataT &current_edge = current_leaf_node.objects[i]; DataT &current_edge = current_leaf_node.objects[i];
if (ignore_tiny_components && current_edge.belongsToTinyComponent) if (ignore_tiny_components && current_edge.is_in_tiny_cc)
{ {
continue; continue;
} }
@ -784,4 +786,4 @@ class StaticRTree : boost::noncopyable
//[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403 //[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
//[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794 //[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794
#endif /* STATICRTREE_H_ */ #endif // STATICRTREE_H

View File

@ -25,18 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef TURNINSTRUCTIONS_H_ #ifndef TURN_INSTRUCTIONS_H
#define TURNINSTRUCTIONS_H_ #define TURN_INSTRUCTIONS_H
#include <boost/noncopyable.hpp>
typedef unsigned char TurnInstruction; typedef unsigned char TurnInstruction;
//This is a hack until c++0x is available enough to use scoped enums // This is a hack until c++0x is available enough to use scoped enums
struct TurnInstructionsClass : boost::noncopyable { struct TurnInstructionsClass
{
TurnInstructionsClass() = delete;
TurnInstructionsClass(const TurnInstructionsClass&) = delete;
const static TurnInstruction NoTurn = 0; //Give no instruction at all const static TurnInstruction NoTurn = 0; // Give no instruction at all
const static TurnInstruction GoStraight = 1; //Tell user to go straight! const static TurnInstruction GoStraight = 1; // Tell user to go straight!
const static TurnInstruction TurnSlightRight = 2; const static TurnInstruction TurnSlightRight = 2;
const static TurnInstruction TurnRight = 3; const static TurnInstruction TurnRight = 3;
const static TurnInstruction TurnSharpRight = 4; const static TurnInstruction TurnSharpRight = 4;
@ -55,41 +56,51 @@ struct TurnInstructionsClass : boost::noncopyable {
const static TurnInstruction LeaveAgainstAllowedDirection = 17; const static TurnInstruction LeaveAgainstAllowedDirection = 17;
const static TurnInstruction AccessRestrictionFlag = 128; const static TurnInstruction AccessRestrictionFlag = 128;
const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning. const static TurnInstruction InverseAccessRestrictionFlag =
0x7f; // ~128 does not work without a warning.
const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag const static int AccessRestrictionPenalty =
1 << 15; // unrelated to the bit set in the restriction flag
static inline TurnInstruction GetTurnDirectionOfInstruction( const double angle ) { static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle)
if(angle >= 23 && angle < 67) { {
if (angle >= 23 && angle < 67)
{
return TurnSharpRight; return TurnSharpRight;
} }
if (angle >= 67 && angle < 113) { if (angle >= 67 && angle < 113)
{
return TurnRight; return TurnRight;
} }
if (angle >= 113 && angle < 158) { if (angle >= 113 && angle < 158)
{
return TurnSlightRight; return TurnSlightRight;
} }
if (angle >= 158 && angle < 202) { if (angle >= 158 && angle < 202)
{
return GoStraight; return GoStraight;
} }
if (angle >= 202 && angle < 248) { if (angle >= 202 && angle < 248)
{
return TurnSlightLeft; return TurnSlightLeft;
} }
if (angle >= 248 && angle < 292) { if (angle >= 248 && angle < 292)
{
return TurnLeft; return TurnLeft;
} }
if (angle >= 292 && angle < 336) { if (angle >= 292 && angle < 336)
{
return TurnSharpLeft; return TurnSharpLeft;
} }
return UTurn; return UTurn;
} }
static inline bool TurnIsNecessary ( const short turnInstruction ) { static inline bool TurnIsNecessary(const short turnInstruction)
if(NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction) {
if (NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction)
return false; return false;
return true; return true;
} }
}; };
#endif /* TURNINSTRUCTIONS_H_ */ #endif /* TURN_INSTRUCTIONS_H */

View File

@ -25,14 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef FASTXORHASH_H_ #ifndef XOR_FAST_HASH_H
#define FASTXORHASH_H_ #define XOR_FAST_HASH_H
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
/* /*
This is an implementation of Tabulation hashing, which has suprising properties like universality. This is an implementation of Tabulation hashing, which has suprising properties like
universality.
The space requirement is 2*2^16 = 256 kb of memory, which fits into L2 cache. The space requirement is 2*2^16 = 256 kb of memory, which fits into L2 cache.
Evaluation boils down to 10 or less assembly instruction on any recent X86 CPU: Evaluation boils down to 10 or less assembly instruction on any recent X86 CPU:
@ -48,49 +49,61 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10: ret 10: ret
*/ */
class XORFastHash { //65k entries class XORFastHash
{ // 65k entries
std::vector<unsigned short> table1; std::vector<unsigned short> table1;
std::vector<unsigned short> table2; std::vector<unsigned short> table2;
public:
XORFastHash() { public:
XORFastHash()
{
table1.resize(2 << 16); table1.resize(2 << 16);
table2.resize(2 << 16); table2.resize(2 << 16);
for(unsigned i = 0; i < (2 << 16); ++i) { for (unsigned i = 0; i < (2 << 16); ++i)
table1[i] = i; table2[i] = i; {
table1[i] = i;
table2[i] = i;
} }
std::random_shuffle(table1.begin(), table1.end()); std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end()); std::random_shuffle(table2.begin(), table2.end());
} }
inline unsigned short operator()(const unsigned originalValue) const { inline unsigned short operator()(const unsigned originalValue) const
{
unsigned short lsb = ((originalValue) & 0xffff); unsigned short lsb = ((originalValue) & 0xffff);
unsigned short msb = (((originalValue) >> 16) & 0xffff); unsigned short msb = (((originalValue) >> 16) & 0xffff);
return table1[lsb] ^ table2[msb]; return table1[lsb] ^ table2[msb];
} }
}; };
class XORMiniHash { //256 entries class XORMiniHash
{ // 256 entries
std::vector<unsigned char> table1; std::vector<unsigned char> table1;
std::vector<unsigned char> table2; std::vector<unsigned char> table2;
std::vector<unsigned char> table3; std::vector<unsigned char> table3;
std::vector<unsigned char> table4; std::vector<unsigned char> table4;
public: public:
XORMiniHash() { XORMiniHash()
{
table1.resize(1 << 8); table1.resize(1 << 8);
table2.resize(1 << 8); table2.resize(1 << 8);
table3.resize(1 << 8); table3.resize(1 << 8);
table4.resize(1 << 8); table4.resize(1 << 8);
for(unsigned i = 0; i < (1 << 8); ++i) { for (unsigned i = 0; i < (1 << 8); ++i)
table1[i] = i; table2[i] = i; {
table3[i] = i; table4[i] = i; table1[i] = i;
table2[i] = i;
table3[i] = i;
table4[i] = i;
} }
std::random_shuffle(table1.begin(), table1.end()); std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end()); std::random_shuffle(table2.begin(), table2.end());
std::random_shuffle(table3.begin(), table3.end()); std::random_shuffle(table3.begin(), table3.end());
std::random_shuffle(table4.begin(), table4.end()); std::random_shuffle(table4.begin(), table4.end());
} }
unsigned char operator()(const unsigned originalValue) const { unsigned char operator()(const unsigned originalValue) const
{
unsigned char byte1 = ((originalValue) & 0xff); unsigned char byte1 = ((originalValue) & 0xff);
unsigned char byte2 = ((originalValue >> 8) & 0xff); unsigned char byte2 = ((originalValue >> 8) & 0xff);
unsigned char byte3 = ((originalValue >> 16) & 0xff); unsigned char byte3 = ((originalValue >> 16) & 0xff);
@ -99,4 +112,4 @@ public:
} }
}; };
#endif /* FASTXORHASH_H_ */ #endif // XOR_FAST_HASH_H

View File

@ -25,63 +25,65 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef XORFASTHASHSTORAGE_H_ #ifndef XOR_FAST_HASH_STORAGE_H
#define XORFASTHASHSTORAGE_H_ #define XOR_FAST_HASH_STORAGE_H
#include "XORFastHash.h" #include "XORFastHash.h"
#include <climits> #include <limits>
#include <vector> #include <vector>
#include <bitset>
template< typename NodeID, typename Key > template <typename NodeID, typename Key> class XORFastHashStorage
class XORFastHashStorage { {
public: public:
struct HashCell{ struct HashCell
{
Key key; Key key;
NodeID id; NodeID id;
unsigned time; unsigned time;
HashCell() : key(UINT_MAX), id(UINT_MAX), time(UINT_MAX) {} HashCell()
: key(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
HashCell(const HashCell & other) : key(other.key), id(other.id), time(other.time) { } time(std::numeric_limits<unsigned>::max())
{
inline operator Key() const {
return key;
} }
inline void operator=(const Key & keyToInsert) { HashCell(const HashCell &other) : key(other.key), id(other.id), time(other.time) {}
key = keyToInsert;
} inline operator Key() const { return key; }
inline void operator=(const Key &key_to_insert) { key = key_to_insert; }
}; };
explicit XORFastHashStorage( size_t ) : positions(2<<16), currentTimestamp(0) { } explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
inline HashCell& operator[]( const NodeID node ) { inline HashCell &operator[](const NodeID node)
unsigned short position = fastHash(node); {
while((positions[position].time == currentTimestamp) && (positions[position].id != node)){ unsigned short position = fast_hasher(node);
++position %= (2<<16); while ((positions[position].time == current_timestamp) && (positions[position].id != node))
{
++position %= (2 << 16);
} }
positions[position].id = node; positions[position].id = node;
positions[position].time = currentTimestamp; positions[position].time = current_timestamp;
return positions[position]; return positions[position];
} }
inline void Clear() { inline void Clear()
++currentTimestamp; {
if(UINT_MAX == currentTimestamp) { ++current_timestamp;
if (std::numeric_limits<unsigned>::max() == current_timestamp)
{
positions.clear(); positions.clear();
positions.resize((2<<16)); positions.resize((2 << 16));
} }
} }
private: private:
XORFastHashStorage() : positions(2<<16), currentTimestamp(0) {} XORFastHashStorage() : positions(2 << 16), current_timestamp(0) {}
std::vector<HashCell> positions; std::vector<HashCell> positions;
XORFastHash fastHash; XORFastHash fast_hasher;
unsigned currentTimestamp; unsigned current_timestamp;
}; };
#endif // XOR_FAST_HASH_STORAGE_H
#endif /* XORFASTHASHSTORAGE_H_ */

View File

@ -90,9 +90,9 @@ void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
{ {
path_description.push_back(SegmentInformation(coordinate, path_description.push_back(SegmentInformation(coordinate,
path_point.name_id, path_point.name_id,
path_point.durationOfSegment, path_point.segment_duration,
0, 0,
path_point.turnInstruction)); path_point.turn_instruction));
} }
} }

View File

@ -57,7 +57,7 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
" OpenStreetMap contributors (ODbL)</license></copyright>" " OpenStreetMap contributors (ODbL)</license></copyright>"
"</metadata>"); "</metadata>");
reply.content.push_back("<rte>"); reply.content.push_back("<rte>");
bool found_route = (raw_route.lengthOfShortestPath != INVALID_EDGE_WEIGHT) && bool found_route = (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT) &&
(!raw_route.unpacked_path_segments.front().empty()); (!raw_route.unpacked_path_segments.front().empty());
if (found_route) if (found_route)
{ {

View File

@ -110,7 +110,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
facade = f; facade = f;
reply.content.push_back("{\"status\":"); reply.content.push_back("{\"status\":");
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath) if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{ {
// We do not need to do much, if there is no route ;-) // We do not need to do much, if there is no route ;-)
reply.content.push_back( reply.content.push_back(
@ -118,14 +118,14 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
return; return;
} }
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath; SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.shortest_path_length;
// check if first segment is non-zero // check if first segment is non-zero
std::string road_name = std::string road_name =
facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id); facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
BOOST_ASSERT(raw_route.unpacked_path_segments.size() == BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
raw_route.segmentEndCoordinates.size()); raw_route.segment_end_coordinates.size());
description_factory.SetStartSegment(phantom_nodes.source_phantom, description_factory.SetStartSegment(phantom_nodes.source_phantom,
raw_route.source_traversed_in_reverse); raw_route.source_traversed_in_reverse);
@ -136,7 +136,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i) for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
{ {
const int added_segments = DescribeLeg(raw_route.unpacked_path_segments[i], const int added_segments = DescribeLeg(raw_route.unpacked_path_segments[i],
raw_route.segmentEndCoordinates[i]); raw_route.segment_end_coordinates[i]);
BOOST_ASSERT(0 < added_segments); BOOST_ASSERT(0 < added_segments);
shortest_leg_end_indices.push_back(added_segments + shortest_leg_end_indices.back()); shortest_leg_end_indices.push_back(added_segments + shortest_leg_end_indices.back());
} }
@ -159,13 +159,13 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
{ {
BuildTextualDescription(description_factory, BuildTextualDescription(description_factory,
reply, reply,
raw_route.lengthOfShortestPath, raw_route.shortest_path_length,
facade, facade,
shortest_path_segments); shortest_path_segments);
} }
reply.content.push_back("],"); reply.content.push_back("],");
description_factory.BuildRouteSummary(description_factory.entireLength, description_factory.BuildRouteSummary(description_factory.entireLength,
raw_route.lengthOfShortestPath); raw_route.shortest_path_length);
reply.content.push_back("\"route_summary\":"); reply.content.push_back("\"route_summary\":");
reply.content.push_back("{"); reply.content.push_back("{");
@ -187,7 +187,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
reply.content.push_back(","); reply.content.push_back(",");
// only one alternative route is computed at this time, so this is hardcoded // only one alternative route is computed at this time, so this is hardcoded
if (raw_route.lengthOfAlternativePath != INVALID_EDGE_WEIGHT) if (raw_route.alternative_path_length != INVALID_EDGE_WEIGHT)
{ {
alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom, alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom,
raw_route.alt_source_traversed_in_reverse); raw_route.alt_source_traversed_in_reverse);
@ -204,7 +204,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
// //give an array of alternative routes // //give an array of alternative routes
reply.content.push_back("\"alternative_geometries\": ["); reply.content.push_back("\"alternative_geometries\": [");
if (config.geometry && INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath) if (config.geometry && INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{ {
// Generate the linestrings for each alternative // Generate the linestrings for each alternative
alternate_descriptionFactory.AppendEncodedPolylineString(config.encode_geometry, alternate_descriptionFactory.AppendEncodedPolylineString(config.encode_geometry,
@ -212,7 +212,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
} }
reply.content.push_back("],"); reply.content.push_back("],");
reply.content.push_back("\"alternative_instructions\":["); reply.content.push_back("\"alternative_instructions\":[");
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath) if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{ {
reply.content.push_back("["); reply.content.push_back("[");
// Generate instructions for each alternative // Generate instructions for each alternative
@ -220,7 +220,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
{ {
BuildTextualDescription(alternate_descriptionFactory, BuildTextualDescription(alternate_descriptionFactory,
reply, reply,
raw_route.lengthOfAlternativePath, raw_route.alternative_path_length,
facade, facade,
alternative_path_segments); alternative_path_segments);
} }
@ -228,11 +228,11 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
} }
reply.content.push_back("],"); reply.content.push_back("],");
reply.content.push_back("\"alternative_summaries\":["); reply.content.push_back("\"alternative_summaries\":[");
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath) if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{ {
// Generate route summary (length, duration) for each alternative // Generate route summary (length, duration) for each alternative
alternate_descriptionFactory.BuildRouteSummary( alternate_descriptionFactory.BuildRouteSummary(
alternate_descriptionFactory.entireLength, raw_route.lengthOfAlternativePath); alternate_descriptionFactory.entireLength, raw_route.alternative_path_length);
reply.content.push_back("{"); reply.content.push_back("{");
reply.content.push_back("\"total_distance\":"); reply.content.push_back("\"total_distance\":");
reply.content.push_back(alternate_descriptionFactory.summary.lengthString); reply.content.push_back(alternate_descriptionFactory.summary.lengthString);
@ -271,16 +271,16 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
// list all viapoints so that the client may display it // list all viapoints so that the client may display it
reply.content.push_back("\"via_points\":["); reply.content.push_back("\"via_points\":[");
BOOST_ASSERT(!raw_route.segmentEndCoordinates.empty()); BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
std::string tmp; std::string tmp;
FixedPointCoordinate::convertInternalReversedCoordinateToString( FixedPointCoordinate::convertInternalReversedCoordinateToString(
raw_route.segmentEndCoordinates.front().source_phantom.location, tmp); raw_route.segment_end_coordinates.front().source_phantom.location, tmp);
reply.content.push_back("["); reply.content.push_back("[");
reply.content.push_back(tmp); reply.content.push_back(tmp);
reply.content.push_back("]"); reply.content.push_back("]");
for (const PhantomNodes &nodes : raw_route.segmentEndCoordinates) for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
{ {
tmp.clear(); tmp.clear();
FixedPointCoordinate::convertInternalReversedCoordinateToString( FixedPointCoordinate::convertInternalReversedCoordinateToString(
@ -303,7 +303,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
} }
} }
reply.content.push_back("],\"alternative_indices\":["); reply.content.push_back("],\"alternative_indices\":[");
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath) if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{ {
reply.content.push_back("0,"); reply.content.push_back("0,");
tmp.clear(); tmp.clear();
@ -314,19 +314,19 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
reply.content.push_back("],"); reply.content.push_back("],");
reply.content.push_back("\"hint_data\": {"); reply.content.push_back("\"hint_data\": {");
reply.content.push_back("\"checksum\":"); reply.content.push_back("\"checksum\":");
intToString(raw_route.checkSum, tmp); intToString(raw_route.check_sum, tmp);
reply.content.push_back(tmp); reply.content.push_back(tmp);
reply.content.push_back(", \"locations\": ["); reply.content.push_back(", \"locations\": [");
std::string hint; std::string hint;
for (unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i) for (unsigned i = 0; i < raw_route.segment_end_coordinates.size(); ++i)
{ {
reply.content.push_back("\""); reply.content.push_back("\"");
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].source_phantom, hint); EncodeObjectToBase64(raw_route.segment_end_coordinates[i].source_phantom, hint);
reply.content.push_back(hint); reply.content.push_back(hint);
reply.content.push_back("\", "); reply.content.push_back("\", ");
} }
EncodeObjectToBase64(raw_route.segmentEndCoordinates.back().target_phantom, hint); EncodeObjectToBase64(raw_route.segment_end_coordinates.back().target_phantom, hint);
reply.content.push_back("\""); reply.content.push_back("\"");
reply.content.push_back(hint); reply.content.push_back(hint);
reply.content.push_back("\"]"); reply.content.push_back("\"]");

View File

@ -71,7 +71,7 @@ struct RouteParameters
bool geometry; bool geometry;
bool compression; bool compression;
bool deprecatedAPI; bool deprecatedAPI;
unsigned checkSum; unsigned check_sum;
std::string service; std::string service;
std::string outputFormat; std::string outputFormat;
std::string jsonpParameter; std::string jsonpParameter;

View File

@ -53,7 +53,7 @@ class HelloWorldPlugin : public BasePlugin
intToString(routeParameters.zoomLevel, temp_string); intToString(routeParameters.zoomLevel, temp_string);
reply.content.push_back(temp_string); reply.content.push_back(temp_string);
reply.content.push_back("\nchecksum: "); reply.content.push_back("\nchecksum: ");
intToString(routeParameters.checkSum, temp_string); intToString(routeParameters.check_sum, temp_string);
reply.content.push_back(temp_string); reply.content.push_back(temp_string);
reply.content.push_back("\ninstructions: "); reply.content.push_back("\ninstructions: ");
reply.content.push_back((routeParameters.printInstructions ? "yes" : "no")); reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));

View File

@ -76,7 +76,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
} }
RawRouteData raw_route; RawRouteData raw_route;
raw_route.checkSum = facade->GetCheckSum(); raw_route.check_sum = facade->GetCheckSum();
if (std::any_of(begin(routeParameters.coordinates), if (std::any_of(begin(routeParameters.coordinates),
end(routeParameters.coordinates), end(routeParameters.coordinates),
@ -89,13 +89,13 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
for (const FixedPointCoordinate &coordinate : routeParameters.coordinates) for (const FixedPointCoordinate &coordinate : routeParameters.coordinates)
{ {
raw_route.rawViaNodeCoordinates.emplace_back(coordinate); raw_route.raw_via_node_coordinates.emplace_back(coordinate);
} }
std::vector<PhantomNode> phantom_node_vector(raw_route.rawViaNodeCoordinates.size()); std::vector<PhantomNode> phantom_node_vector(raw_route.raw_via_node_coordinates.size());
const bool checksum_OK = (routeParameters.checkSum == raw_route.checkSum); const bool checksum_OK = (routeParameters.check_sum == raw_route.check_sum);
for (unsigned i = 0; i < raw_route.rawViaNodeCoordinates.size(); ++i) for (unsigned i = 0; i < raw_route.raw_via_node_coordinates.size(); ++i)
{ {
if (checksum_OK && i < routeParameters.hints.size() && if (checksum_OK && i < routeParameters.hints.size() &&
!routeParameters.hints[i].empty()) !routeParameters.hints[i].empty())
@ -106,7 +106,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
continue; continue;
} }
} }
facade->FindPhantomNodeForCoordinate(raw_route.rawViaNodeCoordinates[i], facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
phantom_node_vector[i], phantom_node_vector[i],
routeParameters.zoomLevel); routeParameters.zoomLevel);
} }
@ -116,19 +116,19 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
{ {
current_phantom_node_pair.source_phantom = phantom_node_vector[i]; current_phantom_node_pair.source_phantom = phantom_node_vector[i];
current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1]; current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1];
raw_route.segmentEndCoordinates.emplace_back(current_phantom_node_pair); raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair);
} }
if ((routeParameters.alternateRoute) && (1 == raw_route.segmentEndCoordinates.size())) if ((routeParameters.alternateRoute) && (1 == raw_route.segment_end_coordinates.size()))
{ {
search_engine_ptr->alternative_path(raw_route.segmentEndCoordinates.front(), raw_route); search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(), raw_route);
} }
else else
{ {
search_engine_ptr->shortest_path(raw_route.segmentEndCoordinates, raw_route); search_engine_ptr->shortest_path(raw_route.segment_end_coordinates, raw_route);
} }
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath) if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{ {
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found"; SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
} }
@ -165,8 +165,8 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
} }
PhantomNodes phantom_nodes; PhantomNodes phantom_nodes;
phantom_nodes.source_phantom = raw_route.segmentEndCoordinates.front().source_phantom; phantom_nodes.source_phantom = raw_route.segment_end_coordinates.front().source_phantom;
phantom_nodes.target_phantom = raw_route.segmentEndCoordinates.back().target_phantom; phantom_nodes.target_phantom = raw_route.segment_end_coordinates.back().target_phantom;
descriptor->SetConfig(descriptor_config); descriptor->SetConfig(descriptor_config);
descriptor->Run(raw_route, phantom_nodes, facade, reply); descriptor->Run(raw_route, phantom_nodes, facade, reply);

View File

@ -315,7 +315,7 @@ public:
// -- unpacked output // -- unpacked output
raw_route_data.unpacked_path_segments.front() raw_route_data.unpacked_path_segments.front()
); );
raw_route_data.lengthOfShortestPath = upper_bound_to_shortest_path_distance; raw_route_data.shortest_path_length = upper_bound_to_shortest_path_distance;
} }
if( SPECIAL_NODEID != selected_via_node ) { if( SPECIAL_NODEID != selected_via_node ) {
@ -341,7 +341,7 @@ public:
raw_route_data.unpacked_alternative raw_route_data.unpacked_alternative
); );
raw_route_data.lengthOfAlternativePath = length_of_via_path; raw_route_data.alternative_path_length = length_of_via_path;
} }
} }

View File

@ -231,8 +231,8 @@ public:
) )
); );
} }
unpacked_path.back().turnInstruction = turn_instruction; unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().durationOfSegment = ed.distance; unpacked_path.back().segment_duration = ed.distance;
} }
} }
} }

View File

@ -59,8 +59,8 @@ public:
for (const PhantomNodes & phantom_node_pair : phantom_nodes_vector) for (const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
{ {
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) { if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
// raw_route_data.lengthOfShortestPath = INT_MAX; // raw_route_data.shortest_path_length = INT_MAX;
// raw_route_data.lengthOfAlternativePath = INT_MAX; // raw_route_data.alternative_path_length = INT_MAX;
return; return;
} }
} }
@ -212,8 +212,8 @@ public:
(INVALID_EDGE_WEIGHT == local_upper_bound1) && (INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INVALID_EDGE_WEIGHT == local_upper_bound2) (INVALID_EDGE_WEIGHT == local_upper_bound2)
) { ) {
raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT; raw_route_data.shortest_path_length = INVALID_EDGE_WEIGHT;
raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT; raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT;
return; return;
} }
if( SPECIAL_NODEID == middle1 ) { if( SPECIAL_NODEID == middle1 ) {
@ -393,7 +393,7 @@ public:
raw_route_data.unpacked_path_segments[i] raw_route_data.unpacked_path_segments[i]
); );
} }
raw_route_data.lengthOfShortestPath = std::min(distance1, distance2); raw_route_data.shortest_path_length = std::min(distance1, distance2);
} }
}; };

View File

@ -91,7 +91,7 @@ int main (int argc, const char * argv[]) {
route_parameters.alternateRoute = true; //get an alternate route, too route_parameters.alternateRoute = true; //get an alternate route, too
route_parameters.geometry = true; //retrieve geometry of route route_parameters.geometry = true; //retrieve geometry of route
route_parameters.compression = true; //polyline encoding route_parameters.compression = true; //polyline encoding
route_parameters.checkSum = UINT_MAX; //see wiki route_parameters.check_sum = UINT_MAX; //see wiki
route_parameters.service = "viaroute"; //that's routing route_parameters.service = "viaroute"; //that's routing
route_parameters.outputFormat = "json"; route_parameters.outputFormat = "json";
route_parameters.jsonpParameter = ""; //set for jsonp wrapping route_parameters.jsonpParameter = ""; //set for jsonp wrapping