Apply clang-format on Contractor/

This commit is contained in:
Patrick Niklaus 2014-05-08 23:07:16 +02:00
parent 79d33d669c
commit d13cd4d4b3
7 changed files with 968 additions and 835 deletions

View File

@ -48,14 +48,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits> #include <limits>
#include <vector> #include <vector>
class Contractor { class Contractor
{
private: private:
struct ContractorEdgeData { struct ContractorEdgeData
ContractorEdgeData() : {
distance(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0), originalViaNodeID(false) {} ContractorEdgeData()
ContractorEdgeData( unsigned _distance, unsigned _originalEdges, unsigned _id, bool _shortcut, bool _forward, bool _backward) : : distance(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0),
distance(_distance), id(_id), originalEdges(std::min((unsigned)1<<28, _originalEdges) ), shortcut(_shortcut), forward(_forward), backward(_backward), originalViaNodeID(false) {} originalViaNodeID(false)
{
}
ContractorEdgeData(unsigned _distance,
unsigned _originalEdges,
unsigned _id,
bool _shortcut,
bool _forward,
bool _backward)
: distance(_distance), id(_id),
originalEdges(std::min((unsigned)1 << 28, _originalEdges)), shortcut(_shortcut),
forward(_forward), backward(_backward), originalViaNodeID(false)
{
}
unsigned distance; unsigned distance;
unsigned id; unsigned id;
unsigned originalEdges : 28; unsigned originalEdges : 28;
@ -65,7 +79,8 @@ private:
bool originalViaNodeID : 1; bool originalViaNodeID : 1;
} data; } data;
struct _HeapData { struct _HeapData
{
short hop; short hop;
bool target; bool target;
_HeapData() : hop(0), target(false) {} _HeapData() : hop(0), target(false) {}
@ -77,42 +92,50 @@ private:
typedef BinaryHeap<NodeID, NodeID, int, _HeapData, XORFastHashStorage<NodeID, NodeID>> _Heap; typedef BinaryHeap<NodeID, NodeID, int, _HeapData, XORFastHashStorage<NodeID, NodeID>> _Heap;
typedef _DynamicGraph::InputEdge _ContractorEdge; typedef _DynamicGraph::InputEdge _ContractorEdge;
struct _ThreadData { struct _ThreadData
{
_Heap heap; _Heap heap;
std::vector<_ContractorEdge> insertedEdges; std::vector<_ContractorEdge> insertedEdges;
std::vector<NodeID> neighbours; std::vector<NodeID> neighbours;
_ThreadData(NodeID nodes) : heap(nodes) {} _ThreadData(NodeID nodes) : heap(nodes) {}
}; };
struct _PriorityData { struct _PriorityData
{
int depth; int depth;
_PriorityData() : depth(0) {} _PriorityData() : depth(0) {}
}; };
struct _ContractionInformation { struct _ContractionInformation
{
int edgesDeleted; int edgesDeleted;
int edgesAdded; int edgesAdded;
int originalEdgesDeleted; int originalEdgesDeleted;
int originalEdgesAdded; int originalEdgesAdded;
_ContractionInformation() : edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0) {} _ContractionInformation()
: edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0)
{
}
}; };
struct _RemainingNodeData { struct _RemainingNodeData
{
_RemainingNodeData() : id(0), isIndependent(false) {} _RemainingNodeData() : id(0), isIndependent(false) {}
NodeID id : 31; NodeID id : 31;
bool isIndependent : 1; bool isIndependent : 1;
}; };
struct _NodePartitionor { struct _NodePartitionor
inline bool operator()(_RemainingNodeData & nodeData ) const { {
inline bool operator()(_RemainingNodeData &nodeData) const
{
return !nodeData.isIndependent; return !nodeData.isIndependent;
} }
}; };
public: public:
template <class ContainerT> Contractor(int nodes, ContainerT &inputEdges)
template<class ContainerT > {
Contractor( int nodes, ContainerT& inputEdges) {
std::vector<_ContractorEdge> edges; std::vector<_ContractorEdge> edges;
edges.reserve(inputEdges.size() * 2); edges.reserve(inputEdges.size() * 2);
temp_edge_counter = 0; temp_edge_counter = 0;
@ -121,15 +144,22 @@ public:
typename ContainerT::deallocation_iterator dend = inputEdges.dend(); typename ContainerT::deallocation_iterator dend = inputEdges.dend();
_ContractorEdge newEdge; _ContractorEdge newEdge;
while(diter!=dend) { while (diter != dend)
{
newEdge.source = diter->source(); newEdge.source = diter->source();
newEdge.target = diter->target(); newEdge.target = diter->target();
newEdge.data = ContractorEdgeData( (std::max)((int)diter->weight(), 1 ), 1, diter->id(), false, diter->isForward(), diter->isBackward()); newEdge.data = ContractorEdgeData((std::max)((int)diter->weight(), 1),
1,
diter->id(),
false,
diter->isForward(),
diter->isBackward());
BOOST_ASSERT_MSG(newEdge.data.distance > 0, "edge distance < 1"); BOOST_ASSERT_MSG(newEdge.data.distance > 0, "edge distance < 1");
#ifndef NDEBUG #ifndef NDEBUG
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) { if (newEdge.data.distance > 24 * 60 * 60 * 10)
SimpleLogger().Write(logWARNING) << {
"Edge weight large -> " << newEdge.data.distance; SimpleLogger().Write(logWARNING) << "Edge weight large -> "
<< newEdge.data.distance;
} }
#endif #endif
edges.push_back(newEdge); edges.push_back(newEdge);
@ -143,12 +173,14 @@ public:
inputEdges.clear(); inputEdges.clear();
sort(edges.begin(), edges.end()); sort(edges.begin(), edges.end());
NodeID edge = 0; NodeID edge = 0;
for ( NodeID i = 0; i < edges.size(); ) { for (NodeID i = 0; i < edges.size();)
{
const NodeID source = edges[i].source; const NodeID source = edges[i].source;
const NodeID target = edges[i].target; const NodeID target = edges[i].target;
const NodeID id = edges[i].data.id; const NodeID id = edges[i].data.id;
// remove eigenloops // remove eigenloops
if ( source == target ) { if (source == target)
{
i++; i++;
continue; continue;
} }
@ -161,33 +193,46 @@ public:
forwardEdge.data.shortcut = backwardEdge.data.shortcut = false; forwardEdge.data.shortcut = backwardEdge.data.shortcut = false;
forwardEdge.data.id = backwardEdge.data.id = id; forwardEdge.data.id = backwardEdge.data.id = id;
forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1; forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1;
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max(); forwardEdge.data.distance = backwardEdge.data.distance =
std::numeric_limits<int>::max();
// remove parallel edges // remove parallel edges
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) { while (i < edges.size() && edges[i].source == source && edges[i].target == target)
if ( edges[i].data.forward) { {
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance ); if (edges[i].data.forward)
{
forwardEdge.data.distance =
std::min(edges[i].data.distance, forwardEdge.data.distance);
} }
if ( edges[i].data.backward) { if (edges[i].data.backward)
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance ); {
backwardEdge.data.distance =
std::min(edges[i].data.distance, backwardEdge.data.distance);
} }
++i; ++i;
} }
// merge edges (s,t) and (t,s) into bidirectional edge // merge edges (s,t) and (t,s) into bidirectional edge
if ( forwardEdge.data.distance == backwardEdge.data.distance ) { if (forwardEdge.data.distance == backwardEdge.data.distance)
if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) { {
if ((int)forwardEdge.data.distance != std::numeric_limits<int>::max())
{
forwardEdge.data.backward = true; forwardEdge.data.backward = true;
edges[edge++] = forwardEdge; edges[edge++] = forwardEdge;
} }
} else { //insert seperate edges }
if ( ((int)forwardEdge.data.distance) != std::numeric_limits< int >::max() ) { else
{ // insert seperate edges
if (((int)forwardEdge.data.distance) != std::numeric_limits<int>::max())
{
edges[edge++] = forwardEdge; edges[edge++] = forwardEdge;
} }
if ( (int)backwardEdge.data.distance != std::numeric_limits< int >::max() ) { if ((int)backwardEdge.data.distance != std::numeric_limits<int>::max())
{
edges[edge++] = backwardEdge; edges[edge++] = backwardEdge;
} }
} }
} }
std::cout << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl; std::cout << "merged " << edges.size() - edge << " edges out of " << edges.size()
<< std::endl;
edges.resize(edge); edges.resize(edge);
_graph = boost::make_shared<_DynamicGraph>(nodes, edges); _graph = boost::make_shared<_DynamicGraph>(nodes, edges);
edges.clear(); edges.clear();
@ -204,9 +249,12 @@ public:
// } // }
// } // }
// //
// SimpleLogger().Write() << "edges at node with id " << highestNode << " has degree " << maxdegree; // SimpleLogger().Write() << "edges at node with id " << highestNode << " has degree
// for(unsigned i = _graph->BeginEdges(highestNode); i < _graph->EndEdges(highestNode); ++i) { // " << maxdegree;
// SimpleLogger().Write() << " ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via; // for(unsigned i = _graph->BeginEdges(highestNode); i <
// _graph->EndEdges(highestNode); ++i) {
// SimpleLogger().Write() << " ->(" << highestNode << "," << _graph->GetTarget(i)
// << "); via: " << _graph->GetEdgeData(i).via;
// } // }
// Create temporary file // Create temporary file
@ -216,19 +264,22 @@ public:
std::cout << "contractor finished initalization" << std::endl; std::cout << "contractor finished initalization" << std::endl;
} }
~Contractor() { ~Contractor()
{
// Delete temporary file // Delete temporary file
// remove(temporaryEdgeStorageFilename.c_str()); // remove(temporaryEdgeStorageFilename.c_str());
TemporaryStorage::GetInstance().DeallocateSlot(edge_storage_slot); TemporaryStorage::GetInstance().DeallocateSlot(edge_storage_slot);
} }
void Run() { void Run()
{
const NodeID numberOfNodes = _graph->GetNumberOfNodes(); const NodeID numberOfNodes = _graph->GetNumberOfNodes();
Percent p(numberOfNodes); Percent p(numberOfNodes);
const unsigned maxThreads = omp_get_max_threads(); const unsigned maxThreads = omp_get_max_threads();
std::vector<_ThreadData *> threadData; std::vector<_ThreadData *> threadData;
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) { for (unsigned threadNum = 0; threadNum < maxThreads; ++threadNum)
{
threadData.push_back(new _ThreadData(numberOfNodes)); threadData.push_back(new _ThreadData(numberOfNodes));
} }
std::cout << "Contractor is using " << maxThreads << " threads" << std::endl; std::cout << "Contractor is using " << maxThreads << " threads" << std::endl;
@ -240,7 +291,8 @@ public:
// initialize the variables // initialize the variables
#pragma omp parallel for schedule(guided) #pragma omp parallel for schedule(guided)
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) { for (int x = 0; x < (int)numberOfNodes; ++x)
{
remainingNodes[x].id = x; remainingNodes[x].id = x;
} }
@ -249,16 +301,22 @@ public:
{ {
_ThreadData *data = threadData[omp_get_thread_num()]; _ThreadData *data = threadData[omp_get_thread_num()];
#pragma omp parallel for schedule(guided) #pragma omp parallel for schedule(guided)
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) { for (int x = 0; x < (int)numberOfNodes; ++x)
{
nodePriority[x] = _Evaluate(data, &nodeData[x], x); nodePriority[x] = _Evaluate(data, &nodeData[x], x);
} }
} }
std::cout << "ok" << std::endl << "preprocessing " << numberOfNodes << " nodes ..." << std::flush; std::cout << "ok" << std::endl << "preprocessing " << numberOfNodes << " nodes ..."
<< std::flush;
bool flushedContractor = false; bool flushedContractor = false;
while ( numberOfNodes > 2 && numberOfContractedNodes < numberOfNodes ) { while (numberOfNodes > 2 && numberOfContractedNodes < numberOfNodes)
if(!flushedContractor && (numberOfContractedNodes > (numberOfNodes*0.65) ) ){ {
DeallocatingVector<_ContractorEdge> newSetOfEdges; //this one is not explicitely cleared since it goes out of scope anywa if (!flushedContractor && (numberOfContractedNodes > (numberOfNodes * 0.65)))
{
DeallocatingVector<_ContractorEdge> newSetOfEdges; // this one is not explicitely
// cleared since it goes out of
// scope anywa
std::cout << " [flush " << numberOfContractedNodes << " nodes] " << std::flush; std::cout << " [flush " << numberOfContractedNodes << " nodes] " << std::flush;
//Delete old heap data to free memory that we need for the coming operations //Delete old heap data to free memory that we need for the coming operations
@ -269,13 +327,17 @@ public:
// Create new priority array // Create new priority array
std::vector<float> newNodePriority(remainingNodes.size()); std::vector<float> newNodePriority(remainingNodes.size());
//this map gives the old IDs from the new ones, necessary to get a consistent graph at the end of contraction // this map gives the old IDs from the new ones, necessary to get a consistent graph
// at the end of contraction
oldNodeIDFromNewNodeIDMap.resize(remainingNodes.size()); oldNodeIDFromNewNodeIDMap.resize(remainingNodes.size());
//this map gives the new IDs from the old ones, necessary to remap targets from the remaining graph // this map gives the new IDs from the old ones, necessary to remap targets from the
// remaining graph
std::vector<NodeID> newNodeIDFromOldNodeIDMap(numberOfNodes, UINT_MAX); std::vector<NodeID> newNodeIDFromOldNodeIDMap(numberOfNodes, UINT_MAX);
//build forward and backward renumbering map and remap ids in remainingNodes and Priorities. // build forward and backward renumbering map and remap ids in remainingNodes and
for(unsigned newNodeID = 0; newNodeID < remainingNodes.size(); ++newNodeID) { // Priorities.
for (unsigned newNodeID = 0; newNodeID < remainingNodes.size(); ++newNodeID)
{
// create renumbering maps in both directions // create renumbering maps in both directions
oldNodeIDFromNewNodeIDMap[newNodeID] = remainingNodes[newNodeID].id; oldNodeIDFromNewNodeIDMap[newNodeID] = remainingNodes[newNodeID].id;
newNodeIDFromOldNodeIDMap[remainingNodes[newNodeID].id] = newNodeID; newNodeIDFromOldNodeIDMap[remainingNodes[newNodeID].id] = newNodeID;
@ -284,18 +346,28 @@ public:
} }
TemporaryStorage &tempStorage = TemporaryStorage::GetInstance(); TemporaryStorage &tempStorage = TemporaryStorage::GetInstance();
// walk over all nodes // walk over all nodes
for(unsigned i = 0; i < _graph->GetNumberOfNodes(); ++i) { for (unsigned i = 0; i < _graph->GetNumberOfNodes(); ++i)
{
const NodeID start = i; const NodeID start = i;
for(_DynamicGraph::EdgeIterator currentEdge = _graph->BeginEdges(start); currentEdge < _graph->EndEdges(start); ++currentEdge) { for (_DynamicGraph::EdgeIterator currentEdge = _graph->BeginEdges(start);
currentEdge < _graph->EndEdges(start);
++currentEdge)
{
_DynamicGraph::EdgeData &data = _graph->GetEdgeData(currentEdge); _DynamicGraph::EdgeData &data = _graph->GetEdgeData(currentEdge);
const NodeID target = _graph->GetTarget(currentEdge); const NodeID target = _graph->GetTarget(currentEdge);
if(UINT_MAX == newNodeIDFromOldNodeIDMap[i] ){ if (UINT_MAX == newNodeIDFromOldNodeIDMap[i])
{
// Save edges of this node w/o renumbering. // Save edges of this node w/o renumbering.
tempStorage.WriteToSlot(edge_storage_slot, (char*)&start, sizeof(NodeID)); tempStorage.WriteToSlot(
tempStorage.WriteToSlot(edge_storage_slot, (char*)&target, sizeof(NodeID)); edge_storage_slot, (char *)&start, sizeof(NodeID));
tempStorage.WriteToSlot(edge_storage_slot, (char*)&data, sizeof(_DynamicGraph::EdgeData)); tempStorage.WriteToSlot(
edge_storage_slot, (char *)&target, sizeof(NodeID));
tempStorage.WriteToSlot(
edge_storage_slot, (char *)&data, sizeof(_DynamicGraph::EdgeData));
++temp_edge_counter; ++temp_edge_counter;
} else { }
else
{
// node is not yet contracted. // node is not yet contracted.
// add (renumbered) outgoing edges to new DynamicGraph. // add (renumbered) outgoing edges to new DynamicGraph.
_ContractorEdge newEdge; _ContractorEdge newEdge;
@ -303,14 +375,10 @@ public:
newEdge.target = newNodeIDFromOldNodeIDMap[target]; newEdge.target = newNodeIDFromOldNodeIDMap[target];
newEdge.data = data; newEdge.data = data;
newEdge.data.originalViaNodeID = true; newEdge.data.originalViaNodeID = true;
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(UINT_MAX != newNodeIDFromOldNodeIDMap[start],
UINT_MAX != newNodeIDFromOldNodeIDMap[start], "new start id not resolveable");
"new start id not resolveable" BOOST_ASSERT_MSG(UINT_MAX != newNodeIDFromOldNodeIDMap[target],
); "new target id not resolveable");
BOOST_ASSERT_MSG(
UINT_MAX != newNodeIDFromOldNodeIDMap[target],
"new target id not resolveable"
);
newSetOfEdges.push_back(newEdge); newSetOfEdges.push_back(newEdge);
} }
} }
@ -335,7 +403,8 @@ public:
// INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH! // INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH!
// reinitialize heaps and ThreadData objects with appropriate size // reinitialize heaps and ThreadData objects with appropriate size
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) { for (unsigned threadNum = 0; threadNum < maxThreads; ++threadNum)
{
threadData.push_back(new _ThreadData(_graph->GetNumberOfNodes())); threadData.push_back(new _ThreadData(_graph->GetNumberOfNodes()));
} }
} }
@ -346,20 +415,24 @@ public:
// determine independent node set // determine independent node set
_ThreadData *const data = threadData[omp_get_thread_num()]; _ThreadData *const data = threadData[omp_get_thread_num()];
#pragma omp for schedule(guided) #pragma omp for schedule(guided)
for ( int i = 0; i < last; ++i ) { for (int i = 0; i < last; ++i)
{
const NodeID node = remainingNodes[i].id; const NodeID node = remainingNodes[i].id;
remainingNodes[i].isIndependent = _IsIndependent( nodePriority/*, nodeData*/, data, node ); remainingNodes[i].isIndependent =
_IsIndependent(nodePriority /*, nodeData*/, data, node);
} }
} }
_NodePartitionor functor; _NodePartitionor functor;
const std::vector < _RemainingNodeData >::const_iterator first = stable_partition( remainingNodes.begin(), remainingNodes.end(), functor ); const std::vector<_RemainingNodeData>::const_iterator first =
stable_partition(remainingNodes.begin(), remainingNodes.end(), functor);
const int firstIndependent = first - remainingNodes.begin(); const int firstIndependent = first - remainingNodes.begin();
// contract independent nodes // contract independent nodes
#pragma omp parallel #pragma omp parallel
{ {
_ThreadData *data = threadData[omp_get_thread_num()]; _ThreadData *data = threadData[omp_get_thread_num()];
#pragma omp for schedule(guided) nowait #pragma omp for schedule(guided) nowait
for ( int position = firstIndependent ; position < last; ++position ) { for (int position = firstIndependent; position < last; ++position)
{
NodeID x = remainingNodes[position].id; NodeID x = remainingNodes[position].id;
_Contract<false>(data, x); _Contract<false>(data, x);
// nodePriority[x] = -1; // nodePriority[x] = -1;
@ -371,7 +444,8 @@ public:
{ {
_ThreadData *data = threadData[omp_get_thread_num()]; _ThreadData *data = threadData[omp_get_thread_num()];
#pragma omp for schedule(guided) nowait #pragma omp for schedule(guided) nowait
for ( int position = firstIndependent ; position < last; ++position ) { for (int position = firstIndependent; position < last; ++position)
{
NodeID x = remainingNodes[position].id; NodeID x = remainingNodes[position].id;
_DeleteIncomingEdges(data, x); _DeleteIncomingEdges(data, x);
} }
@ -386,11 +460,12 @@ public:
if(currentEdgeData.shortcut && if(currentEdgeData.shortcut &&
edge.data.forward == currentEdgeData.forward && edge.data.forward == currentEdgeData.forward &&
edge.data.backward == currentEdgeData.backward && edge.data.backward == currentEdgeData.backward &&
edge.data.distance < currentEdgeData.distance edge.data.distance < currentEdgeData.distance)
) { {
// found a duplicate edge with smaller weight, update it. // found a duplicate edge with smaller weight, update it.
currentEdgeData = edge.data; currentEdgeData = edge.data;
// currentEdgeData.distance = std::min(currentEdgeData.distance, edge.data.distance); // currentEdgeData.distance = std::min(currentEdgeData.distance,
// edge.data.distance);
continue; continue;
} }
} }
@ -403,7 +478,8 @@ public:
{ {
_ThreadData *data = threadData[omp_get_thread_num()]; _ThreadData *data = threadData[omp_get_thread_num()];
#pragma omp for schedule(guided) nowait #pragma omp for schedule(guided) nowait
for ( int position = firstIndependent ; position < last; ++position ) { for (int position = firstIndependent; position < last; ++position)
{
NodeID x = remainingNodes[position].id; NodeID x = remainingNodes[position].id;
_UpdateNeighbours(nodePriority, nodeData, data, x); _UpdateNeighbours(nodePriority, nodeData, data, x);
} }
@ -418,7 +494,8 @@ public:
// unsigned quaddegree = 0; // unsigned quaddegree = 0;
// //
// for(unsigned i = 0; i < remainingNodes.size(); ++i) { // for(unsigned i = 0; i < remainingNodes.size(); ++i) {
// unsigned degree = _graph->EndEdges(remainingNodes[i].first) - _graph->BeginEdges(remainingNodes[i].first); // unsigned degree = _graph->EndEdges(remainingNodes[i].first) -
// _graph->BeginEdges(remainingNodes[i].first);
// if(degree > maxdegree) // if(degree > maxdegree)
// maxdegree = degree; // maxdegree = degree;
// if(degree < mindegree) // if(degree < mindegree)
@ -431,7 +508,9 @@ public:
// avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); // avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
// quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); // quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
// //
// SimpleLogger().Write() << "rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree; // SimpleLogger().Write() << "rest: " << remainingNodes.size() << ", max: "
// << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ",
// quad: " << quaddegree;
p.printStatus(numberOfContractedNodes); p.printStatus(numberOfContractedNodes);
} }
@ -441,47 +520,48 @@ public:
threadData.clear(); threadData.clear();
} }
template< class Edge > template <class Edge> inline void GetEdges(DeallocatingVector<Edge> &edges)
inline void GetEdges( DeallocatingVector< Edge >& edges ) { {
Percent p(_graph->GetNumberOfNodes()); Percent p(_graph->GetNumberOfNodes());
SimpleLogger().Write() << "Getting edges of minimized graph"; SimpleLogger().Write() << "Getting edges of minimized graph";
NodeID numberOfNodes = _graph->GetNumberOfNodes(); NodeID numberOfNodes = _graph->GetNumberOfNodes();
if(_graph->GetNumberOfNodes()) { if (_graph->GetNumberOfNodes())
{
Edge newEdge; Edge newEdge;
for ( NodeID node = 0; node < numberOfNodes; ++node ) { for (NodeID node = 0; node < numberOfNodes; ++node)
{
p.printStatus(node); p.printStatus(node);
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; ++edge ) { for (_DynamicGraph::EdgeIterator edge = _graph->BeginEdges(node),
endEdges = _graph->EndEdges(node);
edge < endEdges;
++edge)
{
const NodeID target = _graph->GetTarget(edge); const NodeID target = _graph->GetTarget(edge);
const _DynamicGraph::EdgeData &data = _graph->GetEdgeData(edge); const _DynamicGraph::EdgeData &data = _graph->GetEdgeData(edge);
if( !oldNodeIDFromNewNodeIDMap.empty() ) { if (!oldNodeIDFromNewNodeIDMap.empty())
{
newEdge.source = oldNodeIDFromNewNodeIDMap[node]; newEdge.source = oldNodeIDFromNewNodeIDMap[node];
newEdge.target = oldNodeIDFromNewNodeIDMap[target]; newEdge.target = oldNodeIDFromNewNodeIDMap[target];
} else { }
else
{
newEdge.source = node; newEdge.source = node;
newEdge.target = target; newEdge.target = target;
} }
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(UINT_MAX != newEdge.source, "Source id invalid");
UINT_MAX != newEdge.source, BOOST_ASSERT_MSG(UINT_MAX != newEdge.target, "Target id invalid");
"Source id invalid"
);
BOOST_ASSERT_MSG(
UINT_MAX != newEdge.target,
"Target id invalid"
);
newEdge.data.distance = data.distance; newEdge.data.distance = data.distance;
newEdge.data.shortcut = data.shortcut; newEdge.data.shortcut = data.shortcut;
if( if (!data.originalViaNodeID && !oldNodeIDFromNewNodeIDMap.empty())
!data.originalViaNodeID && {
!oldNodeIDFromNewNodeIDMap.empty()
) {
newEdge.data.id = oldNodeIDFromNewNodeIDMap[data.id]; newEdge.data.id = oldNodeIDFromNewNodeIDMap[data.id];
} else { }
else
{
newEdge.data.id = data.id; newEdge.data.id = data.id;
} }
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(newEdge.data.id != INT_MAX, // 2^31
newEdge.data.id != INT_MAX, //2^31 "edge id invalid");
"edge id invalid"
);
newEdge.data.forward = data.forward; newEdge.data.forward = data.forward;
newEdge.data.backward = data.backward; newEdge.data.backward = data.backward;
edges.push_back(newEdge); edges.push_back(newEdge);
@ -499,10 +579,12 @@ public:
_DynamicGraph::EdgeData data; _DynamicGraph::EdgeData data;
Edge restored_edge; Edge restored_edge;
for(unsigned i = 0; i < temp_edge_counter; ++i) { for (unsigned i = 0; i < temp_edge_counter; ++i)
{
tempStorage.ReadFromSlot(edge_storage_slot, (char *)&start, sizeof(NodeID)); tempStorage.ReadFromSlot(edge_storage_slot, (char *)&start, sizeof(NodeID));
tempStorage.ReadFromSlot(edge_storage_slot, (char *)&target, sizeof(NodeID)); tempStorage.ReadFromSlot(edge_storage_slot, (char *)&target, sizeof(NodeID));
tempStorage.ReadFromSlot(edge_storage_slot, (char*)&data, sizeof(_DynamicGraph::EdgeData)); tempStorage.ReadFromSlot(
edge_storage_slot, (char *)&data, sizeof(_DynamicGraph::EdgeData));
restored_edge.source = start; restored_edge.source = start;
restored_edge.target = target; restored_edge.target = target;
restored_edge.data.distance = data.distance; restored_edge.data.distance = data.distance;
@ -516,13 +598,19 @@ public:
} }
private: private:
inline void _Dijkstra( const int maxDistance, const unsigned numTargets, const int maxNodes, _ThreadData* const data, const NodeID middleNode ){ inline void _Dijkstra(const int maxDistance,
const unsigned numTargets,
const int maxNodes,
_ThreadData *const data,
const NodeID middleNode)
{
_Heap &heap = data->heap; _Heap &heap = data->heap;
int nodes = 0; int nodes = 0;
unsigned targetsFound = 0; unsigned targetsFound = 0;
while ( heap.Size() > 0 ) { while (heap.Size() > 0)
{
const NodeID node = heap.DeleteMin(); const NodeID node = heap.DeleteMin();
const int distance = heap.GetKey(node); const int distance = heap.GetKey(node);
const short currentHop = heap.GetData(node).hop + 1; const short currentHop = heap.GetData(node).hop + 1;
@ -533,31 +621,41 @@ private:
if (distance > maxDistance) if (distance > maxDistance)
return; return;
if ( heap.GetData( node ).target ) { if (heap.GetData(node).target)
{
++targetsFound; ++targetsFound;
if ( targetsFound >= numTargets ) { if (targetsFound >= numTargets)
{
return; return;
} }
} }
// iterate over all edges of node // iterate over all edges of node
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) { for (_DynamicGraph::EdgeIterator edge = _graph->BeginEdges(node),
endEdges = _graph->EndEdges(node);
edge != endEdges;
++edge)
{
const ContractorEdgeData &data = _graph->GetEdgeData(edge); const ContractorEdgeData &data = _graph->GetEdgeData(edge);
if ( !data.forward ){ if (!data.forward)
{
continue; continue;
} }
const NodeID to = _graph->GetTarget(edge); const NodeID to = _graph->GetTarget(edge);
if(middleNode == to) { if (middleNode == to)
{
continue; continue;
} }
const int toDistance = distance + data.distance; const int toDistance = distance + data.distance;
// New Node discovered -> Add to Heap + Node Info Storage // New Node discovered -> Add to Heap + Node Info Storage
if ( !heap.WasInserted( to ) ) { if (!heap.WasInserted(to))
{
heap.Insert(to, toDistance, _HeapData(currentHop, false)); heap.Insert(to, toDistance, _HeapData(currentHop, false));
} }
// Found a shorter Path -> Update distance // Found a shorter Path -> Update distance
else if ( toDistance < heap.GetKey( to ) ) { else if (toDistance < heap.GetKey(to))
{
heap.DecreaseKey(to, toDistance); heap.DecreaseKey(to, toDistance);
heap.GetData(to).hop = currentHop; heap.GetData(to).hop = currentHop;
} }
@ -565,7 +663,9 @@ private:
} }
} }
inline float _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, const NodeID node){ inline float
_Evaluate(_ThreadData *const data, _PriorityData *const nodeData, const NodeID node)
{
_ContractionInformation stats; _ContractionInformation stats;
// perform simulated contraction // perform simulated contraction
@ -576,21 +676,29 @@ private:
if (0 == (stats.edgesDeleted * stats.originalEdgesDeleted)) if (0 == (stats.edgesDeleted * stats.originalEdgesDeleted))
result = 1 * nodeData->depth; result = 1 * nodeData->depth;
else else
result = 2 * ((( float ) stats.edgesAdded ) / stats.edgesDeleted ) + 4 * ((( float ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + 1 * nodeData->depth; result = 2 * (((float)stats.edgesAdded) / stats.edgesDeleted) +
4 * (((float)stats.originalEdgesAdded) / stats.originalEdgesDeleted) +
1 * nodeData->depth;
assert(result >= 0); assert(result >= 0);
return result; return result;
} }
template <bool Simulate> template <bool Simulate>
inline bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) { inline bool _Contract(_ThreadData *data, NodeID node, _ContractionInformation *stats = NULL)
{
_Heap &heap = data->heap; _Heap &heap = data->heap;
int insertedEdgesSize = data->insertedEdges.size(); int insertedEdgesSize = data->insertedEdges.size();
std::vector<_ContractorEdge> &insertedEdges = data->insertedEdges; std::vector<_ContractorEdge> &insertedEdges = data->insertedEdges;
for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) { for (_DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges(node),
endInEdges = _graph->EndEdges(node);
inEdge != endInEdges;
++inEdge)
{
const ContractorEdgeData &inData = _graph->GetEdgeData(inEdge); const ContractorEdgeData &inData = _graph->GetEdgeData(inEdge);
const NodeID source = _graph->GetTarget(inEdge); const NodeID source = _graph->GetTarget(inEdge);
if ( Simulate ) { if (Simulate)
{
assert(stats != NULL); assert(stats != NULL);
++stats->edgesDeleted; ++stats->edgesDeleted;
stats->originalEdgesDeleted += inData.originalEdges; stats->originalEdgesDeleted += inData.originalEdges;
@ -603,43 +711,69 @@ private:
int maxDistance = 0; int maxDistance = 0;
unsigned numTargets = 0; unsigned numTargets = 0;
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) { for (_DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges(node),
endOutEdges = _graph->EndEdges(node);
outEdge != endOutEdges;
++outEdge)
{
const ContractorEdgeData &outData = _graph->GetEdgeData(outEdge); const ContractorEdgeData &outData = _graph->GetEdgeData(outEdge);
if ( !outData.forward ) { if (!outData.forward)
{
continue; continue;
} }
const NodeID target = _graph->GetTarget(outEdge); const NodeID target = _graph->GetTarget(outEdge);
const int pathDistance = inData.distance + outData.distance; const int pathDistance = inData.distance + outData.distance;
maxDistance = std::max(maxDistance, pathDistance); maxDistance = std::max(maxDistance, pathDistance);
if ( !heap.WasInserted( target ) ) { if (!heap.WasInserted(target))
{
heap.Insert(target, INT_MAX, _HeapData(0, true)); heap.Insert(target, INT_MAX, _HeapData(0, true));
++numTargets; ++numTargets;
} }
} }
if( Simulate ) { if (Simulate)
{
_Dijkstra(maxDistance, numTargets, 1000, data, node); _Dijkstra(maxDistance, numTargets, 1000, data, node);
} else { }
else
{
_Dijkstra(maxDistance, numTargets, 2000, data, node); _Dijkstra(maxDistance, numTargets, 2000, data, node);
} }
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) { for (_DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges(node),
endOutEdges = _graph->EndEdges(node);
outEdge != endOutEdges;
++outEdge)
{
const ContractorEdgeData &outData = _graph->GetEdgeData(outEdge); const ContractorEdgeData &outData = _graph->GetEdgeData(outEdge);
if ( !outData.forward ) { if (!outData.forward)
{
continue; continue;
} }
const NodeID target = _graph->GetTarget(outEdge); const NodeID target = _graph->GetTarget(outEdge);
const int pathDistance = inData.distance + outData.distance; const int pathDistance = inData.distance + outData.distance;
const int distance = heap.GetKey(target); const int distance = heap.GetKey(target);
if ( pathDistance < distance ) { if (pathDistance < distance)
if ( Simulate ) { {
if (Simulate)
{
assert(stats != NULL); assert(stats != NULL);
stats->edgesAdded += 2; stats->edgesAdded += 2;
stats->originalEdgesAdded += 2* ( outData.originalEdges + inData.originalEdges ); stats->originalEdgesAdded +=
} else { 2 * (outData.originalEdges + inData.originalEdges);
}
else
{
_ContractorEdge newEdge; _ContractorEdge newEdge;
newEdge.source = source; newEdge.source = source;
newEdge.target = target; newEdge.target = target;
newEdge.data = ContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node/*, 0, inData.turnInstruction*/, true, true, false);; newEdge.data =
ContractorEdgeData(pathDistance,
outData.originalEdges + inData.originalEdges,
node /*, 0, inData.turnInstruction*/,
true,
true,
false);
;
insertedEdges.push_back(newEdge); insertedEdges.push_back(newEdge);
std::swap(newEdge.source, newEdge.target); std::swap(newEdge.source, newEdge.target);
newEdge.data.forward = false; newEdge.data.forward = false;
@ -649,10 +783,13 @@ private:
} }
} }
} }
if ( !Simulate ) { if (!Simulate)
for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; ++i ) { {
for (int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; ++i)
{
bool found = false; bool found = false;
for ( int other = i + 1 ; other < iend ; ++other ) { for (int other = i + 1; other < iend; ++other)
{
if (insertedEdges[other].source != insertedEdges[i].source) if (insertedEdges[other].source != insertedEdges[i].source)
continue; continue;
if (insertedEdges[other].target != insertedEdges[i].target) if (insertedEdges[other].target != insertedEdges[i].target)
@ -675,12 +812,15 @@ private:
return true; return true;
} }
inline void _DeleteIncomingEdges( _ThreadData* data, const NodeID node ) { inline void _DeleteIncomingEdges(_ThreadData *data, const NodeID node)
{
std::vector<NodeID> &neighbours = data->neighbours; std::vector<NodeID> &neighbours = data->neighbours;
neighbours.clear(); neighbours.clear();
// find all neighbours // find all neighbours
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) { for (_DynamicGraph::EdgeIterator e = _graph->BeginEdges(node); e < _graph->EndEdges(node);
++e)
{
const NodeID u = _graph->GetTarget(e); const NodeID u = _graph->GetTarget(e);
if (u != node) if (u != node)
neighbours.push_back(u); neighbours.push_back(u);
@ -689,17 +829,26 @@ private:
std::sort(neighbours.begin(), neighbours.end()); std::sort(neighbours.begin(), neighbours.end());
neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin()); neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin());
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) { for (int i = 0, e = (int)neighbours.size(); i < e; ++i)
{
_graph->DeleteEdgesTo(neighbours[i], node); _graph->DeleteEdgesTo(neighbours[i], node);
} }
} }
inline bool _UpdateNeighbours( std::vector< float > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, const NodeID node) { inline bool _UpdateNeighbours(std::vector<float> &priorities,
std::vector<_PriorityData> &nodeData,
_ThreadData *const data,
const NodeID node)
{
std::vector<NodeID> &neighbours = data->neighbours; std::vector<NodeID> &neighbours = data->neighbours;
neighbours.clear(); neighbours.clear();
// find all neighbours // find all neighbours
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ) ; e < endEdges ; ++e ) { for (_DynamicGraph::EdgeIterator e = _graph->BeginEdges(node),
endEdges = _graph->EndEdges(node);
e < endEdges;
++e)
{
const NodeID u = _graph->GetTarget(e); const NodeID u = _graph->GetTarget(e);
if (u == node) if (u == node)
continue; continue;
@ -716,13 +865,19 @@ private:
return true; return true;
} }
inline bool _IsIndependent( const std::vector< float >& priorities/*, const std::vector< _PriorityData >& nodeData*/, _ThreadData* const data, NodeID node ) const { inline bool _IsIndependent(
const std::vector<float> &priorities /*, const std::vector< _PriorityData >& nodeData*/,
_ThreadData *const data,
NodeID node) const
{
const double priority = priorities[node]; const double priority = priorities[node];
std::vector<NodeID> &neighbours = data->neighbours; std::vector<NodeID> &neighbours = data->neighbours;
neighbours.clear(); neighbours.clear();
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) { for (_DynamicGraph::EdgeIterator e = _graph->BeginEdges(node); e < _graph->EndEdges(node);
++e)
{
const NodeID target = _graph->GetTarget(e); const NodeID target = _graph->GetTarget(e);
if (node == target) if (node == target)
continue; continue;
@ -732,7 +887,9 @@ private:
if (priority > targetPriority) if (priority > targetPriority)
return false; return false;
// tie breaking // tie breaking
if ( std::abs(priority - targetPriority) < std::numeric_limits<double>::epsilon() && bias(node, target) ) { if (std::abs(priority - targetPriority) < std::numeric_limits<double>::epsilon() &&
bias(node, target))
{
return false; return false;
} }
// TODO: C++11 copy_if with lambda // TODO: C++11 copy_if with lambda
@ -743,13 +900,14 @@ private:
neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin()); neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin());
// examine all neighbours that are at most 2 hops away // examine all neighbours that are at most 2 hops away
for(const NodeID u : neighbours) { for(const NodeID u : neighbours)
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) { {
for (_DynamicGraph::EdgeIterator e = _graph->BeginEdges(u); e < _graph->EndEdges(u);
++e)
{
const NodeID target = _graph->GetTarget(e); const NodeID target = _graph->GetTarget(e);
if (node == target) if (node == target)
{
continue; continue;
}
const double targetPriority = priorities[target]; const double targetPriority = priorities[target];
assert( targetPriority >= 0 ); assert( targetPriority >= 0 );
@ -769,11 +927,13 @@ private:
/** /**
* This bias function takes up 22 assembly instructions in total on X86 * This bias function takes up 22 assembly instructions in total on X86
*/ */
inline bool bias(const NodeID a, const NodeID b) const { inline bool bias(const NodeID a, const NodeID b) const
{
unsigned short hasha = fastHash(a); unsigned short hasha = fastHash(a);
unsigned short hashb = fastHash(b); unsigned short hashb = fastHash(b);
//The compiler optimizes that to conditional register flags but without branching statements! // The compiler optimizes that to conditional register flags but without branching
// statements!
if (hasha != hashb) if (hasha != hashb)
return hasha < hashb; return hasha < hashb;
return a < b; return a < b;

View File

@ -25,7 +25,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "EdgeBasedGraphFactory.h" #include "EdgeBasedGraphFactory.h"
#include "../Util/ComputeAngle.h" #include "../Util/ComputeAngle.h"
#include "../DataStructures/BFSComponentExplorer.h" #include "../DataStructures/BFSComponentExplorer.h"
@ -44,42 +43,30 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
std::vector<NodeID> &barrier_node_list, std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list, std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> &m_node_info_list, std::vector<NodeInfo> &m_node_info_list,
SpeedProfileProperties & speed_profile SpeedProfileProperties &speed_profile)
) : speed_profile(speed_profile), : speed_profile(speed_profile),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()), m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(m_node_info_list), m_node_info_list(m_node_info_list), m_node_based_graph(node_based_graph),
m_node_based_graph(node_based_graph), m_restriction_map(std::move(restriction_map)), max_id(0)
m_restriction_map(std::move(restriction_map)),
max_id(0)
{ {
// insert into unordered sets for fast lookup // insert into unordered sets for fast lookup
m_barrier_nodes.insert( m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end());
barrier_node_list.begin(),
barrier_node_list.end()
);
m_traffic_lights.insert(
traffic_light_node_list.begin(),
traffic_light_node_list.end()
);
m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end());
} }
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &output_edge_list)
void EdgeBasedGraphFactory::GetEdgeBasedEdges( {
DeallocatingVector< EdgeBasedEdge >& output_edge_list BOOST_ASSERT_MSG(0 == output_edge_list.size(), "Vector is not empty");
) {
BOOST_ASSERT_MSG(
0 == output_edge_list.size(),
"Vector is not empty"
);
m_edge_based_edge_list.swap(output_edge_list); m_edge_based_edge_list.swap(output_edge_list);
} }
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) { void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
{
#ifndef NDEBUG #ifndef NDEBUG
BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){ BOOST_FOREACH (const EdgeBasedNode &node, m_edge_based_node_list)
{
BOOST_ASSERT(m_node_info_list.at(node.u).lat != INT_MAX); BOOST_ASSERT(m_node_info_list.at(node.u).lat != INT_MAX);
BOOST_ASSERT(m_node_info_list.at(node.u).lon != INT_MAX); BOOST_ASSERT(m_node_info_list.at(node.u).lon != INT_MAX);
@ -90,13 +77,11 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & node
nodes.swap(m_edge_based_node_list); nodes.swap(m_edge_based_node_list);
} }
void EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeIterator u,
void EdgeBasedGraphFactory::InsertEdgeBasedNode(
NodeIterator u,
NodeIterator v, NodeIterator v,
EdgeIterator e1, EdgeIterator e1,
bool belongs_to_tiny_cc bool belongs_to_tiny_cc)
) { {
// merge edges together into one EdgeBasedNode // merge edges together into one EdgeBasedNode
BOOST_ASSERT(u != SPECIAL_NODEID); BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(v != SPECIAL_NODEID); BOOST_ASSERT(v != SPECIAL_NODEID);
@ -115,7 +100,8 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
const EdgeID e2 = m_node_based_graph->FindEdge(v, u); const EdgeID e2 = m_node_based_graph->FindEdge(v, u);
#ifndef NDEBUG #ifndef NDEBUG
if ( e2 == m_node_based_graph->EndEdges(v) ) { if (e2 == m_node_based_graph->EndEdges(v))
{
SimpleLogger().Write(logWARNING) << "Did not find edge (" << v << "," << u << ")"; SimpleLogger().Write(logWARNING) << "Did not find edge (" << v << "," << u << ")";
} }
#endif #endif
@ -123,21 +109,24 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
BOOST_ASSERT(e2 < m_node_based_graph->EndEdges(v)); BOOST_ASSERT(e2 < m_node_based_graph->EndEdges(v));
const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(e2); const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(e2);
if( if (forward_data.edgeBasedNodeID == SPECIAL_NODEID &&
forward_data.edgeBasedNodeID == SPECIAL_NODEID && reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
reverse_data.edgeBasedNodeID == SPECIAL_NODEID {
) {
return; return;
} }
BOOST_ASSERT( m_geometry_compressor.HasEntryForID(e1) == m_geometry_compressor.HasEntryForID(e2) ); BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e1) ==
if( m_geometry_compressor.HasEntryForID(e1) ) { m_geometry_compressor.HasEntryForID(e2));
if (m_geometry_compressor.HasEntryForID(e1))
{
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e2)); BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e2));
// reconstruct geometry and put in each individual edge with its offset // reconstruct geometry and put in each individual edge with its offset
const std::vector<GeometryCompressor::CompressedNode> & forward_geometry = m_geometry_compressor.GetBucketReference(e1); const std::vector<GeometryCompressor::CompressedNode> &forward_geometry =
const std::vector<GeometryCompressor::CompressedNode> & reverse_geometry = m_geometry_compressor.GetBucketReference(e2); m_geometry_compressor.GetBucketReference(e1);
const std::vector<GeometryCompressor::CompressedNode> &reverse_geometry =
m_geometry_compressor.GetBucketReference(e2);
BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size()); BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size());
BOOST_ASSERT(0 != forward_geometry.size()); BOOST_ASSERT(0 != forward_geometry.size());
@ -159,7 +148,8 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
} }
temp_sum = 0; temp_sum = 0;
for( unsigned i = 0; i < reverse_geometry.size(); ++i ) { for (unsigned i = 0; i < reverse_geometry.size(); ++i)
{
temp_sum += reverse_geometry[reverse_geometry.size() - 1 - i].second; temp_sum += reverse_geometry[reverse_geometry.size() - 1 - i].second;
reverse_dist_prefix_sum[i] = reverse_data.distance - temp_sum; reverse_dist_prefix_sum[i] = reverse_data.distance - temp_sum;
BOOST_ASSERT(reverse_data.distance >= temp_sum); BOOST_ASSERT(reverse_data.distance >= temp_sum);
@ -181,15 +171,16 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
} }
// traverse arrays from start and end respectively // traverse arrays from start and end respectively
for( unsigned i = 0; i < geometry_size; ++i ) { for (unsigned i = 0; i < geometry_size; ++i)
BOOST_ASSERT( current_edge_start_coordinate_id == reverse_geometry[geometry_size-1-i].first ); {
BOOST_ASSERT(current_edge_start_coordinate_id ==
reverse_geometry[geometry_size - 1 - i].first);
const NodeID current_edge_target_coordinate_id = forward_geometry[i].first; const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_start_coordinate_id); BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_start_coordinate_id);
// build edges // build edges
m_edge_based_node_list.emplace_back( m_edge_based_node_list.emplace_back(
EdgeBasedNode( EdgeBasedNode(forward_data.edgeBasedNodeID,
forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID,
current_edge_start_coordinate_id, current_edge_start_coordinate_id,
current_edge_target_coordinate_id, current_edge_target_coordinate_id,
@ -200,51 +191,46 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
reverse_dist_prefix_sum[i], reverse_dist_prefix_sum[i],
m_geometry_compressor.GetPositionForID(e1), m_geometry_compressor.GetPositionForID(e1),
i, i,
belongs_to_tiny_cc belongs_to_tiny_cc));
)
);
current_edge_start_coordinate_id = current_edge_target_coordinate_id; current_edge_start_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed()); BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
BOOST_ASSERT( BOOST_ASSERT(u != m_edge_based_node_list.back().u ||
u != m_edge_based_node_list.back().u || v != m_edge_based_node_list.back().v);
v != m_edge_based_node_list.back().v
);
BOOST_ASSERT( BOOST_ASSERT(u != m_edge_based_node_list.back().v ||
u != m_edge_based_node_list.back().v || v != m_edge_based_node_list.back().u);
v != m_edge_based_node_list.back().u
);
} }
BOOST_ASSERT(current_edge_start_coordinate_id == v); BOOST_ASSERT(current_edge_start_coordinate_id == v);
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed()); BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
}
} else { else
{
BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(e2)); BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(e2));
if( forward_data.edgeBasedNodeID != SPECIAL_NODEID ) { if (forward_data.edgeBasedNodeID != SPECIAL_NODEID)
{
BOOST_ASSERT(forward_data.forward); BOOST_ASSERT(forward_data.forward);
} }
if( reverse_data.edgeBasedNodeID != SPECIAL_NODEID ) { if (reverse_data.edgeBasedNodeID != SPECIAL_NODEID)
{
BOOST_ASSERT(reverse_data.forward); BOOST_ASSERT(reverse_data.forward);
} }
if( forward_data.edgeBasedNodeID == SPECIAL_NODEID ) { if (forward_data.edgeBasedNodeID == SPECIAL_NODEID)
{
BOOST_ASSERT(!forward_data.forward); BOOST_ASSERT(!forward_data.forward);
} }
if( reverse_data.edgeBasedNodeID == SPECIAL_NODEID ) { if (reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
{
BOOST_ASSERT(!reverse_data.forward); BOOST_ASSERT(!reverse_data.forward);
} }
BOOST_ASSERT( BOOST_ASSERT(forward_data.edgeBasedNodeID != SPECIAL_NODEID ||
forward_data.edgeBasedNodeID != SPECIAL_NODEID || reverse_data.edgeBasedNodeID != SPECIAL_NODEID);
reverse_data.edgeBasedNodeID != SPECIAL_NODEID
);
m_edge_based_node_list.emplace_back( m_edge_based_node_list.emplace_back(EdgeBasedNode(forward_data.edgeBasedNodeID,
EdgeBasedNode(
forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID,
u, u,
v, v,
@ -255,30 +241,23 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
0, 0,
SPECIAL_EDGEID, SPECIAL_EDGEID,
0, 0,
belongs_to_tiny_cc belongs_to_tiny_cc));
)
);
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed()); BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
} }
} }
void EdgeBasedGraphFactory::FlushVectorToStream( void EdgeBasedGraphFactory::FlushVectorToStream(
std::ofstream & edge_data_file, std::ofstream &edge_data_file, std::vector<OriginalEdgeData> &original_edge_data_vector) const
std::vector<OriginalEdgeData> & original_edge_data_vector {
) const { edge_data_file.write((char *)&(original_edge_data_vector[0]),
edge_data_file.write( original_edge_data_vector.size() * sizeof(OriginalEdgeData));
(char*)&(original_edge_data_vector[0]),
original_edge_data_vector.size()*sizeof(OriginalEdgeData)
);
original_edge_data_vector.clear(); original_edge_data_vector.clear();
} }
void EdgeBasedGraphFactory::Run( void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
const std::string & original_edge_data_filename,
const std::string &geometry_filename, const std::string &geometry_filename,
lua_State *lua_state lua_State *lua_state)
) { {
CompressGeometry(); CompressGeometry();
@ -289,7 +268,6 @@ void EdgeBasedGraphFactory::Run(
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state); GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
m_geometry_compressor.SerializeInternalVector(geometry_filename); m_geometry_compressor.SerializeInternalVector(geometry_filename);
} }
void EdgeBasedGraphFactory::CompressGeometry() void EdgeBasedGraphFactory::CompressGeometry()
@ -302,20 +280,24 @@ void EdgeBasedGraphFactory::CompressGeometry()
Percent p(original_number_of_nodes); Percent p(original_number_of_nodes);
unsigned removed_node_count = 0; unsigned removed_node_count = 0;
for( NodeID v = 0; v < original_number_of_nodes; ++v ) { for (NodeID v = 0; v < original_number_of_nodes; ++v)
{
p.printStatus(v); p.printStatus(v);
// only contract degree 2 vertices // only contract degree 2 vertices
if( 2 != m_node_based_graph->GetOutDegree(v) ) { if (2 != m_node_based_graph->GetOutDegree(v))
{
continue; continue;
} }
// don't contract barrier node // don't contract barrier node
if( m_barrier_nodes.end() != m_barrier_nodes.find(v) ) { if (m_barrier_nodes.end() != m_barrier_nodes.find(v))
{
continue; continue;
} }
const bool reverse_edge_order = !(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(v)).forward); const bool reverse_edge_order =
!(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(v)).forward);
const EdgeIterator forward_e2 = m_node_based_graph->BeginEdges(v) + reverse_edge_order; const EdgeIterator forward_e2 = m_node_based_graph->BeginEdges(v) + reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2); BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
const EdgeIterator reverse_e2 = m_node_based_graph->BeginEdges(v) + 1 - reverse_edge_order; const EdgeIterator reverse_e2 = m_node_based_graph->BeginEdges(v) + 1 - reverse_edge_order;
@ -342,17 +324,15 @@ void EdgeBasedGraphFactory::CompressGeometry()
const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1); const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1); const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1);
if( if ((m_node_based_graph->FindEdge(u, w) != m_node_based_graph->EndEdges(u)) ||
( m_node_based_graph->FindEdge(u, w) != m_node_based_graph->EndEdges(u) ) || (m_node_based_graph->FindEdge(w, u) != m_node_based_graph->EndEdges(w)))
( m_node_based_graph->FindEdge(w, u) != m_node_based_graph->EndEdges(w) ) {
) {
continue; continue;
} }
if ( // TODO: rename to IsCompatibleTo if ( // TODO: rename to IsCompatibleTo
fwd_edge_data1.IsEqualTo(fwd_edge_data2) && fwd_edge_data1.IsEqualTo(fwd_edge_data2) && rev_edge_data1.IsEqualTo(rev_edge_data2))
rev_edge_data1.IsEqualTo(rev_edge_data2) {
) {
// Get distances before graph is modified // Get distances before graph is modified
const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance; const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance;
const int forward_weight2 = m_node_based_graph->GetEdgeData(forward_e2).distance; const int forward_weight2 = m_node_based_graph->GetEdgeData(forward_e2).distance;
@ -366,15 +346,18 @@ void EdgeBasedGraphFactory::CompressGeometry()
BOOST_ASSERT(0 != reverse_weight1); BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != forward_weight2); BOOST_ASSERT(0 != forward_weight2);
const bool add_traffic_signal_penalty = (m_traffic_lights.find(v) != m_traffic_lights.end()); const bool add_traffic_signal_penalty =
(m_traffic_lights.find(v) != m_traffic_lights.end());
// add weight of e2's to e1 // add weight of e2's to e1
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance; m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance; m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
if (add_traffic_signal_penalty) if (add_traffic_signal_penalty)
{ {
m_node_based_graph->GetEdgeData(forward_e1).distance += speed_profile.trafficSignalPenalty; m_node_based_graph->GetEdgeData(forward_e1).distance +=
m_node_based_graph->GetEdgeData(reverse_e1).distance += speed_profile.trafficSignalPenalty; speed_profile.trafficSignalPenalty;
m_node_based_graph->GetEdgeData(reverse_e1).distance +=
speed_profile.trafficSignalPenalty;
} }
// extend e1's to targets of e2's // extend e1's to targets of e2's
@ -398,24 +381,21 @@ void EdgeBasedGraphFactory::CompressGeometry()
forward_e2, forward_e2,
v, v,
w, w,
forward_weight1 + (add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty :0), forward_weight1 +
forward_weight2 (add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty : 0),
); forward_weight2);
m_geometry_compressor.CompressEdge( m_geometry_compressor.CompressEdge(
reverse_e1, reverse_e1,
reverse_e2, reverse_e2,
v, v,
u, u,
reverse_weight1, reverse_weight1,
reverse_weight2 + (add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty :0) reverse_weight2 +
); (add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty : 0));
++removed_node_count; ++removed_node_count;
BOOST_ASSERT BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
( m_node_based_graph->GetEdgeData(reverse_e1).nameID);
m_node_based_graph->GetEdgeData(forward_e1).nameID ==
m_node_based_graph->GetEdgeData(reverse_e1).nameID
);
} }
} }
SimpleLogger().Write() << "removed " << removed_node_count << " nodes"; SimpleLogger().Write() << "removed " << removed_node_count << " nodes";
@ -423,15 +403,19 @@ void EdgeBasedGraphFactory::CompressGeometry()
unsigned new_node_count = 0; unsigned new_node_count = 0;
unsigned new_edge_count = 0; unsigned new_edge_count = 0;
for( unsigned i = 0; i < m_node_based_graph->GetNumberOfNodes(); ++i ) { for (unsigned i = 0; i < m_node_based_graph->GetNumberOfNodes(); ++i)
if( m_node_based_graph->GetOutDegree(i) > 0 ) { {
if (m_node_based_graph->GetOutDegree(i) > 0)
{
++new_node_count; ++new_node_count;
new_edge_count += (m_node_based_graph->EndEdges(i) - m_node_based_graph->BeginEdges(i)); new_edge_count += (m_node_based_graph->EndEdges(i) - m_node_based_graph->BeginEdges(i));
} }
} }
SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count; SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count;
SimpleLogger().Write() << "Node compression ratio: " << new_node_count/(double)original_number_of_nodes; SimpleLogger().Write() << "Node compression ratio: "
SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count/(double)original_number_of_edges; << new_node_count / (double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: "
<< new_edge_count / (double)original_number_of_edges;
} }
/** /**
@ -441,10 +425,16 @@ void EdgeBasedGraphFactory::RenumberEdges()
{ {
// renumber edge based node IDs // renumber edge based node IDs
unsigned numbered_edges_count = 0; unsigned numbered_edges_count = 0;
for(NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes(); ++current_node) { for (NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes();
for(EdgeIterator current_edge = m_node_based_graph->BeginEdges(current_node); current_edge < m_node_based_graph->EndEdges(current_node); ++current_edge) { ++current_node)
{
for (EdgeIterator current_edge = m_node_based_graph->BeginEdges(current_node);
current_edge < m_node_based_graph->EndEdges(current_node);
++current_edge)
{
EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge); EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge);
if( !edge_data.forward ) { if (!edge_data.forward)
{
continue; continue;
} }
@ -468,36 +458,30 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
// Run a BFS on the undirected graph and identify small components // Run a BFS on the undirected graph and identify small components
BFSComponentExplorer<NodeBasedDynamicGraph> component_explorer( BFSComponentExplorer<NodeBasedDynamicGraph> component_explorer(
*m_node_based_graph, *m_node_based_graph, *m_restriction_map, m_barrier_nodes);
*m_restriction_map,
m_barrier_nodes
);
component_explorer.run(); component_explorer.run();
SimpleLogger().Write() << SimpleLogger().Write() << "identified: " << component_explorer.getNumberOfComponents()
"identified: " << component_explorer.getNumberOfComponents() << " many components"; << " many components";
SimpleLogger().Write() << "generating edge-expanded nodes"; SimpleLogger().Write() << "generating edge-expanded nodes";
Percent p(m_node_based_graph->GetNumberOfNodes()); Percent p(m_node_based_graph->GetNumberOfNodes());
// loop over all edges and generate new set of nodes // loop over all edges and generate new set of nodes
for( for (NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); {
u < end;
++u
) {
BOOST_ASSERT(u != SPECIAL_NODEID); BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes()); BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes());
p.printIncrement(); p.printIncrement();
for( for (EdgeID e1 = m_node_based_graph->BeginEdges(u),
EdgeID e1 = m_node_based_graph->BeginEdges(u),
last_edge = m_node_based_graph->EndEdges(u); last_edge = m_node_based_graph->EndEdges(u);
e1 < last_edge; e1 < last_edge;
++e1 ++e1)
) { {
const EdgeData &edge_data = m_node_based_graph->GetEdgeData(e1); const EdgeData &edge_data = m_node_based_graph->GetEdgeData(e1);
if( edge_data.edgeBasedNodeID == SPECIAL_NODEID ) { if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
{
// continue; // continue;
} }
BOOST_ASSERT(e1 != SPECIAL_EDGEID); BOOST_ASSERT(e1 != SPECIAL_EDGEID);
@ -505,7 +489,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
BOOST_ASSERT(SPECIAL_NODEID != v); BOOST_ASSERT(SPECIAL_NODEID != v);
// pick only every other edge // pick only every other edge
if( u > v ) { if (u > v)
{
continue; continue;
} }
@ -514,41 +499,34 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
// Note: edges that end on barrier nodes or on a turn restriction // Note: edges that end on barrier nodes or on a turn restriction
// may actually be in two distinct components. We choose the smallest // may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min( const unsigned size_of_component = std::min(component_explorer.getComponentSize(u),
component_explorer.getComponentSize(u), component_explorer.getComponentSize(v));
component_explorer.getComponentSize(v)
);
const bool component_is_tiny = (size_of_component < 1000); const bool component_is_tiny = (size_of_component < 1000);
InsertEdgeBasedNode(u, v, e1, component_is_tiny); InsertEdgeBasedNode(u, v, e1, component_is_tiny);
} }
} }
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size() << SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size()
" nodes in edge-expanded graph"; << " nodes in edge-expanded graph";
} }
/** /**
* Actually it also generates OriginalEdgeData and serializes them... * Actually it also generates OriginalEdgeData and serializes them...
*/ */
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string& original_edge_data_filename, lua_State* lua_state) void
EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state)
{ {
SimpleLogger().Write() << "generating edge-expanded edges"; SimpleLogger().Write() << "generating edge-expanded edges";
unsigned node_based_edge_counter = 0; unsigned node_based_edge_counter = 0;
unsigned original_edges_counter = 0; unsigned original_edges_counter = 0;
std::ofstream edge_data_file( std::ofstream edge_data_file(original_edge_data_filename.c_str(), std::ios::binary);
original_edge_data_filename.c_str(),
std::ios::binary
);
// writes a dummy value that is updated later // writes a dummy value that is updated later
edge_data_file.write( edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
(char*)&original_edges_counter,
sizeof(unsigned)
);
std::vector<OriginalEdgeData> original_edge_data_vector; std::vector<OriginalEdgeData> original_edge_data_vector;
original_edge_data_vector.reserve(1024 * 1024); original_edge_data_vector.reserve(1024 * 1024);
@ -565,30 +543,35 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string& origina
for (NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u) for (NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
{ {
for (EdgeIterator e1 = m_node_based_graph->BeginEdges(u), last_edge_u = m_node_based_graph->EndEdges(u); e1 < last_edge_u; ++e1) for (EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
last_edge_u = m_node_based_graph->EndEdges(u);
e1 < last_edge_u;
++e1)
{
if (!m_node_based_graph->GetEdgeData(e1).forward)
{ {
if( !m_node_based_graph->GetEdgeData(e1).forward ) {
continue; continue;
} }
++node_based_edge_counter; ++node_based_edge_counter;
const NodeIterator v = m_node_based_graph->GetTarget(e1); const NodeIterator v = m_node_based_graph->GetTarget(e1);
const NodeID to_node_of_only_restriction = m_restriction_map->CheckForEmanatingIsOnlyTurn(u, v); const NodeID to_node_of_only_restriction =
m_restriction_map->CheckForEmanatingIsOnlyTurn(u, v);
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
for( for (EdgeIterator e2 = m_node_based_graph->BeginEdges(v),
EdgeIterator e2 = m_node_based_graph->BeginEdges(v),
last_edge_v = m_node_based_graph->EndEdges(v); last_edge_v = m_node_based_graph->EndEdges(v);
e2 < last_edge_v; e2 < last_edge_v;
++e2 ++e2)
) { {
if (!m_node_based_graph->GetEdgeData(e2).forward) if (!m_node_based_graph->GetEdgeData(e2).forward)
{ {
continue; continue;
} }
const NodeIterator w = m_node_based_graph->GetTarget(e2); const NodeIterator w = m_node_based_graph->GetTarget(e2);
if ((to_node_of_only_restriction != SPECIAL_NODEID) && (w != to_node_of_only_restriction)) if ((to_node_of_only_restriction != SPECIAL_NODEID) &&
(w != to_node_of_only_restriction))
{ {
// We are at an only_-restriction but not at the right turn. // We are at an only_-restriction but not at the right turn.
++restricted_turns_counter; ++restricted_turns_counter;
@ -614,7 +597,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string& origina
// only add an edge if turn is not a U-turn except when it is // only add an edge if turn is not a U-turn except when it is
// at the end of a dead-end street // at the end of a dead-end street
if (m_restriction_map->CheckIfTurnIsRestricted(u, v, w) && (to_node_of_only_restriction == SPECIAL_NODEID) && (w != to_node_of_only_restriction)) if (m_restriction_map->CheckIfTurnIsRestricted(u, v, w) &&
(to_node_of_only_restriction == SPECIAL_NODEID) &&
(w != to_node_of_only_restriction))
{ {
++restricted_turns_counter; ++restricted_turns_counter;
continue; continue;
@ -649,14 +634,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string& origina
++compressed; ++compressed;
} }
original_edge_data_vector.push_back( original_edge_data_vector.push_back(OriginalEdgeData(
OriginalEdgeData(
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v), (edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data1.nameID, edge_data1.nameID,
turn_instruction, turn_instruction,
edge_is_compressed edge_is_compressed));
)
);
++original_edges_counter; ++original_edges_counter;
@ -668,16 +650,12 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string& origina
BOOST_ASSERT(SPECIAL_NODEID != edge_data1.edgeBasedNodeID); BOOST_ASSERT(SPECIAL_NODEID != edge_data1.edgeBasedNodeID);
BOOST_ASSERT(SPECIAL_NODEID != edge_data2.edgeBasedNodeID); BOOST_ASSERT(SPECIAL_NODEID != edge_data2.edgeBasedNodeID);
m_edge_based_edge_list.emplace_back( m_edge_based_edge_list.emplace_back(EdgeBasedEdge(edge_data1.edgeBasedNodeID,
EdgeBasedEdge(
edge_data1.edgeBasedNodeID,
edge_data2.edgeBasedNodeID, edge_data2.edgeBasedNodeID,
m_edge_based_edge_list.size(), m_edge_based_edge_list.size(),
distance, distance,
true, true,
false false));
)
);
} }
} }
p.printIncrement(); p.printIncrement();
@ -693,45 +671,40 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string& origina
SimpleLogger().Write() << "Edge-expanded graph ..."; SimpleLogger().Write() << "Edge-expanded graph ...";
SimpleLogger().Write() << " contains " << m_edge_based_edge_list.size() << " edges"; SimpleLogger().Write() << " contains " << m_edge_based_edge_list.size() << " edges";
SimpleLogger().Write() << " skips " << restricted_turns_counter << " turns, " SimpleLogger().Write() << " skips " << restricted_turns_counter << " turns, "
"defined by " << m_restriction_map->size() << " restrictions"; "defined by "
<< m_restriction_map->size() << " restrictions";
SimpleLogger().Write() << " skips " << skipped_uturns_counter << " U turns"; SimpleLogger().Write() << " skips " << skipped_uturns_counter << " U turns";
SimpleLogger().Write() << " skips " << skipped_barrier_turns_counter << " turns over barriers"; SimpleLogger().Write() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
} }
int EdgeBasedGraphFactory::GetTurnPenalty(const NodeID u,
int EdgeBasedGraphFactory::GetTurnPenalty(
const NodeID u,
const NodeID v, const NodeID v,
const NodeID w, const NodeID w,
lua_State *lua_state lua_State *lua_state) const
) const { {
const double angle = GetAngleBetweenThreeFixedPointCoordinates( const double angle = GetAngleBetweenThreeFixedPointCoordinates(
m_node_info_list[u], m_node_info_list[u], m_node_info_list[v], m_node_info_list[w]);
m_node_info_list[v],
m_node_info_list[w]
);
if( speed_profile.has_turn_penalty_function ) { if (speed_profile.has_turn_penalty_function)
try { {
try
{
// call lua profile to compute turn penalty // call lua profile to compute turn penalty
return luabind::call_function<int>( return luabind::call_function<int>(lua_state, "turn_function", 180. - angle);
lua_state, }
"turn_function", catch (const luabind::error &er)
180.-angle {
);
} catch (const luabind::error &er) {
SimpleLogger().Write(logWARNING) << er.what(); SimpleLogger().Write(logWARNING) << er.what();
} }
} }
return 0; return 0;
} }
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn( TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w)
const NodeID u, const
const NodeID v, {
const NodeID w if (u == w)
) const { {
if(u == w) {
return TurnInstruction::UTurn; return TurnInstruction::UTurn;
} }
@ -741,55 +714,63 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1); const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1);
const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2); const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2);
if(!data1.contraFlow && data2.contraFlow) { if (!data1.contraFlow && data2.contraFlow)
{
return TurnInstruction::EnterAgainstAllowedDirection; return TurnInstruction::EnterAgainstAllowedDirection;
} }
if(data1.contraFlow && !data2.contraFlow) { if (data1.contraFlow && !data2.contraFlow)
{
return TurnInstruction::LeaveAgainstAllowedDirection; return TurnInstruction::LeaveAgainstAllowedDirection;
} }
// roundabouts need to be handled explicitely // roundabouts need to be handled explicitely
if(data1.roundabout && data2.roundabout) { if (data1.roundabout && data2.roundabout)
{
// Is a turn possible? If yes, we stay on the roundabout! // Is a turn possible? If yes, we stay on the roundabout!
if( 1 == m_node_based_graph->GetOutDegree(v) ) { if (1 == m_node_based_graph->GetOutDegree(v))
{
// No turn possible. // No turn possible.
return TurnInstruction::NoTurn; return TurnInstruction::NoTurn;
} }
return TurnInstruction::StayOnRoundAbout; return TurnInstruction::StayOnRoundAbout;
} }
// Does turn start or end on roundabout? // Does turn start or end on roundabout?
if(data1.roundabout || data2.roundabout) { if (data1.roundabout || data2.roundabout)
{
// We are entering the roundabout // We are entering the roundabout
if( (!data1.roundabout) && data2.roundabout) { if ((!data1.roundabout) && data2.roundabout)
{
return TurnInstruction::EnterRoundAbout; return TurnInstruction::EnterRoundAbout;
} }
// We are leaving the roundabout // We are leaving the roundabout
if(data1.roundabout && (!data2.roundabout) ) { if (data1.roundabout && (!data2.roundabout))
{
return TurnInstruction::LeaveRoundAbout; return TurnInstruction::LeaveRoundAbout;
} }
} }
// If street names stay the same and if we are certain that it is not a // If street names stay the same and if we are certain that it is not a
// a segment of a roundabout, we skip it. // a segment of a roundabout, we skip it.
if( data1.nameID == data2.nameID ) { if (data1.nameID == data2.nameID)
{
// TODO: Here we should also do a small graph exploration to check for // TODO: Here we should also do a small graph exploration to check for
// more complex situations // more complex situations
if( 0 != data1.nameID ) { if (0 != data1.nameID)
{
return TurnInstruction::NoTurn; return TurnInstruction::NoTurn;
} else if (m_node_based_graph->GetOutDegree(v) <= 2) { }
else if (m_node_based_graph->GetOutDegree(v) <= 2)
{
return TurnInstruction::NoTurn; return TurnInstruction::NoTurn;
} }
} }
const double angle = GetAngleBetweenThreeFixedPointCoordinates( const double angle = GetAngleBetweenThreeFixedPointCoordinates(
m_node_info_list[u], m_node_info_list[u], m_node_info_list[v], m_node_info_list[w]);
m_node_info_list[v],
m_node_info_list[w]
);
return TurnInstructionsClass::GetTurnDirectionOfInstruction(angle); return TurnInstructionsClass::GetTurnDirectionOfInstruction(angle);
} }
unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const { unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const
{
return m_number_of_edge_based_nodes; return m_number_of_edge_based_nodes;
} }

