migrate DataStructures to C++11
This commit is contained in:
parent
6abbb06ff6
commit
e12ad48822
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CONCURRENTQUEUE_H_
|
||||
#define CONCURRENTQUEUE_H_
|
||||
#ifndef CONCURRENT_QUEUE_H
|
||||
#define CONCURRENT_QUEUE_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/thread.hpp>
|
||||
|
||||
template<typename Data>
|
||||
class ConcurrentQueue {
|
||||
template <typename Data> class ConcurrentQueue
|
||||
{
|
||||
|
||||
public:
|
||||
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
|
||||
public:
|
||||
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);
|
||||
m_not_full.wait(
|
||||
lock,
|
||||
boost::bind(&ConcurrentQueue<Data>::is_not_full, this)
|
||||
);
|
||||
m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this));
|
||||
m_internal_queue.push_back(data);
|
||||
lock.unlock();
|
||||
m_not_empty.notify_one();
|
||||
}
|
||||
|
||||
inline bool empty() const {
|
||||
return m_internal_queue.empty();
|
||||
}
|
||||
inline bool empty() const { 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);
|
||||
m_not_empty.wait(
|
||||
lock,
|
||||
boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)
|
||||
);
|
||||
m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this));
|
||||
popped_value = m_internal_queue.front();
|
||||
m_internal_queue.pop_front();
|
||||
lock.unlock();
|
||||
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);
|
||||
if(m_internal_queue.empty()) {
|
||||
if (m_internal_queue.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
popped_value=m_internal_queue.front();
|
||||
popped_value = m_internal_queue.front();
|
||||
m_internal_queue.pop_front();
|
||||
lock.unlock();
|
||||
m_not_full.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool is_not_empty() const {
|
||||
return !m_internal_queue.empty();
|
||||
}
|
||||
private:
|
||||
inline bool is_not_empty() const { 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();
|
||||
}
|
||||
|
||||
boost::circular_buffer<Data> m_internal_queue;
|
||||
boost::mutex m_mutex;
|
||||
boost::condition m_not_empty;
|
||||
boost::condition m_not_full;
|
||||
boost::circular_buffer<Data> m_internal_queue;
|
||||
boost::mutex m_mutex;
|
||||
boost::condition m_not_empty;
|
||||
boost::condition m_not_full;
|
||||
};
|
||||
|
||||
#endif /* CONCURRENTQUEUE_H_ */
|
||||
#endif // CONCURRENT_QUEUE_H
|
||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DYNAMICGRAPH_H_INCLUDED
|
||||
#define DYNAMICGRAPH_H_INCLUDED
|
||||
#ifndef DYNAMICGRAPH_H
|
||||
#define DYNAMICGRAPH_H
|
||||
|
||||
#include "../DataStructures/DeallocatingVector.h"
|
||||
|
||||
@ -38,211 +38,224 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
template< typename EdgeDataT>
|
||||
class DynamicGraph {
|
||||
public:
|
||||
typedef EdgeDataT EdgeData;
|
||||
typedef unsigned NodeIterator;
|
||||
typedef unsigned EdgeIterator;
|
||||
template <typename EdgeDataT> class DynamicGraph
|
||||
{
|
||||
public:
|
||||
typedef EdgeDataT EdgeData;
|
||||
typedef unsigned NodeIterator;
|
||||
typedef unsigned EdgeIterator;
|
||||
|
||||
class InputEdge {
|
||||
public:
|
||||
NodeIterator source;
|
||||
NodeIterator target;
|
||||
EdgeDataT data;
|
||||
bool operator<( const InputEdge& right ) const {
|
||||
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 );
|
||||
class InputEdge
|
||||
{
|
||||
public:
|
||||
NodeIterator source;
|
||||
NodeIterator target;
|
||||
EdgeDataT data;
|
||||
bool operator<(const InputEdge &right) const
|
||||
{
|
||||
if (source != right.source)
|
||||
return source < right.source;
|
||||
return target < right.target;
|
||||
}
|
||||
};
|
||||
|
||||
template<class ContainerT>
|
||||
DynamicGraph( const int32_t nodes, const ContainerT &graph ) {
|
||||
m_numNodes = nodes;
|
||||
m_numEdges = ( EdgeIterator ) graph.size();
|
||||
m_nodes.reserve( m_numNodes +1);
|
||||
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[node].firstEdge = position;
|
||||
m_nodes[node].edges = edge - lastEdge;
|
||||
position += m_nodes[node].edges;
|
||||
// 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> DynamicGraph(const int32_t nodes, const ContainerT &graph)
|
||||
{
|
||||
m_numNodes = nodes;
|
||||
m_numEdges = (EdgeIterator)graph.size();
|
||||
m_nodes.reserve(m_numNodes + 1);
|
||||
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_edges.reserve( position * 1.1 );
|
||||
m_edges.resize( position );
|
||||
edge = 0;
|
||||
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
|
||||
for ( EdgeIterator i = m_nodes[node].firstEdge, e = m_nodes[node].firstEdge + m_nodes[node].edges; 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;
|
||||
m_nodes[node].firstEdge = position;
|
||||
m_nodes[node].edges = edge - lastEdge;
|
||||
position += m_nodes[node].edges;
|
||||
}
|
||||
m_nodes.back().firstEdge = position;
|
||||
m_edges.reserve(position * 1.1);
|
||||
m_edges.resize(position);
|
||||
edge = 0;
|
||||
for (NodeIterator node = 0; node < m_numNodes; ++node)
|
||||
{
|
||||
for (EdgeIterator i = m_nodes[node].firstEdge,
|
||||
e = m_nodes[node].firstEdge + m_nodes[node].edges;
|
||||
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 m_numNodes;
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// searches for a specific edge
|
||||
EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const
|
||||
{
|
||||
for (EdgeIterator i = BeginEdges(from), iend = EndEdges(from); i != iend; ++i)
|
||||
{
|
||||
if (to == m_edges[i].target)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
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
|
||||
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 );
|
||||
}
|
||||
protected:
|
||||
bool isDummy(const EdgeIterator edge) const
|
||||
{
|
||||
return m_edges[edge].target == (std::numeric_limits<NodeIterator>::max)();
|
||||
}
|
||||
|
||||
//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 );
|
||||
}
|
||||
}
|
||||
void makeDummy(const EdgeIterator edge)
|
||||
{
|
||||
m_edges[edge].target = (std::numeric_limits<NodeIterator>::max)();
|
||||
}
|
||||
|
||||
#pragma omp atomic
|
||||
m_numEdges -= deleted;
|
||||
m_nodes[source].edges -= deleted;
|
||||
struct Node
|
||||
{
|
||||
// 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
|
||||
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const {
|
||||
for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) {
|
||||
if ( to == m_edges[i].target ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return EndEdges( from );
|
||||
}
|
||||
NodeIterator m_numNodes;
|
||||
EdgeIterator m_numEdges;
|
||||
|
||||
protected:
|
||||
|
||||
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;
|
||||
std::vector<Node> m_nodes;
|
||||
DeallocatingVector<Edge> m_edges;
|
||||
};
|
||||
|
||||
#endif // DYNAMICGRAPH_H_INCLUDED
|
||||
#endif // DYNAMICGRAPH_H
|
||||
|
@ -10,7 +10,8 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
struct EdgeBasedNode {
|
||||
struct EdgeBasedNode
|
||||
{
|
||||
|
||||
EdgeBasedNode() :
|
||||
forward_edge_based_node_id(SPECIAL_NODEID),
|
||||
@ -24,7 +25,7 @@ struct EdgeBasedNode {
|
||||
reverse_offset(0),
|
||||
packed_geometry_id(SPECIAL_EDGEID),
|
||||
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
|
||||
belongsToTinyComponent(false)
|
||||
is_in_tiny_cc(false)
|
||||
{ }
|
||||
|
||||
explicit EdgeBasedNode(
|
||||
@ -52,18 +53,14 @@ struct EdgeBasedNode {
|
||||
reverse_offset(reverse_offset),
|
||||
packed_geometry_id(packed_geometry_id),
|
||||
fwd_segment_position(fwd_segment_position),
|
||||
belongsToTinyComponent(belongs_to_tiny_component)
|
||||
is_in_tiny_cc(belongs_to_tiny_component)
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
( forward_edge_based_node_id != SPECIAL_NODEID ) ||
|
||||
( reverse_edge_based_node_id != SPECIAL_NODEID )
|
||||
);
|
||||
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
|
||||
(reverse_edge_based_node_id != SPECIAL_NODEID));
|
||||
}
|
||||
|
||||
static inline FixedPointCoordinate Centroid(
|
||||
const FixedPointCoordinate & a,
|
||||
const FixedPointCoordinate & b
|
||||
) {
|
||||
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate & a, const FixedPointCoordinate & b)
|
||||
{
|
||||
FixedPointCoordinate centroid;
|
||||
//The coordinates of the midpoint are given by:
|
||||
centroid.lat = (a.lat + b.lat)/2;
|
||||
@ -71,7 +68,8 @@ struct EdgeBasedNode {
|
||||
return centroid;
|
||||
}
|
||||
|
||||
bool IsCompressed() {
|
||||
bool IsCompressed() const
|
||||
{
|
||||
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
|
||||
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
|
||||
unsigned short fwd_segment_position; // segment id in a compressed geometry
|
||||
bool belongsToTinyComponent;
|
||||
bool is_in_tiny_cc;
|
||||
};
|
||||
|
||||
#endif //EDGE_BASED_NODE_H
|
||||
|
@ -33,15 +33,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
class NodeBasedEdge {
|
||||
class NodeBasedEdge
|
||||
{
|
||||
|
||||
public:
|
||||
bool operator< (const NodeBasedEdge& e) const {
|
||||
if (source() == e.source()) {
|
||||
if (target() == e.target()) {
|
||||
if (weight() == e.weight()) {
|
||||
return (isForward() && isBackward() &&
|
||||
((! e.isForward()) || (! e.isBackward())));
|
||||
public:
|
||||
bool operator<(const NodeBasedEdge &e) const
|
||||
{
|
||||
if (source() == e.source())
|
||||
{
|
||||
if (target() == e.target())
|
||||
{
|
||||
if (weight() == e.weight())
|
||||
{
|
||||
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
|
||||
}
|
||||
return (weight() < e.weight());
|
||||
}
|
||||
@ -50,80 +54,77 @@ public:
|
||||
return (source() < e.source());
|
||||
}
|
||||
|
||||
explicit NodeBasedEdge(
|
||||
NodeID s,
|
||||
NodeID t,
|
||||
NodeID n,
|
||||
EdgeWeight w,
|
||||
bool f,
|
||||
bool b,
|
||||
short ty,
|
||||
bool ra,
|
||||
bool ig,
|
||||
bool ar,
|
||||
bool cf,
|
||||
bool is_split
|
||||
) : _source(s),
|
||||
_target(t),
|
||||
_name(n),
|
||||
_weight(w),
|
||||
_type(ty),
|
||||
forward(f),
|
||||
backward(b),
|
||||
_roundabout(ra),
|
||||
_ignoreInGrid(ig),
|
||||
_accessRestricted(ar),
|
||||
_contraFlow(cf),
|
||||
is_split(is_split)
|
||||
explicit NodeBasedEdge(NodeID s,
|
||||
NodeID t,
|
||||
NodeID n,
|
||||
EdgeWeight w,
|
||||
bool f,
|
||||
bool b,
|
||||
short ty,
|
||||
bool ra,
|
||||
bool ig,
|
||||
bool ar,
|
||||
bool cf,
|
||||
bool is_split)
|
||||
: _source(s), _target(t), _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");
|
||||
}
|
||||
}
|
||||
|
||||
NodeID target() const {return _target; }
|
||||
NodeID source() const {return _source; }
|
||||
NodeID name() const { return _name; }
|
||||
EdgeWeight weight() const {return _weight; }
|
||||
short type() const {
|
||||
NodeID target() const { return _target; }
|
||||
NodeID source() const { return _source; }
|
||||
NodeID name() const { return _name; }
|
||||
EdgeWeight weight() const { return _weight; }
|
||||
short type() const
|
||||
{
|
||||
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
|
||||
return _type; }
|
||||
bool isBackward() const { return backward; }
|
||||
bool isForward() const { return forward; }
|
||||
bool isLocatable() const { return _type != 14; }
|
||||
bool isRoundabout() const { return _roundabout; }
|
||||
bool ignoreInGrid() const { return _ignoreInGrid; }
|
||||
bool isAccessRestricted() const { return _accessRestricted; }
|
||||
bool isContraFlow() const { return _contraFlow; }
|
||||
bool IsSplit() const { return is_split; }
|
||||
return _type;
|
||||
}
|
||||
bool isBackward() const { return backward; }
|
||||
bool isForward() const { return forward; }
|
||||
bool isLocatable() const { return _type != 14; }
|
||||
bool isRoundabout() const { return _roundabout; }
|
||||
bool ignoreInGrid() const { return _ignoreInGrid; }
|
||||
bool isAccessRestricted() const { return _accessRestricted; }
|
||||
bool isContraFlow() const { return _contraFlow; }
|
||||
bool IsSplit() const { return is_split; }
|
||||
|
||||
//TODO: names need to be fixed.
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
NodeID _name;
|
||||
EdgeWeight _weight;
|
||||
short _type;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
bool _roundabout:1;
|
||||
bool _ignoreInGrid:1;
|
||||
bool _accessRestricted:1;
|
||||
bool _contraFlow:1;
|
||||
bool is_split:1;
|
||||
// TODO: names need to be fixed.
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
NodeID _name;
|
||||
EdgeWeight _weight;
|
||||
short _type;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
bool _roundabout : 1;
|
||||
bool _ignoreInGrid : 1;
|
||||
bool _accessRestricted : 1;
|
||||
bool _contraFlow : 1;
|
||||
bool is_split : 1;
|
||||
|
||||
private:
|
||||
NodeBasedEdge() { }
|
||||
private:
|
||||
NodeBasedEdge() {}
|
||||
};
|
||||
|
||||
class EdgeBasedEdge {
|
||||
class EdgeBasedEdge
|
||||
{
|
||||
|
||||
public:
|
||||
bool operator< (const EdgeBasedEdge& e) const {
|
||||
if (source() == e.source()) {
|
||||
if (target() == e.target()) {
|
||||
if (weight() == e.weight()) {
|
||||
return (isForward() && isBackward() &&
|
||||
((! e.isForward()) || (! e.isBackward())));
|
||||
public:
|
||||
bool operator<(const EdgeBasedEdge &e) const
|
||||
{
|
||||
if (source() == e.source())
|
||||
{
|
||||
if (target() == e.target())
|
||||
{
|
||||
if (weight() == e.weight())
|
||||
{
|
||||
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
|
||||
}
|
||||
return (weight() < e.weight());
|
||||
}
|
||||
@ -132,56 +133,44 @@ public:
|
||||
return (source() < e.source());
|
||||
}
|
||||
|
||||
template<class EdgeT>
|
||||
explicit EdgeBasedEdge(const EdgeT & myEdge ) :
|
||||
m_source(myEdge.source),
|
||||
m_target(myEdge.target),
|
||||
m_edgeID(myEdge.data.via),
|
||||
m_weight(myEdge.data.distance),
|
||||
m_forward(myEdge.data.forward),
|
||||
m_backward(myEdge.data.backward)
|
||||
{ }
|
||||
template <class EdgeT>
|
||||
explicit EdgeBasedEdge(const EdgeT &myEdge)
|
||||
: m_source(myEdge.source), m_target(myEdge.target), m_edgeID(myEdge.data.via),
|
||||
m_weight(myEdge.data.distance), m_forward(myEdge.data.forward),
|
||||
m_backward(myEdge.data.backward)
|
||||
{
|
||||
}
|
||||
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
EdgeBasedEdge() :
|
||||
m_source(0),
|
||||
m_target(0),
|
||||
m_edgeID(0),
|
||||
m_weight(0),
|
||||
m_forward(false),
|
||||
m_backward(false)
|
||||
{ }
|
||||
EdgeBasedEdge()
|
||||
: m_source(0), m_target(0), m_edgeID(0), m_weight(0), m_forward(false), m_backward(false)
|
||||
{
|
||||
}
|
||||
|
||||
explicit EdgeBasedEdge(
|
||||
const NodeID s,
|
||||
const NodeID t,
|
||||
const NodeID v,
|
||||
const EdgeWeight w,
|
||||
const bool f,
|
||||
const bool b
|
||||
) :
|
||||
m_source(s),
|
||||
m_target(t),
|
||||
m_edgeID(v),
|
||||
m_weight(w),
|
||||
m_forward(f),
|
||||
m_backward(b)
|
||||
{ }
|
||||
explicit EdgeBasedEdge(const NodeID s,
|
||||
const NodeID t,
|
||||
const NodeID v,
|
||||
const EdgeWeight w,
|
||||
const bool f,
|
||||
const bool 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 source() const { return m_source; }
|
||||
EdgeWeight weight() const { return m_weight; }
|
||||
NodeID id() const { return m_edgeID; }
|
||||
bool isBackward() const { return m_backward; }
|
||||
bool isForward() const { return m_forward; }
|
||||
NodeID target() const { return m_target; }
|
||||
NodeID source() const { return m_source; }
|
||||
EdgeWeight weight() const { return m_weight; }
|
||||
NodeID id() const { return m_edgeID; }
|
||||
bool isBackward() const { return m_backward; }
|
||||
bool isForward() const { return m_forward; }
|
||||
|
||||
private:
|
||||
NodeID m_source;
|
||||
NodeID m_target;
|
||||
NodeID m_edgeID;
|
||||
EdgeWeight m_weight:30;
|
||||
bool m_forward:1;
|
||||
bool m_backward:1;
|
||||
private:
|
||||
NodeID m_source;
|
||||
NodeID m_target;
|
||||
NodeID m_edgeID;
|
||||
EdgeWeight m_weight : 30;
|
||||
bool m_forward : 1;
|
||||
bool m_backward : 1;
|
||||
};
|
||||
|
||||
typedef NodeBasedEdge ImportEdge;
|
||||
|
@ -31,55 +31,45 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "QueryNode.h"
|
||||
#include "../DataStructures/HashTable.h"
|
||||
|
||||
|
||||
struct ExternalMemoryNode : NodeInfo {
|
||||
ExternalMemoryNode(
|
||||
int lat,
|
||||
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);
|
||||
struct ExternalMemoryNode : NodeInfo
|
||||
{
|
||||
ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light)
|
||||
: NodeInfo(lat, lon, id), bollard(bollard), trafficLight(traffic_light)
|
||||
{
|
||||
}
|
||||
|
||||
static ExternalMemoryNode max_value() {
|
||||
return ExternalMemoryNode(
|
||||
std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<unsigned>::max(),
|
||||
false,
|
||||
false
|
||||
);
|
||||
ExternalMemoryNode() : bollard(false), trafficLight(false) {}
|
||||
|
||||
static ExternalMemoryNode min_value() { return ExternalMemoryNode(0, 0, 0, false, false); }
|
||||
|
||||
static ExternalMemoryNode max_value()
|
||||
{
|
||||
return ExternalMemoryNode(std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<unsigned>::max(),
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
NodeID key() const {
|
||||
return id;
|
||||
}
|
||||
NodeID key() const { return id; }
|
||||
|
||||
bool bollard;
|
||||
bool trafficLight;
|
||||
};
|
||||
|
||||
struct ImportNode : public ExternalMemoryNode {
|
||||
struct ImportNode : public ExternalMemoryNode
|
||||
{
|
||||
HashTable<std::string, std::string> keyVals;
|
||||
|
||||
inline void Clear() {
|
||||
keyVals.clear();
|
||||
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false;
|
||||
}
|
||||
inline void Clear()
|
||||
{
|
||||
keyVals.clear();
|
||||
lat = 0;
|
||||
lon = 0;
|
||||
id = 0;
|
||||
bollard = false;
|
||||
trafficLight = false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* IMPORTNODE_H_ */
|
||||
|
@ -25,80 +25,99 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INPUTREADERFACTORY_H
|
||||
#define INPUTREADERFACTORY_H
|
||||
#ifndef INPUT_READER_FACTORY_H
|
||||
#define INPUT_READER_FACTORY_H
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <bzlib.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
|
||||
struct BZ2Context {
|
||||
FILE* file;
|
||||
BZFILE* bz2;
|
||||
struct BZ2Context
|
||||
{
|
||||
FILE *file;
|
||||
BZFILE *bz2;
|
||||
int error;
|
||||
int nUnused;
|
||||
char unused[BZ_MAX_UNUSED];
|
||||
};
|
||||
|
||||
int readFromBz2Stream( void* pointer, char* buffer, int len ) {
|
||||
void *unusedTmpVoid=NULL;
|
||||
char *unusedTmp=NULL;
|
||||
BZ2Context* context = (BZ2Context*) pointer;
|
||||
int readFromBz2Stream(void *pointer, char *buffer, int len)
|
||||
{
|
||||
void *unusedTmpVoid = NULL;
|
||||
char *unusedTmp = NULL;
|
||||
BZ2Context *context = (BZ2Context *)pointer;
|
||||
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);
|
||||
if(BZ_OK == context->error) {
|
||||
if (BZ_OK == context->error)
|
||||
{
|
||||
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);
|
||||
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
|
||||
unusedTmp = (char*)unusedTmpVoid;
|
||||
for(int i=0;i<context->nUnused;i++) {
|
||||
unusedTmp = (char *)unusedTmpVoid;
|
||||
for (int i = 0; i < context->nUnused; i++)
|
||||
{
|
||||
context->unused[i] = unusedTmp[i];
|
||||
}
|
||||
BZ2_bzReadClose(&context->error, context->bz2);
|
||||
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
|
||||
if(0 == context->nUnused && feof(context->file)) {
|
||||
if (0 == context->nUnused && feof(context->file))
|
||||
{
|
||||
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");
|
||||
}
|
||||
} else { BOOST_ASSERT_MSG(false, "Could not read bz2 file"); }
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT_MSG(false, "Could not read bz2 file");
|
||||
}
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
int closeBz2Stream( void *pointer )
|
||||
int closeBz2Stream(void *pointer)
|
||||
{
|
||||
BZ2Context* context = (BZ2Context*) pointer;
|
||||
fclose( context->file );
|
||||
BZ2Context *context = (BZ2Context *)pointer;
|
||||
fclose(context->file);
|
||||
delete context;
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmlTextReaderPtr inputReaderFactory( const char* name )
|
||||
xmlTextReaderPtr inputReaderFactory(const char *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->file = fopen( name, "r" );
|
||||
context->file = fopen(name, "r");
|
||||
int error;
|
||||
context->bz2 = BZ2_bzReadOpen( &error, context->file, 0, 0, context->unused, context->nUnused );
|
||||
if ( context->bz2 == NULL || context->file == NULL ) {
|
||||
context->bz2 =
|
||||
BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused);
|
||||
if (context->bz2 == NULL || context->file == NULL)
|
||||
{
|
||||
delete context;
|
||||
return NULL;
|
||||
}
|
||||
return xmlReaderForIO( readFromBz2Stream, closeBz2Stream, (void*) context, NULL, NULL, 0 );
|
||||
} else {
|
||||
return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, NULL, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return xmlNewTextReaderFilename(name);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INPUTREADERFACTORY_H
|
||||
#endif // INPUT_READER_FACTORY_H
|
||||
|
@ -29,61 +29,69 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define LRUCACHE_H
|
||||
|
||||
#include <list>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
template<typename KeyT, typename ValueT>
|
||||
class LRUCache {
|
||||
private:
|
||||
struct CacheEntry {
|
||||
template <typename KeyT, typename ValueT> class LRUCache
|
||||
{
|
||||
private:
|
||||
struct CacheEntry
|
||||
{
|
||||
CacheEntry(KeyT k, ValueT v) : key(k), value(v) {}
|
||||
KeyT key;
|
||||
ValueT value;
|
||||
};
|
||||
unsigned capacity;
|
||||
std::list<CacheEntry> itemsInCache;
|
||||
boost::unordered_map<KeyT, typename std::list<CacheEntry>::iterator > positionMap;
|
||||
public:
|
||||
std::unordered_map<KeyT, typename std::list<CacheEntry>::iterator> positionMap;
|
||||
|
||||
public:
|
||||
explicit LRUCache(unsigned c) : capacity(c) {}
|
||||
|
||||
bool Holds(KeyT key) {
|
||||
if(positionMap.find(key) != positionMap.end()) {
|
||||
bool Holds(KeyT key)
|
||||
{
|
||||
if (positionMap.find(key) != positionMap.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Insert(const KeyT key, ValueT &value) {
|
||||
void Insert(const KeyT key, ValueT &value)
|
||||
{
|
||||
itemsInCache.push_front(CacheEntry(key, value));
|
||||
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
||||
if(itemsInCache.size() > capacity) {
|
||||
if (itemsInCache.size() > capacity)
|
||||
{
|
||||
positionMap.erase(itemsInCache.back().key);
|
||||
itemsInCache.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void Insert(const KeyT key, ValueT value) {
|
||||
void Insert(const KeyT key, ValueT value)
|
||||
{
|
||||
itemsInCache.push_front(CacheEntry(key, value));
|
||||
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
||||
if(itemsInCache.size() > capacity) {
|
||||
if (itemsInCache.size() > capacity)
|
||||
{
|
||||
positionMap.erase(itemsInCache.back().key);
|
||||
itemsInCache.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
bool Fetch(const KeyT key, ValueT& result) {
|
||||
if(Holds(key)) {
|
||||
bool Fetch(const KeyT key, ValueT &result)
|
||||
{
|
||||
if (Holds(key))
|
||||
{
|
||||
CacheEntry e = *(positionMap.find(key)->second);
|
||||
result = e.value;
|
||||
|
||||
//move to front
|
||||
// move to front
|
||||
itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin());
|
||||
positionMap.find(key)->second = itemsInCache.begin();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
unsigned Size() const {
|
||||
return itemsInCache.size();
|
||||
}
|
||||
unsigned Size() const { return itemsInCache.size(); }
|
||||
};
|
||||
#endif //LRUCACHE_H
|
||||
#endif // LRUCACHE_H
|
||||
|
@ -33,25 +33,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <limits>
|
||||
|
||||
struct OriginalEdgeData{
|
||||
explicit OriginalEdgeData(
|
||||
NodeID via_node,
|
||||
unsigned name_id,
|
||||
TurnInstruction turn_instruction,
|
||||
bool compressed_geometry
|
||||
) :
|
||||
via_node( via_node ),
|
||||
name_id( name_id ),
|
||||
turn_instruction( turn_instruction ),
|
||||
compressed_geometry( compressed_geometry )
|
||||
{ }
|
||||
struct OriginalEdgeData
|
||||
{
|
||||
explicit OriginalEdgeData(NodeID via_node,
|
||||
unsigned name_id,
|
||||
TurnInstruction turn_instruction,
|
||||
bool compressed_geometry)
|
||||
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
|
||||
compressed_geometry(compressed_geometry)
|
||||
{
|
||||
}
|
||||
|
||||
OriginalEdgeData() :
|
||||
via_node( std::numeric_limits<unsigned>::max() ),
|
||||
name_id( std::numeric_limits<unsigned>::max() ),
|
||||
turn_instruction( std::numeric_limits<unsigned char>::max() ),
|
||||
compressed_geometry( false )
|
||||
{ }
|
||||
OriginalEdgeData()
|
||||
: via_node(std::numeric_limits<unsigned>::max()),
|
||||
name_id(std::numeric_limits<unsigned>::max()),
|
||||
turn_instruction(std::numeric_limits<unsigned char>::max()), compressed_geometry(false)
|
||||
{
|
||||
}
|
||||
|
||||
NodeID via_node;
|
||||
unsigned name_id;
|
||||
@ -59,4 +57,4 @@ struct OriginalEdgeData{
|
||||
bool compressed_geometry;
|
||||
};
|
||||
|
||||
#endif //ORIGINAL_EDGE_DATA_H
|
||||
#endif // ORIGINAL_EDGE_DATA_H
|
||||
|
@ -31,64 +31,68 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "../Util/OpenMPWrapper.h"
|
||||
#include <iostream>
|
||||
|
||||
class Percent {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param maxValue the value that corresponds to 100%
|
||||
* @param step the progress is shown in steps of 'step' percent
|
||||
*/
|
||||
explicit Percent(unsigned maxValue, unsigned step = 5) {
|
||||
reinit(maxValue, step);
|
||||
class Percent
|
||||
{
|
||||
public:
|
||||
explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); }
|
||||
|
||||
// Reinitializes
|
||||
void reinit(unsigned max_value, unsigned step = 5)
|
||||
{
|
||||
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. */
|
||||
void reinit(unsigned maxValue, unsigned step = 5) {
|
||||
_maxValue = maxValue;
|
||||
_current_value = 0;
|
||||
_intervalPercent = _maxValue / 100;
|
||||
_nextThreshold = _intervalPercent;
|
||||
_lastPercent = 0;
|
||||
_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 there has been significant progress, display it.
|
||||
void printStatus(unsigned current_value)
|
||||
{
|
||||
if (current_value >= m_next_threshold)
|
||||
{
|
||||
m_next_threshold += m_percent_interval;
|
||||
printPercent(current_value / (double)m_max_value * 100);
|
||||
}
|
||||
if (currentValue + 1 == _maxValue)
|
||||
if (current_value + 1 == m_max_value)
|
||||
std::cout << " 100%" << std::endl;
|
||||
}
|
||||
|
||||
void printIncrement() {
|
||||
void printIncrement()
|
||||
{
|
||||
#pragma omp atomic
|
||||
++_current_value;
|
||||
printStatus(_current_value);
|
||||
++m_current_value;
|
||||
printStatus(m_current_value);
|
||||
}
|
||||
|
||||
void printAddition(const unsigned addition) {
|
||||
void printAddition(const unsigned addition)
|
||||
{
|
||||
#pragma omp atomic
|
||||
_current_value += addition;
|
||||
printStatus(_current_value);
|
||||
m_current_value += addition;
|
||||
printStatus(m_current_value);
|
||||
}
|
||||
private:
|
||||
unsigned _current_value;
|
||||
unsigned _maxValue;
|
||||
unsigned _intervalPercent;
|
||||
unsigned _nextThreshold;
|
||||
unsigned _lastPercent;
|
||||
unsigned _step;
|
||||
|
||||
/** Displays the new progress. */
|
||||
void printPercent(double percent) {
|
||||
while (percent >= _lastPercent+_step) {
|
||||
_lastPercent+=_step;
|
||||
if (_lastPercent % 10 == 0) {
|
||||
std::cout << " " << _lastPercent << "% ";
|
||||
private:
|
||||
unsigned m_current_value;
|
||||
unsigned m_max_value;
|
||||
unsigned m_percent_interval;
|
||||
unsigned m_next_threshold;
|
||||
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.flush();
|
||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PHANTOMNODES_H_
|
||||
#define PHANTOMNODES_H_
|
||||
#ifndef PHANTOM_NODES_H
|
||||
#define PHANTOM_NODES_H
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
#include "../Util/SimpleLogger.h"
|
||||
@ -171,4 +171,4 @@ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif /* PHANTOMNODES_H_ */
|
||||
#endif // PHANTOM_NODES_H
|
||||
|
@ -30,34 +30,34 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
struct QueryEdge {
|
||||
struct QueryEdge
|
||||
{
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
struct EdgeData {
|
||||
NodeID id:31;
|
||||
bool shortcut:1;
|
||||
int distance:30;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
struct EdgeData
|
||||
{
|
||||
NodeID id : 31;
|
||||
bool shortcut : 1;
|
||||
int distance : 30;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
} data;
|
||||
|
||||
bool operator<( const QueryEdge& right ) const {
|
||||
if ( source != right.source ) {
|
||||
bool operator<(const QueryEdge &right) const
|
||||
{
|
||||
if (source != right.source)
|
||||
{
|
||||
return source < right.source;
|
||||
}
|
||||
return target < right.target;
|
||||
}
|
||||
|
||||
bool operator== ( const QueryEdge& right ) const {
|
||||
return (
|
||||
source == right.source &&
|
||||
target == right.target &&
|
||||
data.distance == right.data.distance &&
|
||||
data.shortcut == right.data.shortcut &&
|
||||
data.forward == right.data.forward &&
|
||||
data.backward == right.data.backward &&
|
||||
data.id == right.data.id
|
||||
);
|
||||
bool operator==(const QueryEdge &right) const
|
||||
{
|
||||
return (source == right.source && target == right.target &&
|
||||
data.distance == right.data.distance && data.shortcut == right.data.shortcut &&
|
||||
data.forward == right.data.forward && data.backward == right.data.backward &&
|
||||
data.id == right.data.id);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -36,52 +36,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <limits>
|
||||
|
||||
struct NodeInfo {
|
||||
typedef NodeID key_type; //type of NodeID
|
||||
typedef int value_type; //type of lat,lons
|
||||
struct NodeInfo
|
||||
{
|
||||
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()
|
||||
:
|
||||
lat(std::numeric_limits<int>::max()),
|
||||
lon(std::numeric_limits<int>::max()),
|
||||
id(std::numeric_limits<unsigned>::max())
|
||||
{ }
|
||||
NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) {}
|
||||
NodeInfo()
|
||||
: lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
|
||||
id(std::numeric_limits<unsigned>::max())
|
||||
{
|
||||
}
|
||||
|
||||
int lat;
|
||||
int lon;
|
||||
NodeID id;
|
||||
int lat;
|
||||
int lon;
|
||||
NodeID id;
|
||||
|
||||
static NodeInfo min_value() {
|
||||
return NodeInfo(
|
||||
-90*COORDINATE_PRECISION,
|
||||
-180*COORDINATE_PRECISION,
|
||||
std::numeric_limits<NodeID>::min()
|
||||
);
|
||||
}
|
||||
static NodeInfo min_value()
|
||||
{
|
||||
return NodeInfo(-90 * COORDINATE_PRECISION,
|
||||
-180 * COORDINATE_PRECISION,
|
||||
std::numeric_limits<NodeID>::min());
|
||||
}
|
||||
|
||||
static NodeInfo max_value() {
|
||||
return NodeInfo(
|
||||
90*COORDINATE_PRECISION,
|
||||
180*COORDINATE_PRECISION,
|
||||
std::numeric_limits<NodeID>::max()
|
||||
);
|
||||
}
|
||||
static NodeInfo max_value()
|
||||
{
|
||||
return NodeInfo(90 * COORDINATE_PRECISION,
|
||||
180 * COORDINATE_PRECISION,
|
||||
std::numeric_limits<NodeID>::max());
|
||||
}
|
||||
|
||||
value_type operator[](const std::size_t n) const {
|
||||
switch(n) {
|
||||
case 1:
|
||||
return lat;
|
||||
// break;
|
||||
case 0:
|
||||
return lon;
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BOOST_ASSERT_MSG(false, "should not happen");
|
||||
return std::numeric_limits<unsigned>::max();
|
||||
}
|
||||
value_type operator[](const std::size_t n) const
|
||||
{
|
||||
switch (n)
|
||||
{
|
||||
case 1:
|
||||
return lat;
|
||||
case 0:
|
||||
return lon;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BOOST_ASSERT_MSG(false, "should not happen");
|
||||
return std::numeric_limits<unsigned>::max();
|
||||
}
|
||||
};
|
||||
|
||||
#endif //QUERY_NODE_H
|
||||
#endif // QUERY_NODE_H
|
||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef RAWROUTEDATA_H_
|
||||
#define RAWROUTEDATA_H_
|
||||
#ifndef RAW_ROUTE_DATA_H
|
||||
#define RAW_ROUTE_DATA_H
|
||||
|
||||
#include "../DataStructures/PhantomNodes.h"
|
||||
#include "../typedefs.h"
|
||||
@ -37,53 +37,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct PathData {
|
||||
PathData() :
|
||||
node(UINT_MAX),
|
||||
name_id(UINT_MAX),
|
||||
durationOfSegment(UINT_MAX),
|
||||
turnInstruction(UCHAR_MAX)
|
||||
{ }
|
||||
struct PathData
|
||||
{
|
||||
PathData()
|
||||
: node(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
|
||||
segment_duration(std::numeric_limits<unsigned>::max()),
|
||||
turn_instruction(std::numeric_limits<unsigned char>::max())
|
||||
{
|
||||
}
|
||||
|
||||
PathData(
|
||||
NodeID no,
|
||||
unsigned na,
|
||||
unsigned tu,
|
||||
unsigned dur
|
||||
) :
|
||||
node(no),
|
||||
name_id(na),
|
||||
durationOfSegment(dur),
|
||||
turnInstruction(tu)
|
||||
{ }
|
||||
PathData(NodeID no, unsigned na, unsigned tu, unsigned dur)
|
||||
: node(no), name_id(na), segment_duration(dur), turn_instruction(tu)
|
||||
{
|
||||
}
|
||||
NodeID node;
|
||||
unsigned name_id;
|
||||
unsigned durationOfSegment;
|
||||
short turnInstruction;
|
||||
unsigned segment_duration;
|
||||
short turn_instruction;
|
||||
};
|
||||
|
||||
struct RawRouteData {
|
||||
std::vector< std::vector<PathData> > unpacked_path_segments;
|
||||
std::vector< PathData > unpacked_alternative;
|
||||
std::vector< PhantomNodes > segmentEndCoordinates;
|
||||
std::vector< FixedPointCoordinate > rawViaNodeCoordinates;
|
||||
unsigned checkSum;
|
||||
int lengthOfShortestPath;
|
||||
int lengthOfAlternativePath;
|
||||
struct RawRouteData
|
||||
{
|
||||
std::vector<std::vector<PathData>> unpacked_path_segments;
|
||||
std::vector<PathData> unpacked_alternative;
|
||||
std::vector<PhantomNodes> segment_end_coordinates;
|
||||
std::vector<FixedPointCoordinate> raw_via_node_coordinates;
|
||||
unsigned check_sum;
|
||||
int shortest_path_length;
|
||||
int alternative_path_length;
|
||||
bool source_traversed_in_reverse;
|
||||
bool target_traversed_in_reverse;
|
||||
bool alt_source_traversed_in_reverse;
|
||||
bool alt_target_traversed_in_reverse;
|
||||
|
||||
RawRouteData() :
|
||||
checkSum(UINT_MAX),
|
||||
lengthOfShortestPath(INT_MAX),
|
||||
lengthOfAlternativePath(INT_MAX),
|
||||
source_traversed_in_reverse(false),
|
||||
target_traversed_in_reverse(false),
|
||||
alt_source_traversed_in_reverse(false),
|
||||
alt_target_traversed_in_reverse(false)
|
||||
{ }
|
||||
RawRouteData()
|
||||
: check_sum(std::numeric_limits<unsigned>::max()),
|
||||
shortest_path_length(std::numeric_limits<int>::max()),
|
||||
alternative_path_length(std::numeric_limits<int>::max()),
|
||||
source_traversed_in_reverse(false), 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
|
||||
|
@ -33,7 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
RouteParameters::RouteParameters()
|
||||
: 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::setChecksum(const unsigned c) { checkSum = c; }
|
||||
void RouteParameters::setChecksum(const unsigned c) { check_sum = c; }
|
||||
|
||||
void RouteParameters::setInstructionFlag(const bool b) { printInstructions = b; }
|
||||
|
||||
|
@ -29,40 +29,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define SEARCHENGINE_H
|
||||
|
||||
#include "SearchEngineData.h"
|
||||
#include "PhantomNodes.h"
|
||||
#include "QueryEdge.h"
|
||||
#include "../RoutingAlgorithms/AlternativePathRouting.h"
|
||||
#include "../RoutingAlgorithms/ShortestPathRouting.h"
|
||||
|
||||
#include "../Util/StringUtil.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <climits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
template<class DataFacadeT>
|
||||
class SearchEngine {
|
||||
private:
|
||||
DataFacadeT * facade;
|
||||
template <class DataFacadeT> class SearchEngine
|
||||
{
|
||||
private:
|
||||
DataFacadeT *facade;
|
||||
SearchEngineData engine_working_data;
|
||||
public:
|
||||
ShortestPathRouting<DataFacadeT> shortest_path;
|
||||
AlternativeRouting <DataFacadeT> alternative_path;
|
||||
|
||||
explicit SearchEngine( DataFacadeT * facade )
|
||||
:
|
||||
facade (facade),
|
||||
shortest_path (facade, engine_working_data),
|
||||
alternative_path (facade, engine_working_data)
|
||||
{}
|
||||
public:
|
||||
ShortestPathRouting<DataFacadeT> shortest_path;
|
||||
AlternativeRouting<DataFacadeT> alternative_path;
|
||||
|
||||
explicit SearchEngine(DataFacadeT *facade)
|
||||
: facade(facade), shortest_path(facade, engine_working_data),
|
||||
alternative_path(facade, engine_working_data)
|
||||
{
|
||||
}
|
||||
|
||||
~SearchEngine() {}
|
||||
|
||||
};
|
||||
|
||||
#endif // SEARCHENGINE_H
|
||||
|
@ -44,8 +44,6 @@ struct HeapData
|
||||
/* explicit */ HeapData(NodeID p) : parent(p) {}
|
||||
};
|
||||
|
||||
// typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
|
||||
|
||||
struct SearchEngineData
|
||||
{
|
||||
typedef BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>> QueryHeap;
|
||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGMENTINFORMATION_H_
|
||||
#define SEGMENTINFORMATION_H_
|
||||
#ifndef SEGMENT_INFORMATION_H
|
||||
#define SEGMENT_INFORMATION_H
|
||||
|
||||
#include "TurnInstructions.h"
|
||||
|
||||
@ -35,47 +35,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
// Struct fits everything in one cache line
|
||||
struct SegmentInformation {
|
||||
struct SegmentInformation
|
||||
{
|
||||
FixedPointCoordinate location;
|
||||
NodeID name_id;
|
||||
unsigned duration;
|
||||
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;
|
||||
bool necessary;
|
||||
|
||||
explicit SegmentInformation(
|
||||
const FixedPointCoordinate & location,
|
||||
const NodeID name_id,
|
||||
const unsigned duration,
|
||||
const double length,
|
||||
const TurnInstruction turn_instruction,
|
||||
const bool necessary
|
||||
) :
|
||||
location(location),
|
||||
name_id(name_id),
|
||||
duration(duration),
|
||||
length(length),
|
||||
bearing(0),
|
||||
turn_instruction(turn_instruction),
|
||||
necessary(necessary)
|
||||
{ }
|
||||
explicit SegmentInformation(const FixedPointCoordinate &location,
|
||||
const NodeID name_id,
|
||||
const unsigned duration,
|
||||
const double length,
|
||||
const TurnInstruction turn_instruction,
|
||||
const bool necessary)
|
||||
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
|
||||
turn_instruction(turn_instruction), necessary(necessary)
|
||||
{
|
||||
}
|
||||
|
||||
explicit SegmentInformation(
|
||||
const FixedPointCoordinate & location,
|
||||
const NodeID name_id,
|
||||
const unsigned duration,
|
||||
const double length,
|
||||
const TurnInstruction turn_instruction
|
||||
) :
|
||||
location(location),
|
||||
name_id(name_id),
|
||||
duration(duration),
|
||||
length(length),
|
||||
bearing(0),
|
||||
turn_instruction(turn_instruction),
|
||||
necessary(turn_instruction != 0)
|
||||
{ }
|
||||
explicit SegmentInformation(const FixedPointCoordinate &location,
|
||||
const NodeID name_id,
|
||||
const unsigned duration,
|
||||
const double length,
|
||||
const TurnInstruction turn_instruction)
|
||||
: 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 */
|
||||
|
@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "../Util/OSRMException.h"
|
||||
#include "../Util/SimpleLogger.h"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.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>
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
// #include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
|
||||
struct OSRMLockFile {
|
||||
boost::filesystem::path operator()() {
|
||||
boost::filesystem::path temp_dir =
|
||||
boost::filesystem::temp_directory_path();
|
||||
boost::filesystem::path lock_file = temp_dir / "osrm.lock";
|
||||
return lock_file;
|
||||
}
|
||||
struct OSRMLockFile
|
||||
{
|
||||
boost::filesystem::path operator()()
|
||||
{
|
||||
boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
|
||||
boost::filesystem::path lock_file = temp_dir / "osrm.lock";
|
||||
return lock_file;
|
||||
}
|
||||
};
|
||||
|
||||
class SharedMemory : boost::noncopyable {
|
||||
class SharedMemory
|
||||
{
|
||||
|
||||
//Remove shared memory on destruction
|
||||
class shm_remove : boost::noncopyable {
|
||||
private:
|
||||
int m_shmid;
|
||||
bool m_initialized;
|
||||
public:
|
||||
void SetID(int shmid) {
|
||||
m_shmid = shmid;
|
||||
m_initialized = true;
|
||||
}
|
||||
// Remove shared memory on destruction
|
||||
class shm_remove
|
||||
{
|
||||
private:
|
||||
int m_shmid;
|
||||
bool m_initialized;
|
||||
|
||||
shm_remove() : m_shmid(INT_MIN), m_initialized(false) {}
|
||||
public:
|
||||
void SetID(int shmid)
|
||||
{
|
||||
m_shmid = shmid;
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
~shm_remove(){
|
||||
if(m_initialized) {
|
||||
SimpleLogger().Write(logDEBUG) <<
|
||||
"automatic memory deallocation";
|
||||
if(!boost::interprocess::xsi_shared_memory::remove(m_shmid)) {
|
||||
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
shm_remove() : m_shmid(INT_MIN), m_initialized(false) {}
|
||||
shm_remove(const shm_remove &) = delete;
|
||||
~shm_remove()
|
||||
{
|
||||
if (m_initialized)
|
||||
{
|
||||
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:
|
||||
void * Ptr() const {
|
||||
return region.get_address();
|
||||
}
|
||||
public:
|
||||
void *Ptr() const { return region.get_address(); }
|
||||
|
||||
template<typename IdentifierT >
|
||||
SharedMemory(
|
||||
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
|
||||
);
|
||||
SharedMemory() = delete;
|
||||
SharedMemory(const SharedMemory &) = delete;
|
||||
|
||||
region = boost::interprocess::mapped_region (
|
||||
shm,
|
||||
(
|
||||
read_write ?
|
||||
boost::interprocess::read_write :
|
||||
boost::interprocess::read_only
|
||||
)
|
||||
);
|
||||
} 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
|
||||
);
|
||||
template <typename IdentifierT>
|
||||
SharedMemory(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(
|
||||
shm,
|
||||
(read_write ? boost::interprocess::read_write : boost::interprocess::read_only));
|
||||
}
|
||||
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__
|
||||
if( -1 == shmctl(shm.get_shmid(), SHM_LOCK, 0) ) {
|
||||
if( ENOMEM == errno ) {
|
||||
SimpleLogger().Write(logWARNING) <<
|
||||
"could not lock shared memory to RAM";
|
||||
}
|
||||
}
|
||||
if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, 0))
|
||||
{
|
||||
if (ENOMEM == errno)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "could not lock shared memory to RAM";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
region = boost::interprocess::mapped_region (
|
||||
shm,
|
||||
boost::interprocess::read_write
|
||||
);
|
||||
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
|
||||
|
||||
remover.SetID( shm.get_shmid() );
|
||||
SimpleLogger().Write(logDEBUG) <<
|
||||
"writeable memory allocated " << size << " bytes";
|
||||
}
|
||||
}
|
||||
remover.SetID(shm.get_shmid());
|
||||
SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IdentifierT >
|
||||
static bool RegionExists(
|
||||
const IdentifierT id
|
||||
) {
|
||||
bool result = true;
|
||||
try {
|
||||
OSRMLockFile lock_file;
|
||||
boost::interprocess::xsi_key key( lock_file().string().c_str(), id );
|
||||
result = RegionExists(key);
|
||||
} catch(...) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
template <typename IdentifierT> static bool RegionExists(const IdentifierT id)
|
||||
{
|
||||
bool result = true;
|
||||
try
|
||||
{
|
||||
OSRMLockFile lock_file;
|
||||
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
||||
result = RegionExists(key);
|
||||
}
|
||||
catch (...) { result = false; }
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename IdentifierT >
|
||||
static bool Remove(
|
||||
const IdentifierT id
|
||||
) {
|
||||
OSRMLockFile lock_file;
|
||||
boost::interprocess::xsi_key key( lock_file().string().c_str(), id );
|
||||
return Remove(key);
|
||||
}
|
||||
template <typename IdentifierT> static bool Remove(const IdentifierT id)
|
||||
{
|
||||
OSRMLockFile lock_file;
|
||||
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
||||
return Remove(key);
|
||||
}
|
||||
|
||||
private:
|
||||
static bool RegionExists( const boost::interprocess::xsi_key &key ) {
|
||||
bool result = true;
|
||||
try {
|
||||
boost::interprocess::xsi_shared_memory shm(
|
||||
boost::interprocess::open_only,
|
||||
key
|
||||
);
|
||||
} catch(...) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
static bool RegionExists(const boost::interprocess::xsi_key &key)
|
||||
{
|
||||
bool result = true;
|
||||
try { boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); }
|
||||
catch (...) { result = false; }
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool Remove(
|
||||
const boost::interprocess::xsi_key &key
|
||||
) {
|
||||
bool ret = false;
|
||||
try{
|
||||
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
|
||||
boost::interprocess::xsi_shared_memory xsi(
|
||||
boost::interprocess::open_only,
|
||||
key
|
||||
);
|
||||
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) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static bool Remove(const boost::interprocess::xsi_key &key)
|
||||
{
|
||||
bool ret = false;
|
||||
try
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
|
||||
boost::interprocess::xsi_shared_memory xsi(boost::interprocess::open_only, key);
|
||||
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)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
boost::interprocess::xsi_key key;
|
||||
boost::interprocess::xsi_shared_memory shm;
|
||||
boost::interprocess::mapped_region region;
|
||||
shm_remove remover;
|
||||
boost::interprocess::xsi_key key;
|
||||
boost::interprocess::xsi_shared_memory shm;
|
||||
boost::interprocess::mapped_region region;
|
||||
shm_remove remover;
|
||||
};
|
||||
|
||||
template<class LockFileT = OSRMLockFile>
|
||||
class SharedMemoryFactory_tmpl : boost::noncopyable {
|
||||
public:
|
||||
template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
|
||||
{
|
||||
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 >
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SharedMemoryFactory_tmpl() {}
|
||||
SharedMemoryFactory_tmpl() = delete;
|
||||
SharedMemoryFactory_tmpl(const SharedMemoryFactory_tmpl &) = delete;
|
||||
};
|
||||
|
||||
typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory;
|
||||
|
@ -31,153 +31,114 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "../Util/SimpleLogger.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
template<typename DataT>
|
||||
class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT> {
|
||||
DataT * p;
|
||||
public:
|
||||
explicit ShMemIterator(DataT * x) : p(x) {}
|
||||
ShMemIterator(const ShMemIterator & mit) : p(mit.p) {}
|
||||
ShMemIterator& operator++() {
|
||||
template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
|
||||
{
|
||||
DataT *p;
|
||||
|
||||
public:
|
||||
explicit ShMemIterator(DataT *x) : p(x) {}
|
||||
ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
|
||||
ShMemIterator &operator++()
|
||||
{
|
||||
++p;
|
||||
return *this;
|
||||
}
|
||||
ShMemIterator operator++(int) {
|
||||
ShMemIterator operator++(int)
|
||||
{
|
||||
ShMemIterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
ShMemIterator operator+(std::ptrdiff_t diff) {
|
||||
ShMemIterator tmp(p+diff);
|
||||
ShMemIterator operator+(std::ptrdiff_t diff)
|
||||
{
|
||||
ShMemIterator tmp(p + diff);
|
||||
return tmp;
|
||||
}
|
||||
bool operator==(const ShMemIterator& rhs) {
|
||||
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; }
|
||||
bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
|
||||
DataT &operator*() { return *p; }
|
||||
};
|
||||
|
||||
template<typename DataT>
|
||||
class SharedMemoryWrapper {
|
||||
private:
|
||||
DataT * m_ptr;
|
||||
template <typename DataT> class SharedMemoryWrapper
|
||||
{
|
||||
private:
|
||||
DataT *m_ptr;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
SharedMemoryWrapper() :
|
||||
m_ptr(NULL),
|
||||
m_size(0)
|
||||
{ }
|
||||
public:
|
||||
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
|
||||
|
||||
SharedMemoryWrapper(DataT * ptr, std::size_t size) :
|
||||
m_ptr(ptr),
|
||||
m_size(size)
|
||||
{ }
|
||||
SharedMemoryWrapper(DataT *ptr, std::size_t 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");
|
||||
std::swap( m_size, other.m_size);
|
||||
std::swap( m_ptr , other.m_ptr );
|
||||
std::swap(m_size, other.m_size);
|
||||
std::swap(m_ptr, other.m_ptr);
|
||||
}
|
||||
|
||||
// void SetData(const DataT * ptr, const std::size_t size) {
|
||||
// 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) { return m_ptr[index]; }
|
||||
|
||||
DataT & at(const std::size_t index) {
|
||||
return m_ptr[index];
|
||||
}
|
||||
const DataT &at(const std::size_t index) const { return m_ptr[index]; }
|
||||
|
||||
const DataT & at(const std::size_t index) const {
|
||||
return m_ptr[index];
|
||||
}
|
||||
ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }
|
||||
|
||||
ShMemIterator<DataT> begin() const {
|
||||
return ShMemIterator<DataT>(m_ptr);
|
||||
}
|
||||
|
||||
ShMemIterator<DataT> end() const {
|
||||
return ShMemIterator<DataT>(m_ptr+m_size);
|
||||
}
|
||||
ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }
|
||||
|
||||
std::size_t size() const { return m_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");
|
||||
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");
|
||||
return m_ptr[index];
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class SharedMemoryWrapper<bool> {
|
||||
private:
|
||||
unsigned * m_ptr;
|
||||
template <> class SharedMemoryWrapper<bool>
|
||||
{
|
||||
private:
|
||||
unsigned *m_ptr;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
SharedMemoryWrapper() :
|
||||
m_ptr(NULL),
|
||||
m_size(0)
|
||||
{ }
|
||||
public:
|
||||
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
|
||||
|
||||
SharedMemoryWrapper(unsigned * ptr, std::size_t size) :
|
||||
m_ptr(ptr),
|
||||
m_size(size)
|
||||
{ }
|
||||
SharedMemoryWrapper(unsigned *ptr, std::size_t 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");
|
||||
std::swap( m_size, other.m_size);
|
||||
std::swap( m_ptr , other.m_ptr );
|
||||
std::swap(m_size, other.m_size);
|
||||
std::swap(m_ptr, other.m_ptr);
|
||||
}
|
||||
|
||||
// void SetData(const DataT * ptr, const std::size_t size) {
|
||||
// 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");
|
||||
bool at(const std::size_t index) const
|
||||
{
|
||||
const unsigned bucket = index / 32;
|
||||
const unsigned offset = index % 32;
|
||||
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; }
|
||||
|
||||
bool empty() const { return 0 == size(); }
|
||||
|
||||
bool operator[](const unsigned index) {
|
||||
bool operator[](const unsigned index)
|
||||
{
|
||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||
const unsigned bucket = index / 32;
|
||||
const unsigned offset = index % 32;
|
||||
@ -185,13 +146,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DataT, bool UseSharedMemory>
|
||||
struct ShM {
|
||||
typedef typename boost::conditional<
|
||||
UseSharedMemory,
|
||||
SharedMemoryWrapper<DataT>,
|
||||
std::vector<DataT>
|
||||
>::type vector;
|
||||
};
|
||||
template <typename DataT, bool UseSharedMemory> struct ShM
|
||||
{
|
||||
typedef typename std::conditional<UseSharedMemory,
|
||||
SharedMemoryWrapper<DataT>,
|
||||
std::vector<DataT>>::type vector;
|
||||
};
|
||||
|
||||
#endif //SHARED_MEMORY_VECTOR_WRAPPER_H
|
||||
#endif // SHARED_MEMORY_VECTOR_WRAPPER_H
|
||||
|
@ -36,17 +36,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <stack>
|
||||
#include <limits>
|
||||
|
||||
namespace KDTree {
|
||||
namespace KDTree
|
||||
{
|
||||
|
||||
#define KDTREE_BASESIZE (8)
|
||||
|
||||
template< unsigned k, typename T >
|
||||
class BoundingBox {
|
||||
public:
|
||||
BoundingBox() {
|
||||
for ( unsigned dim = 0; dim < k; ++dim ) {
|
||||
min[dim] = std::numeric_limits< T >::min();
|
||||
max[dim] = std::numeric_limits< T >::max();
|
||||
template <unsigned k, typename T> class BoundingBox
|
||||
{
|
||||
public:
|
||||
BoundingBox()
|
||||
{
|
||||
for (unsigned dim = 0; dim < k; ++dim)
|
||||
{
|
||||
min[dim] = std::numeric_limits<T>::min();
|
||||
max[dim] = std::numeric_limits<T>::max();
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,102 +57,118 @@ public:
|
||||
T max[k];
|
||||
};
|
||||
|
||||
struct NoData {};
|
||||
struct NoData
|
||||
{
|
||||
};
|
||||
|
||||
template< unsigned k, typename T >
|
||||
class EuclidianMetric {
|
||||
public:
|
||||
double operator() ( const T left[k], const T right[k] ) {
|
||||
template <unsigned k, typename T> class EuclidianMetric
|
||||
{
|
||||
public:
|
||||
double operator()(const T left[k], const T right[k])
|
||||
{
|
||||
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];
|
||||
result += temp * temp;
|
||||
}
|
||||
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];
|
||||
for ( unsigned dim = 0; dim < k; ++dim ) {
|
||||
if ( point[dim] < box.min[dim] )
|
||||
for (unsigned dim = 0; dim < k; ++dim)
|
||||
{
|
||||
if (point[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];
|
||||
else
|
||||
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 > >
|
||||
class StaticKDTree {
|
||||
public:
|
||||
|
||||
struct InputPoint {
|
||||
template <unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric<k, T>>
|
||||
class StaticKDTree
|
||||
{
|
||||
public:
|
||||
struct InputPoint
|
||||
{
|
||||
T coordinates[k];
|
||||
Data data;
|
||||
bool operator==( const InputPoint& right )
|
||||
{
|
||||
for ( int i = 0; i < k; i++ ) {
|
||||
if ( coordinates[i] != right.coordinates[i] )
|
||||
bool operator==(const InputPoint &right)
|
||||
{
|
||||
for (int i = 0; i < k; i++)
|
||||
{
|
||||
if (coordinates[i] != right.coordinates[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
explicit StaticKDTree( std::vector< InputPoint > * points ){
|
||||
BOOST_ASSERT( k > 0 );
|
||||
BOOST_ASSERT ( points->size() > 0 );
|
||||
explicit StaticKDTree(std::vector<InputPoint> *points)
|
||||
{
|
||||
BOOST_ASSERT(k > 0);
|
||||
BOOST_ASSERT(points->size() > 0);
|
||||
size = points->size();
|
||||
kdtree = new InputPoint[size];
|
||||
for ( Iterator i = 0; i != size; ++i ) {
|
||||
for (Iterator i = 0; i != size; ++i)
|
||||
{
|
||||
kdtree[i] = points->at(i);
|
||||
for ( unsigned dim = 0; dim < k; ++dim ) {
|
||||
if ( kdtree[i].coordinates[dim] < boundingBox.min[dim] )
|
||||
for (unsigned dim = 0; dim < k; ++dim)
|
||||
{
|
||||
if (kdtree[i].coordinates[dim] < boundingBox.min[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];
|
||||
}
|
||||
}
|
||||
std::stack< Tree > s;
|
||||
s.push ( Tree ( 0, size, 0 ) );
|
||||
while ( !s.empty() ) {
|
||||
std::stack<Tree> s;
|
||||
s.push(Tree(0, size, 0));
|
||||
while (!s.empty())
|
||||
{
|
||||
Tree tree = s.top();
|
||||
s.pop();
|
||||
|
||||
if ( tree.right - tree.left < KDTREE_BASESIZE )
|
||||
if (tree.right - tree.left < KDTREE_BASESIZE)
|
||||
continue;
|
||||
|
||||
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
|
||||
std::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) );
|
||||
s.push( Tree( tree.left, middle, ( tree.dimension + 1 ) % k ) );
|
||||
s.push( Tree( middle + 1, tree.right, ( tree.dimension + 1 ) % k ) );
|
||||
Iterator middle = tree.left + (tree.right - tree.left) / 2;
|
||||
std::nth_element(
|
||||
kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less(tree.dimension));
|
||||
s.push(Tree(tree.left, middle, (tree.dimension + 1) % k));
|
||||
s.push(Tree(middle + 1, tree.right, (tree.dimension + 1) % k));
|
||||
}
|
||||
}
|
||||
|
||||
~StaticKDTree(){
|
||||
delete[] kdtree;
|
||||
}
|
||||
~StaticKDTree() { delete[] kdtree; }
|
||||
|
||||
bool NearestNeighbor( InputPoint* result, const InputPoint& point ) {
|
||||
bool NearestNeighbor(InputPoint *result, const InputPoint &point)
|
||||
{
|
||||
Metric distance;
|
||||
bool found = false;
|
||||
double nearestDistance = std::numeric_limits< T >::max();
|
||||
std::stack< NNTree > s;
|
||||
s.push ( NNTree ( 0, size, 0, boundingBox ) );
|
||||
while ( !s.empty() ) {
|
||||
double nearestDistance = std::numeric_limits<T>::max();
|
||||
std::stack<NNTree> s;
|
||||
s.push(NNTree(0, size, 0, boundingBox));
|
||||
while (!s.empty())
|
||||
{
|
||||
NNTree tree = s.top();
|
||||
s.pop();
|
||||
|
||||
if ( distance( tree.box, point.coordinates ) >= nearestDistance )
|
||||
if (distance(tree.box, point.coordinates) >= nearestDistance)
|
||||
continue;
|
||||
|
||||
if ( tree.right - tree.left < KDTREE_BASESIZE ) {
|
||||
for ( unsigned i = tree.left; i < tree.right; i++ ) {
|
||||
double newDistance = distance( kdtree[i].coordinates, point.coordinates );
|
||||
if ( newDistance < nearestDistance ) {
|
||||
if (tree.right - tree.left < KDTREE_BASESIZE)
|
||||
{
|
||||
for (unsigned i = tree.left; i < tree.right; i++)
|
||||
{
|
||||
double newDistance = distance(kdtree[i].coordinates, point.coordinates);
|
||||
if (newDistance < nearestDistance)
|
||||
{
|
||||
nearestDistance = newDistance;
|
||||
*result = kdtree[i];
|
||||
found = true;
|
||||
@ -158,73 +177,84 @@ public:
|
||||
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 );
|
||||
if ( newDistance < nearestDistance ) {
|
||||
double newDistance = distance(kdtree[middle].coordinates, point.coordinates);
|
||||
if (newDistance < nearestDistance)
|
||||
{
|
||||
nearestDistance = newDistance;
|
||||
*result = kdtree[middle];
|
||||
found = true;
|
||||
}
|
||||
|
||||
Less comperator( tree.dimension );
|
||||
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 );
|
||||
Less comperator(tree.dimension);
|
||||
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);
|
||||
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||
s.push( second );
|
||||
s.push( first );
|
||||
s.push(second);
|
||||
s.push(first);
|
||||
}
|
||||
else {
|
||||
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
|
||||
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
|
||||
else
|
||||
{
|
||||
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];
|
||||
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||
s.push( first );
|
||||
s.push( second );
|
||||
s.push(first);
|
||||
s.push(second);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
typedef unsigned Iterator;
|
||||
struct Tree {
|
||||
struct Tree
|
||||
{
|
||||
Iterator left;
|
||||
Iterator right;
|
||||
unsigned dimension;
|
||||
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 right;
|
||||
unsigned dimension;
|
||||
BoundingBox< k, T > box;
|
||||
BoundingBox<k, T> box;
|
||||
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 {
|
||||
public:
|
||||
explicit Less( unsigned d ) {
|
||||
class Less
|
||||
{
|
||||
public:
|
||||
explicit Less(unsigned d)
|
||||
{
|
||||
dimension = d;
|
||||
BOOST_ASSERT( dimension < k );
|
||||
BOOST_ASSERT(dimension < k);
|
||||
}
|
||||
|
||||
bool operator() ( const InputPoint& left, const InputPoint& right ) {
|
||||
BOOST_ASSERT( dimension < k );
|
||||
bool operator()(const InputPoint &left, const InputPoint &right)
|
||||
{
|
||||
BOOST_ASSERT(dimension < k);
|
||||
return left.coordinates[dimension] < right.coordinates[dimension];
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
unsigned dimension;
|
||||
};
|
||||
|
||||
BoundingBox< k, T > boundingBox;
|
||||
InputPoint* kdtree;
|
||||
BoundingBox<k, T> boundingBox;
|
||||
InputPoint *kdtree;
|
||||
Iterator size;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // STATICKDTREE_H_INCLUDED
|
||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef STATICRTREE_H_
|
||||
#define STATICRTREE_H_
|
||||
#ifndef STATICRTREE_H
|
||||
#define STATICRTREE_H
|
||||
|
||||
#include "DeallocatingVector.h"
|
||||
#include "HilbertValue.h"
|
||||
@ -45,7 +45,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
@ -67,7 +66,7 @@ static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtre
|
||||
template <class DataT,
|
||||
class CoordinateListT = std::vector<FixedPointCoordinate>,
|
||||
bool UseSharedMemory = false>
|
||||
class StaticRTree : boost::noncopyable
|
||||
class StaticRTree
|
||||
{
|
||||
public:
|
||||
struct RectangleInt2D
|
||||
@ -269,6 +268,9 @@ class StaticRTree : boost::noncopyable
|
||||
boost::shared_ptr<CoordinateListT> m_coordinate_list;
|
||||
|
||||
public:
|
||||
StaticRTree() = delete;
|
||||
StaticRTree(const StaticRTree &) = delete;
|
||||
|
||||
// Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
|
||||
explicit StaticRTree(std::vector<DataT> &input_data_vector,
|
||||
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)
|
||||
{
|
||||
DataT const ¤t_edge = current_leaf_node.objects[i];
|
||||
if (ignore_tiny_components && current_edge.belongsToTinyComponent)
|
||||
if (ignore_tiny_components && current_edge.is_in_tiny_cc)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -637,7 +639,7 @@ class StaticRTree : boost::noncopyable
|
||||
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
|
||||
{
|
||||
DataT ¤t_edge = current_leaf_node.objects[i];
|
||||
if (ignore_tiny_components && current_edge.belongsToTinyComponent)
|
||||
if (ignore_tiny_components && current_edge.is_in_tiny_cc)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -784,4 +786,4 @@ class StaticRTree : boost::noncopyable
|
||||
//[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
|
||||
|
||||
#endif /* STATICRTREE_H_ */
|
||||
#endif // STATICRTREE_H
|
||||
|
@ -25,18 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TURNINSTRUCTIONS_H_
|
||||
#define TURNINSTRUCTIONS_H_
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#ifndef TURN_INSTRUCTIONS_H
|
||||
#define TURN_INSTRUCTIONS_H
|
||||
|
||||
typedef unsigned char TurnInstruction;
|
||||
|
||||
//This is a hack until c++0x is available enough to use scoped enums
|
||||
struct TurnInstructionsClass : boost::noncopyable {
|
||||
// This is a hack until c++0x is available enough to use scoped enums
|
||||
struct TurnInstructionsClass
|
||||
{
|
||||
TurnInstructionsClass() = delete;
|
||||
TurnInstructionsClass(const TurnInstructionsClass&) = delete;
|
||||
|
||||
const static TurnInstruction NoTurn = 0; //Give no instruction at all
|
||||
const static TurnInstruction GoStraight = 1; //Tell user to go straight!
|
||||
const static TurnInstruction NoTurn = 0; // Give no instruction at all
|
||||
const static TurnInstruction GoStraight = 1; // Tell user to go straight!
|
||||
const static TurnInstruction TurnSlightRight = 2;
|
||||
const static TurnInstruction TurnRight = 3;
|
||||
const static TurnInstruction TurnSharpRight = 4;
|
||||
@ -55,41 +56,51 @@ struct TurnInstructionsClass : boost::noncopyable {
|
||||
const static TurnInstruction LeaveAgainstAllowedDirection = 17;
|
||||
|
||||
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 ) {
|
||||
if(angle >= 23 && angle < 67) {
|
||||
static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle)
|
||||
{
|
||||
if (angle >= 23 && angle < 67)
|
||||
{
|
||||
return TurnSharpRight;
|
||||
}
|
||||
if (angle >= 67 && angle < 113) {
|
||||
if (angle >= 67 && angle < 113)
|
||||
{
|
||||
return TurnRight;
|
||||
}
|
||||
if (angle >= 113 && angle < 158) {
|
||||
if (angle >= 113 && angle < 158)
|
||||
{
|
||||
return TurnSlightRight;
|
||||
}
|
||||
if (angle >= 158 && angle < 202) {
|
||||
if (angle >= 158 && angle < 202)
|
||||
{
|
||||
return GoStraight;
|
||||
}
|
||||
if (angle >= 202 && angle < 248) {
|
||||
if (angle >= 202 && angle < 248)
|
||||
{
|
||||
return TurnSlightLeft;
|
||||
}
|
||||
if (angle >= 248 && angle < 292) {
|
||||
if (angle >= 248 && angle < 292)
|
||||
{
|
||||
return TurnLeft;
|
||||
}
|
||||
if (angle >= 292 && angle < 336) {
|
||||
if (angle >= 292 && angle < 336)
|
||||
{
|
||||
return TurnSharpLeft;
|
||||
}
|
||||
return UTurn;
|
||||
}
|
||||
|
||||
static inline bool TurnIsNecessary ( const short turnInstruction ) {
|
||||
if(NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction)
|
||||
static inline bool TurnIsNecessary(const short turnInstruction)
|
||||
{
|
||||
if (NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif /* TURNINSTRUCTIONS_H_ */
|
||||
#endif /* TURN_INSTRUCTIONS_H */
|
||||
|
@ -25,14 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FASTXORHASH_H_
|
||||
#define FASTXORHASH_H_
|
||||
#ifndef XOR_FAST_HASH_H
|
||||
#define XOR_FAST_HASH_H
|
||||
|
||||
#include <algorithm>
|
||||
#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.
|
||||
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
|
||||
|
||||
*/
|
||||
class XORFastHash { //65k entries
|
||||
class XORFastHash
|
||||
{ // 65k entries
|
||||
std::vector<unsigned short> table1;
|
||||
std::vector<unsigned short> table2;
|
||||
public:
|
||||
XORFastHash() {
|
||||
|
||||
public:
|
||||
XORFastHash()
|
||||
{
|
||||
table1.resize(2 << 16);
|
||||
table2.resize(2 << 16);
|
||||
for(unsigned i = 0; i < (2 << 16); ++i) {
|
||||
table1[i] = i; table2[i] = i;
|
||||
for (unsigned i = 0; i < (2 << 16); ++i)
|
||||
{
|
||||
table1[i] = i;
|
||||
table2[i] = i;
|
||||
}
|
||||
std::random_shuffle(table1.begin(), table1.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 msb = (((originalValue) >> 16) & 0xffff);
|
||||
return table1[lsb] ^ table2[msb];
|
||||
}
|
||||
};
|
||||
|
||||
class XORMiniHash { //256 entries
|
||||
class XORMiniHash
|
||||
{ // 256 entries
|
||||
std::vector<unsigned char> table1;
|
||||
std::vector<unsigned char> table2;
|
||||
std::vector<unsigned char> table3;
|
||||
std::vector<unsigned char> table4;
|
||||
|
||||
public:
|
||||
XORMiniHash() {
|
||||
public:
|
||||
XORMiniHash()
|
||||
{
|
||||
table1.resize(1 << 8);
|
||||
table2.resize(1 << 8);
|
||||
table3.resize(1 << 8);
|
||||
table4.resize(1 << 8);
|
||||
for(unsigned i = 0; i < (1 << 8); ++i) {
|
||||
table1[i] = i; table2[i] = i;
|
||||
table3[i] = i; table4[i] = i;
|
||||
for (unsigned i = 0; i < (1 << 8); ++i)
|
||||
{
|
||||
table1[i] = i;
|
||||
table2[i] = i;
|
||||
table3[i] = i;
|
||||
table4[i] = i;
|
||||
}
|
||||
std::random_shuffle(table1.begin(), table1.end());
|
||||
std::random_shuffle(table2.begin(), table2.end());
|
||||
std::random_shuffle(table3.begin(), table3.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 byte2 = ((originalValue >> 8) & 0xff);
|
||||
unsigned char byte3 = ((originalValue >> 16) & 0xff);
|
||||
@ -99,4 +112,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* FASTXORHASH_H_ */
|
||||
#endif // XOR_FAST_HASH_H
|
||||
|
@ -25,63 +25,65 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef XORFASTHASHSTORAGE_H_
|
||||
#define XORFASTHASHSTORAGE_H_
|
||||
#ifndef XOR_FAST_HASH_STORAGE_H
|
||||
#define XOR_FAST_HASH_STORAGE_H
|
||||
|
||||
#include "XORFastHash.h"
|
||||
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
|
||||
template< typename NodeID, typename Key >
|
||||
class XORFastHashStorage {
|
||||
public:
|
||||
struct HashCell{
|
||||
template <typename NodeID, typename Key> class XORFastHashStorage
|
||||
{
|
||||
public:
|
||||
struct HashCell
|
||||
{
|
||||
Key key;
|
||||
NodeID id;
|
||||
unsigned time;
|
||||
HashCell() : key(UINT_MAX), id(UINT_MAX), time(UINT_MAX) {}
|
||||
|
||||
HashCell(const HashCell & other) : key(other.key), id(other.id), time(other.time) { }
|
||||
|
||||
inline operator Key() const {
|
||||
return key;
|
||||
HashCell()
|
||||
: key(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
|
||||
time(std::numeric_limits<unsigned>::max())
|
||||
{
|
||||
}
|
||||
|
||||
inline void operator=(const Key & keyToInsert) {
|
||||
key = keyToInsert;
|
||||
}
|
||||
HashCell(const HashCell &other) : key(other.key), id(other.id), time(other.time) {}
|
||||
|
||||
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 ) {
|
||||
unsigned short position = fastHash(node);
|
||||
while((positions[position].time == currentTimestamp) && (positions[position].id != node)){
|
||||
++position %= (2<<16);
|
||||
inline HashCell &operator[](const NodeID node)
|
||||
{
|
||||
unsigned short position = fast_hasher(node);
|
||||
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
||||
{
|
||||
++position %= (2 << 16);
|
||||
}
|
||||
|
||||
positions[position].id = node;
|
||||
positions[position].time = currentTimestamp;
|
||||
positions[position].time = current_timestamp;
|
||||
return positions[position];
|
||||
}
|
||||
|
||||
inline void Clear() {
|
||||
++currentTimestamp;
|
||||
if(UINT_MAX == currentTimestamp) {
|
||||
inline void Clear()
|
||||
{
|
||||
++current_timestamp;
|
||||
if (std::numeric_limits<unsigned>::max() == current_timestamp)
|
||||
{
|
||||
positions.clear();
|
||||
positions.resize((2<<16));
|
||||
positions.resize((2 << 16));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
XORFastHashStorage() : positions(2<<16), currentTimestamp(0) {}
|
||||
private:
|
||||
XORFastHashStorage() : positions(2 << 16), current_timestamp(0) {}
|
||||
std::vector<HashCell> positions;
|
||||
XORFastHash fastHash;
|
||||
unsigned currentTimestamp;
|
||||
XORFastHash fast_hasher;
|
||||
unsigned current_timestamp;
|
||||
};
|
||||
|
||||
|
||||
#endif /* XORFASTHASHSTORAGE_H_ */
|
||||
|
||||
#endif // XOR_FAST_HASH_STORAGE_H
|
||||
|
@ -90,9 +90,9 @@ void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
|
||||
{
|
||||
path_description.push_back(SegmentInformation(coordinate,
|
||||
path_point.name_id,
|
||||
path_point.durationOfSegment,
|
||||
path_point.segment_duration,
|
||||
0,
|
||||
path_point.turnInstruction));
|
||||
path_point.turn_instruction));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
|
||||
" OpenStreetMap contributors (ODbL)</license></copyright>"
|
||||
"</metadata>");
|
||||
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());
|
||||
if (found_route)
|
||||
{
|
||||
|
@ -110,7 +110,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
||||
facade = f;
|
||||
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 ;-)
|
||||
reply.content.push_back(
|
||||
@ -118,14 +118,14 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath;
|
||||
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.shortest_path_length;
|
||||
|
||||
// check if first segment is non-zero
|
||||
std::string road_name =
|
||||
facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
|
||||
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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,
|
||||
reply,
|
||||
raw_route.lengthOfShortestPath,
|
||||
raw_route.shortest_path_length,
|
||||
facade,
|
||||
shortest_path_segments);
|
||||
}
|
||||
reply.content.push_back("],");
|
||||
description_factory.BuildRouteSummary(description_factory.entireLength,
|
||||
raw_route.lengthOfShortestPath);
|
||||
raw_route.shortest_path_length);
|
||||
|
||||
reply.content.push_back("\"route_summary\":");
|
||||
reply.content.push_back("{");
|
||||
@ -187,7 +187,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
||||
reply.content.push_back(",");
|
||||
|
||||
// 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,
|
||||
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
|
||||
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
|
||||
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("\"alternative_instructions\":[");
|
||||
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
||||
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||
{
|
||||
reply.content.push_back("[");
|
||||
// Generate instructions for each alternative
|
||||
@ -220,7 +220,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
||||
{
|
||||
BuildTextualDescription(alternate_descriptionFactory,
|
||||
reply,
|
||||
raw_route.lengthOfAlternativePath,
|
||||
raw_route.alternative_path_length,
|
||||
facade,
|
||||
alternative_path_segments);
|
||||
}
|
||||
@ -228,11 +228,11 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
||||
}
|
||||
reply.content.push_back("],");
|
||||
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
|
||||
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("\"total_distance\":");
|
||||
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
|
||||
reply.content.push_back("\"via_points\":[");
|
||||
|
||||
BOOST_ASSERT(!raw_route.segmentEndCoordinates.empty());
|
||||
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
|
||||
|
||||
std::string tmp;
|
||||
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(tmp);
|
||||
reply.content.push_back("]");
|
||||
|
||||
for (const PhantomNodes &nodes : raw_route.segmentEndCoordinates)
|
||||
for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
|
||||
{
|
||||
tmp.clear();
|
||||
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
||||
@ -303,7 +303,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
||||
}
|
||||
}
|
||||
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,");
|
||||
tmp.clear();
|
||||
@ -314,19 +314,19 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
||||
reply.content.push_back("],");
|
||||
reply.content.push_back("\"hint_data\": {");
|
||||
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(", \"locations\": [");
|
||||
|
||||
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("\"");
|
||||
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("\", ");
|
||||
}
|
||||
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(hint);
|
||||
reply.content.push_back("\"]");
|
||||
|
@ -71,7 +71,7 @@ struct RouteParameters
|
||||
bool geometry;
|
||||
bool compression;
|
||||
bool deprecatedAPI;
|
||||
unsigned checkSum;
|
||||
unsigned check_sum;
|
||||
std::string service;
|
||||
std::string outputFormat;
|
||||
std::string jsonpParameter;
|
||||
|
@ -53,7 +53,7 @@ class HelloWorldPlugin : public BasePlugin
|
||||
intToString(routeParameters.zoomLevel, temp_string);
|
||||
reply.content.push_back(temp_string);
|
||||
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("\ninstructions: ");
|
||||
reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));
|
||||
|
@ -76,7 +76,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
||||
}
|
||||
|
||||
RawRouteData raw_route;
|
||||
raw_route.checkSum = facade->GetCheckSum();
|
||||
raw_route.check_sum = facade->GetCheckSum();
|
||||
|
||||
if (std::any_of(begin(routeParameters.coordinates),
|
||||
end(routeParameters.coordinates),
|
||||
@ -89,13 +89,13 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
||||
|
||||
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());
|
||||
const bool checksum_OK = (routeParameters.checkSum == raw_route.checkSum);
|
||||
std::vector<PhantomNode> phantom_node_vector(raw_route.raw_via_node_coordinates.size());
|
||||
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() &&
|
||||
!routeParameters.hints[i].empty())
|
||||
@ -106,7 +106,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
||||
continue;
|
||||
}
|
||||
}
|
||||
facade->FindPhantomNodeForCoordinate(raw_route.rawViaNodeCoordinates[i],
|
||||
facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
|
||||
phantom_node_vector[i],
|
||||
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.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
|
||||
{
|
||||
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";
|
||||
}
|
||||
@ -165,8 +165,8 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
||||
}
|
||||
|
||||
PhantomNodes phantom_nodes;
|
||||
phantom_nodes.source_phantom = raw_route.segmentEndCoordinates.front().source_phantom;
|
||||
phantom_nodes.target_phantom = raw_route.segmentEndCoordinates.back().target_phantom;
|
||||
phantom_nodes.source_phantom = raw_route.segment_end_coordinates.front().source_phantom;
|
||||
phantom_nodes.target_phantom = raw_route.segment_end_coordinates.back().target_phantom;
|
||||
descriptor->SetConfig(descriptor_config);
|
||||
descriptor->Run(raw_route, phantom_nodes, facade, reply);
|
||||
|
||||
|
@ -315,7 +315,7 @@ public:
|
||||
// -- unpacked output
|
||||
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 ) {
|
||||
@ -341,7 +341,7 @@ public:
|
||||
raw_route_data.unpacked_alternative
|
||||
);
|
||||
|
||||
raw_route_data.lengthOfAlternativePath = length_of_via_path;
|
||||
raw_route_data.alternative_path_length = length_of_via_path;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,8 +231,8 @@ public:
|
||||
)
|
||||
);
|
||||
}
|
||||
unpacked_path.back().turnInstruction = turn_instruction;
|
||||
unpacked_path.back().durationOfSegment = ed.distance;
|
||||
unpacked_path.back().turn_instruction = turn_instruction;
|
||||
unpacked_path.back().segment_duration = ed.distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ public:
|
||||
for (const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
|
||||
{
|
||||
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
|
||||
// raw_route_data.lengthOfShortestPath = INT_MAX;
|
||||
// raw_route_data.lengthOfAlternativePath = INT_MAX;
|
||||
// raw_route_data.shortest_path_length = INT_MAX;
|
||||
// raw_route_data.alternative_path_length = INT_MAX;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -212,8 +212,8 @@ public:
|
||||
(INVALID_EDGE_WEIGHT == local_upper_bound1) &&
|
||||
(INVALID_EDGE_WEIGHT == local_upper_bound2)
|
||||
) {
|
||||
raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
|
||||
raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
|
||||
raw_route_data.shortest_path_length = INVALID_EDGE_WEIGHT;
|
||||
raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT;
|
||||
return;
|
||||
}
|
||||
if( SPECIAL_NODEID == middle1 ) {
|
||||
@ -393,7 +393,7 @@ public:
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -91,7 +91,7 @@ int main (int argc, const char * argv[]) {
|
||||
route_parameters.alternateRoute = true; //get an alternate route, too
|
||||
route_parameters.geometry = true; //retrieve geometry of route
|
||||
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.outputFormat = "json";
|
||||
route_parameters.jsonpParameter = ""; //set for jsonp wrapping
|
||||
|
Loading…
Reference in New Issue
Block a user