View File

@ -58,50 +58,38 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <queue> #include <queue>
#include <vector> #include <vector>
class EdgeBasedGraphFactory : boost::noncopyable { class EdgeBasedGraphFactory : boost::noncopyable
{
public: public:
struct SpeedProfileProperties; struct SpeedProfileProperties;
explicit EdgeBasedGraphFactory( explicit EdgeBasedGraphFactory(const boost::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
const boost::shared_ptr<NodeBasedDynamicGraph>& node_based_graph,
std::unique_ptr<RestrictionMap> restricion_map, std::unique_ptr<RestrictionMap> restricion_map,
std::vector<NodeID> &barrier_node_list, std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list, std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> &m_node_info_list, std::vector<NodeInfo> &m_node_info_list,
SpeedProfileProperties & speed_profile SpeedProfileProperties &speed_profile);
);
void Run( void Run(const std::string &original_edge_data_filename,
const std::string & original_edge_data_filename,
const std::string &geometry_filename, const std::string &geometry_filename,
lua_State *myLuaState lua_State *myLuaState);
);
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges); void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes); void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
TurnInstruction AnalyzeTurn( TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
const NodeID u,
const NodeID v,
const NodeID w
) const;
int GetTurnPenalty( int GetTurnPenalty(const NodeID u, const NodeID v, const NodeID w, lua_State *myLuaState) const;
const NodeID u,
const NodeID v,
const NodeID w,
lua_State *myLuaState
) const;
unsigned GetNumberOfEdgeBasedNodes() const; unsigned GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties{ struct SpeedProfileProperties
SpeedProfileProperties() : {
trafficSignalPenalty(0), SpeedProfileProperties()
uTurnPenalty(0), : trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false)
has_turn_penalty_function(false) {
{ } }
int trafficSignalPenalty; int trafficSignalPenalty;
int uTurnPenalty; int uTurnPenalty;
@ -130,22 +118,16 @@ private:
void CompressGeometry(); void CompressGeometry();
void RenumberEdges(); void RenumberEdges();
void GenerateEdgeExpandedNodes(); void GenerateEdgeExpandedNodes();
void GenerateEdgeExpandedEdges( void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
const std::string& original_edge_data_filename, lua_State *lua_state);
lua_State* lua_state
);
void InsertEdgeBasedNode( void InsertEdgeBasedNode(NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator v, NodeBasedDynamicGraph::NodeIterator v,
NodeBasedDynamicGraph::EdgeIterator e1, NodeBasedDynamicGraph::EdgeIterator e1,
bool belongsToTinyComponent bool belongsToTinyComponent);
);
void FlushVectorToStream( void FlushVectorToStream(std::ofstream &edge_data_file,
std::ofstream & edge_data_file, std::vector<OriginalEdgeData> &original_edge_data_vector) const;
std::vector<OriginalEdgeData> & original_edge_data_vector
) const;
unsigned max_id; unsigned max_id;
}; };

View File

@ -146,7 +146,8 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
m_free_list.pop_back(); m_free_list.pop_back();
} }
const boost::unordered_map<EdgeID, unsigned>::const_iterator iter = m_edge_id_to_list_index_map.find(edge_id_1); const boost::unordered_map<EdgeID, unsigned>::const_iterator iter =
m_edge_id_to_list_index_map.find(edge_id_1);
BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end()); BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end());
const unsigned edge_bucket_id1 = iter->second; const unsigned edge_bucket_id1 = iter->second;
BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1)); BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1));

View File

@ -27,90 +27,95 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TemporaryStorage.h" #include "TemporaryStorage.h"
TemporaryStorage::TemporaryStorage() { TemporaryStorage::TemporaryStorage() { temp_directory = boost::filesystem::temp_directory_path(); }
temp_directory = boost::filesystem::temp_directory_path();
}
TemporaryStorage & TemporaryStorage::GetInstance(){ TemporaryStorage &TemporaryStorage::GetInstance()
{
static TemporaryStorage static_instance; static TemporaryStorage static_instance;
return static_instance; return static_instance;
} }
TemporaryStorage::~TemporaryStorage() { TemporaryStorage::~TemporaryStorage() { RemoveAll(); }
RemoveAll();
}
void TemporaryStorage::RemoveAll() { void TemporaryStorage::RemoveAll()
{
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
for(unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id) { for (unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id)
{
DeallocateSlot(slot_id); DeallocateSlot(slot_id);
} }
stream_data_list.clear(); stream_data_list.clear();
} }
int TemporaryStorage::AllocateSlot() { int TemporaryStorage::AllocateSlot()
{
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
try { try
{
stream_data_list.push_back(StreamData()); stream_data_list.push_back(StreamData());
} catch(boost::filesystem::filesystem_error & e) { }
catch (boost::filesystem::filesystem_error &e)
{
Abort(e); Abort(e);
} }
CheckIfTemporaryDeviceFull(); CheckIfTemporaryDeviceFull();
return stream_data_list.size() - 1; return stream_data_list.size() - 1;
} }
void TemporaryStorage::DeallocateSlot(const int slot_id) { void TemporaryStorage::DeallocateSlot(const int slot_id)
try { {
try
{
StreamData &data = stream_data_list[slot_id]; StreamData &data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!boost::filesystem::exists(data.temp_path)) { if (!boost::filesystem::exists(data.temp_path))
{
return; return;
} }
if(data.temp_file->is_open()) { if (data.temp_file->is_open())
{
data.temp_file->close(); data.temp_file->close();
} }
boost::filesystem::remove(data.temp_path); boost::filesystem::remove(data.temp_path);
} catch(boost::filesystem::filesystem_error & e) { }
catch (boost::filesystem::filesystem_error &e)
{
Abort(e); Abort(e);
} }
} }
void TemporaryStorage::WriteToSlot( void TemporaryStorage::WriteToSlot(const int slot_id, char *pointer, const std::size_t size)
const int slot_id, {
char * pointer, try
const std::size_t size {
) {
try {
StreamData &data = stream_data_list[slot_id]; StreamData &data = stream_data_list[slot_id];
BOOST_ASSERT(data.write_mode); BOOST_ASSERT(data.write_mode);
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(data.write_mode, "Writing after first read is not allowed");
data.write_mode, if (1073741824 < data.buffer.size())
"Writing after first read is not allowed" {
);
if( 1073741824 < data.buffer.size() ) {
data.temp_file->write(&data.buffer[0], data.buffer.size()); data.temp_file->write(&data.buffer[0], data.buffer.size());
// data.temp_file->write(pointer, size); // data.temp_file->write(pointer, size);
data.buffer.clear(); data.buffer.clear();
CheckIfTemporaryDeviceFull(); CheckIfTemporaryDeviceFull();
} }
data.buffer.insert(data.buffer.end(), pointer, pointer + size); data.buffer.insert(data.buffer.end(), pointer, pointer + size);
}
} catch(boost::filesystem::filesystem_error & e) { catch (boost::filesystem::filesystem_error &e)
{
Abort(e); Abort(e);
} }
} }
void TemporaryStorage::ReadFromSlot( void TemporaryStorage::ReadFromSlot(const int slot_id, char *pointer, const std::size_t size)
const int slot_id, {
char * pointer, try
const std::size_t size {
) {
try {
StreamData &data = stream_data_list[slot_id]; StreamData &data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
if( data.write_mode ) { if (data.write_mode)
{
data.write_mode = false; data.write_mode = false;
data.temp_file->write(&data.buffer[0], data.buffer.size()); data.temp_file->write(&data.buffer[0], data.buffer.size());
data.buffer.clear(); data.buffer.clear();
@ -119,44 +124,57 @@ void TemporaryStorage::ReadFromSlot(
} }
BOOST_ASSERT(!data.write_mode); BOOST_ASSERT(!data.write_mode);
data.temp_file->read(pointer, size); data.temp_file->read(pointer, size);
} catch(boost::filesystem::filesystem_error & e) { }
catch (boost::filesystem::filesystem_error &e)
{
Abort(e); Abort(e);
} }
} }
uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice() { uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice()
{
uint64_t value = -1; uint64_t value = -1;
try { try
{
boost::filesystem::path p = boost::filesystem::temp_directory_path(); boost::filesystem::path p = boost::filesystem::temp_directory_path();
boost::filesystem::space_info s = boost::filesystem::space(p); boost::filesystem::space_info s = boost::filesystem::space(p);
value = s.free; value = s.free;
} catch(boost::filesystem::filesystem_error & e) { }
catch (boost::filesystem::filesystem_error &e)
{
Abort(e); Abort(e);
} }
return value; return value;
} }
void TemporaryStorage::CheckIfTemporaryDeviceFull() { void TemporaryStorage::CheckIfTemporaryDeviceFull()
{
boost::filesystem::path p = boost::filesystem::temp_directory_path(); boost::filesystem::path p = boost::filesystem::temp_directory_path();
boost::filesystem::space_info s = boost::filesystem::space(p); boost::filesystem::space_info s = boost::filesystem::space(p);
if( (1024*1024) > s.free ) { if ((1024 * 1024) > s.free)
{
throw OSRMException("temporary device is full"); throw OSRMException("temporary device is full");
} }
} }
boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id) { boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id)
{
boost::filesystem::fstream::pos_type position; boost::filesystem::fstream::pos_type position;
try { try
{
StreamData &data = stream_data_list[slot_id]; StreamData &data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
position = data.temp_file->tellp(); position = data.temp_file->tellp();
} catch(boost::filesystem::filesystem_error & e) { }
catch (boost::filesystem::filesystem_error &e)
{
Abort(e); Abort(e);
} }
return position; return position;
} }
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error& e) { void TemporaryStorage::Abort(const boost::filesystem::filesystem_error &e)
{
RemoveAll(); RemoveAll();
throw OSRMException(e.what()); throw OSRMException(e.what());
} }

View File

@ -56,7 +56,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static boost::filesystem::path temp_directory; static boost::filesystem::path temp_directory;
static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%"); static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%");
class TemporaryStorage { class TemporaryStorage
{
public: public:
static TemporaryStorage &GetInstance(); static TemporaryStorage &GetInstance();
virtual ~TemporaryStorage(); virtual ~TemporaryStorage();
@ -69,43 +70,33 @@ public:
uint64_t GetFreeBytesOnTemporaryDevice(); uint64_t GetFreeBytesOnTemporaryDevice();
boost::filesystem::fstream::pos_type Tell(const int slot_id); boost::filesystem::fstream::pos_type Tell(const int slot_id);
void RemoveAll(); void RemoveAll();
private: private:
TemporaryStorage(); TemporaryStorage();
TemporaryStorage(TemporaryStorage const &) {}; TemporaryStorage(TemporaryStorage const &) {};
TemporaryStorage & operator=(TemporaryStorage const &) { TemporaryStorage &operator=(TemporaryStorage const &) { return *this; }
return *this;
}
void Abort(const boost::filesystem::filesystem_error &e); void Abort(const boost::filesystem::filesystem_error &e);
void CheckIfTemporaryDeviceFull(); void CheckIfTemporaryDeviceFull();
struct StreamData { struct StreamData
{
bool write_mode; bool write_mode;
boost::filesystem::path temp_path; boost::filesystem::path temp_path;
boost::shared_ptr<boost::filesystem::fstream> temp_file; boost::shared_ptr<boost::filesystem::fstream> temp_file;
boost::shared_ptr<boost::mutex> readWriteMutex; boost::shared_ptr<boost::mutex> readWriteMutex;
std::vector<char> buffer; std::vector<char> buffer;
StreamData() : StreamData()
write_mode(true), : write_mode(true), temp_path(boost::filesystem::unique_path(temp_directory.append(
temp_path( TemporaryFilePattern.begin(), TemporaryFilePattern.end()))),
boost::filesystem::unique_path( temp_file(new boost::filesystem::fstream(
temp_directory.append( temp_path, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
TemporaryFilePattern.begin(),
TemporaryFilePattern.end()
)
)
),
temp_file(
new boost::filesystem::fstream(
temp_path,
std::ios::in|std::ios::out|std::ios::trunc|std::ios::binary
)
),
readWriteMutex(boost::make_shared<boost::mutex>()) readWriteMutex(boost::make_shared<boost::mutex>())
{ {
if( temp_file->fail() ) { if (temp_file->fail())
{
throw OSRMException("temporary file could not be created"); throw OSRMException("temporary file could not be created");
} }
} }