diff --git a/Contractor/Contractor.h b/Contractor/Contractor.h index 46bf78be8..e24a6c562 100644 --- a/Contractor/Contractor.h +++ b/Contractor/Contractor.h @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CONTRACTOR_H_INCLUDED -#define CONTRACTOR_H_INCLUDED +#ifndef CONTRACTOR_H +#define CONTRACTOR_H #include "TemporaryStorage.h" #include "../DataStructures/BinaryHeap.h" @@ -40,7 +40,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../Util/StringUtil.h" #include -#include #include #include @@ -54,7 +53,7 @@ class Contractor { ContractorEdgeData() : distance(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0), - originalViaNodeID(false) + is_original_via_node_ID(false) { } ContractorEdgeData(unsigned _distance, @@ -65,7 +64,7 @@ class Contractor bool _backward) : distance(_distance), id(_id), originalEdges(std::min((unsigned)1 << 28, _originalEdges)), shortcut(_shortcut), - forward(_forward), backward(_backward), originalViaNodeID(false) + forward(_forward), backward(_backward), is_original_via_node_ID(false) { } unsigned distance; @@ -74,101 +73,96 @@ class Contractor bool shortcut : 1; bool forward : 1; bool backward : 1; - bool originalViaNodeID : 1; + bool is_original_via_node_ID : 1; } data; - struct _HeapData + struct ContractorHeapData { short hop; bool target; - _HeapData() : hop(0), target(false) {} - _HeapData(short h, bool t) : hop(h), target(t) {} + ContractorHeapData() : hop(0), target(false) {} + ContractorHeapData(short h, bool t) : hop(h), target(t) {} }; - typedef DynamicGraph _DynamicGraph; - // typedef BinaryHeap< NodeID, NodeID, int, _HeapData, ArrayStorage > _Heap; - typedef BinaryHeap> _Heap; - typedef _DynamicGraph::InputEdge _ContractorEdge; + typedef DynamicGraph ContractorGraph; + // typedef BinaryHeap< NodeID, NodeID, int, ContractorHeapData, ArrayStorage + // > ContractorHeap; + typedef BinaryHeap> + ContractorHeap; + typedef ContractorGraph::InputEdge ContractorEdge; - struct _ThreadData + struct ContractorThreadData { - _Heap heap; - std::vector<_ContractorEdge> insertedEdges; + ContractorHeap heap; + std::vector inserted_edges; std::vector neighbours; - _ThreadData(NodeID nodes) : heap(nodes) {} + ContractorThreadData(NodeID nodes) : heap(nodes) {} }; - struct _PriorityData + struct NodePriorityData { int depth; - _PriorityData() : depth(0) {} + NodePriorityData() : depth(0) {} }; - struct _ContractionInformation + struct ContractionStats { - int edgesDeleted; - int edgesAdded; - int originalEdgesDeleted; - int originalEdgesAdded; - _ContractionInformation() - : edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0) + int edges_deleted_count; + int edges_added_count; + int original_edges_deleted_count; + int original_edges_added_count; + ContractionStats() + : edges_deleted_count(0), edges_added_count(0), original_edges_deleted_count(0), + original_edges_added_count(0) { } }; - struct _RemainingNodeData + struct RemainingNodeData { - _RemainingNodeData() : id(0), isIndependent(false) {} + RemainingNodeData() : id(0), is_independent(false) {} NodeID id : 31; - bool isIndependent : 1; - }; - - struct _NodePartitionor - { - inline bool operator()(_RemainingNodeData &nodeData) const - { - return !nodeData.isIndependent; - } + bool is_independent : 1; }; public: - template Contractor(int nodes, ContainerT &inputEdges) + template Contractor(int nodes, ContainerT &input_edge_list) { - std::vector<_ContractorEdge> edges; - edges.reserve(inputEdges.size() * 2); + std::vector edges; + edges.reserve(input_edge_list.size() * 2); temp_edge_counter = 0; - typename ContainerT::deallocation_iterator diter = inputEdges.dbegin(); - typename ContainerT::deallocation_iterator dend = inputEdges.dend(); + auto diter = input_edge_list.dbegin(); + auto dend = input_edge_list.dend(); - _ContractorEdge newEdge; + ContractorEdge new_edge; while (diter != dend) { - newEdge.source = diter->source(); - newEdge.target = diter->target(); - 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"); + new_edge.source = diter->source(); + new_edge.target = diter->target(); + new_edge.data = ContractorEdgeData((std::max)((int)diter->weight(), 1), + 1, + diter->id(), + false, + diter->isForward(), + diter->isBackward()); + BOOST_ASSERT_MSG(new_edge.data.distance > 0, "edge distance < 1"); #ifndef NDEBUG - if (newEdge.data.distance > 24 * 60 * 60 * 10) + if (new_edge.data.distance > 24 * 60 * 60 * 10) { SimpleLogger().Write(logWARNING) << "Edge weight large -> " - << newEdge.data.distance; + << new_edge.data.distance; } #endif - edges.push_back(newEdge); - std::swap(newEdge.source, newEdge.target); - newEdge.data.forward = diter->isBackward(); - newEdge.data.backward = diter->isForward(); - edges.push_back(newEdge); + edges.push_back(new_edge); + std::swap(new_edge.source, new_edge.target); + new_edge.data.forward = diter->isBackward(); + new_edge.data.backward = diter->isForward(); + edges.push_back(new_edge); ++diter; } // clear input vector and trim the current set of edges with the well-known swap trick - inputEdges.clear(); + input_edge_list.clear(); sort(edges.begin(), edges.end()); NodeID edge = 0; for (NodeID i = 0; i < edges.size();) @@ -182,65 +176,67 @@ class Contractor i++; continue; } - _ContractorEdge forwardEdge; - _ContractorEdge backwardEdge; - forwardEdge.source = backwardEdge.source = source; - forwardEdge.target = backwardEdge.target = target; - forwardEdge.data.forward = backwardEdge.data.backward = true; - forwardEdge.data.backward = backwardEdge.data.forward = false; - forwardEdge.data.shortcut = backwardEdge.data.shortcut = false; - forwardEdge.data.id = backwardEdge.data.id = id; - forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1; - forwardEdge.data.distance = backwardEdge.data.distance = + ContractorEdge forward_edge; + ContractorEdge reverse_edge; + forward_edge.source = reverse_edge.source = source; + forward_edge.target = reverse_edge.target = target; + forward_edge.data.forward = reverse_edge.data.backward = true; + forward_edge.data.backward = reverse_edge.data.forward = false; + forward_edge.data.shortcut = reverse_edge.data.shortcut = false; + forward_edge.data.id = reverse_edge.data.id = id; + forward_edge.data.originalEdges = reverse_edge.data.originalEdges = 1; + forward_edge.data.distance = reverse_edge.data.distance = std::numeric_limits::max(); // remove parallel edges 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); + forward_edge.data.distance = + std::min(edges[i].data.distance, forward_edge.data.distance); } if (edges[i].data.backward) { - backwardEdge.data.distance = - std::min(edges[i].data.distance, backwardEdge.data.distance); + reverse_edge.data.distance = + std::min(edges[i].data.distance, reverse_edge.data.distance); } ++i; } // merge edges (s,t) and (t,s) into bidirectional edge - if (forwardEdge.data.distance == backwardEdge.data.distance) + if (forward_edge.data.distance == reverse_edge.data.distance) { - if ((int)forwardEdge.data.distance != std::numeric_limits::max()) + if ((int)forward_edge.data.distance != std::numeric_limits::max()) { - forwardEdge.data.backward = true; - edges[edge++] = forwardEdge; + forward_edge.data.backward = true; + edges[edge++] = forward_edge; } } else { // insert seperate edges - if (((int)forwardEdge.data.distance) != std::numeric_limits::max()) + if (((int)forward_edge.data.distance) != std::numeric_limits::max()) { - edges[edge++] = forwardEdge; + edges[edge++] = forward_edge; } - if ((int)backwardEdge.data.distance != std::numeric_limits::max()) + if ((int)reverse_edge.data.distance != std::numeric_limits::max()) { - edges[edge++] = backwardEdge; + edges[edge++] = reverse_edge; } } } std::cout << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl; edges.resize(edge); - _graph = std::make_shared<_DynamicGraph>(nodes, edges); + contractor_graph = std::make_shared(nodes, edges); edges.clear(); - std::vector<_ContractorEdge>().swap(edges); + edges.shrink_to_fit(); + BOOST_ASSERT(0 == edges.capacity()); // unsigned maxdegree = 0; // NodeID highestNode = 0; // - // for(unsigned i = 0; i < _graph->GetNumberOfNodes(); ++i) { - // unsigned degree = _graph->EndEdges(i) - _graph->BeginEdges(i); + // for(unsigned i = 0; i < contractor_graph->GetNumberOfNodes(); ++i) { + // unsigned degree = contractor_graph->EndEdges(i) - + // contractor_graph->BeginEdges(i); // if(degree > maxdegree) { // maxdegree = degree; // highestNode = i; @@ -249,251 +245,256 @@ class Contractor // // SimpleLogger().Write() << "edges at node with id " << highestNode << " has degree // " << maxdegree; - // for(unsigned i = _graph->BeginEdges(highestNode); i < - // _graph->EndEdges(highestNode); ++i) { - // SimpleLogger().Write() << " ->(" << highestNode << "," << _graph->GetTarget(i) - // << "); via: " << _graph->GetEdgeData(i).via; + // for(unsigned i = contractor_graph->BeginEdges(highestNode); i < + // contractor_graph->EndEdges(highestNode); ++i) { + // SimpleLogger().Write() << " ->(" << highestNode << "," << + // contractor_graph->GetTarget(i) + // << "); via: " << contractor_graph->GetEdgeData(i).via; // } // Create temporary file - // GetTemporaryFileName(temporaryEdgeStorageFilename); edge_storage_slot = TemporaryStorage::GetInstance().AllocateSlot(); std::cout << "contractor finished initalization" << std::endl; } - ~Contractor() - { - // Delete temporary file - // remove(temporaryEdgeStorageFilename.c_str()); - TemporaryStorage::GetInstance().DeallocateSlot(edge_storage_slot); - } + ~Contractor() { TemporaryStorage::GetInstance().DeallocateSlot(edge_storage_slot); } void Run() { - const NodeID numberOfNodes = _graph->GetNumberOfNodes(); - Percent p(numberOfNodes); + const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes(); + Percent p(number_of_nodes); - const unsigned maxThreads = omp_get_max_threads(); - std::vector<_ThreadData *> threadData; - for (unsigned threadNum = 0; threadNum < maxThreads; ++threadNum) + const unsigned thread_count = omp_get_max_threads(); + std::vector thread_data_list; + for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id) { - threadData.push_back(new _ThreadData(numberOfNodes)); + thread_data_list.push_back(new ContractorThreadData(number_of_nodes)); } - std::cout << "Contractor is using " << maxThreads << " threads" << std::endl; + std::cout << "Contractor is using " << thread_count << " threads" << std::endl; - NodeID numberOfContractedNodes = 0; - std::vector<_RemainingNodeData> remainingNodes(numberOfNodes); - std::vector nodePriority(numberOfNodes); - std::vector<_PriorityData> nodeData(numberOfNodes); + NodeID number_of_contracted_nodes = 0; + std::vector remaining_nodes(number_of_nodes); + std::vector node_priorities(number_of_nodes); + std::vector node_data(number_of_nodes); -// initialize the variables +// initialize priorities in parallel #pragma omp parallel for schedule(guided) - for (int x = 0; x < (int)numberOfNodes; ++x) + for (int x = 0; x < (int)number_of_nodes; ++x) { - remainingNodes[x].id = x; + remaining_nodes[x].id = x; } std::cout << "initializing elimination PQ ..." << std::flush; #pragma omp parallel { - _ThreadData *data = threadData[omp_get_thread_num()]; + ContractorThreadData *data = thread_data_list[omp_get_thread_num()]; #pragma omp parallel for schedule(guided) - for (int x = 0; x < (int)numberOfNodes; ++x) + for (int x = 0; x < (int)number_of_nodes; ++x) { - nodePriority[x] = _Evaluate(data, &nodeData[x], x); + node_priorities[x] = EvaluateNodePriority(data, &node_data[x], x); } } - std::cout << "ok" << std::endl << "preprocessing " << numberOfNodes << " nodes ..." + std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..." << std::flush; - bool flushedContractor = false; - while (numberOfNodes > 2 && numberOfContractedNodes < numberOfNodes) + bool flushed_contractor = false; + while (number_of_nodes > 2 && number_of_contracted_nodes < number_of_nodes) { - if (!flushedContractor && (numberOfContractedNodes > (numberOfNodes * 0.65))) + if (!flushed_contractor && (number_of_contracted_nodes > (number_of_nodes * 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; + DeallocatingVector new_edge_set; // this one is not explicitely + // cleared since it goes out of + // scope anywa + std::cout << " [flush " << number_of_contracted_nodes << " nodes] " << std::flush; - //Delete old heap data to free memory that we need for the coming operations - for(_ThreadData * data : threadData) { - delete data; + // Delete old heap data to free memory that we need for the coming operations + for (ContractorThreadData *data : thread_data_list) + { + delete data; } - threadData.clear(); + thread_data_list.clear(); // Create new priority array - std::vector newNodePriority(remainingNodes.size()); + std::vector new_node_priority(remaining_nodes.size()); // 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()); + orig_node_id_to_new_id_map.resize(remaining_nodes.size()); // this map gives the new IDs from the old ones, necessary to remap targets from the // remaining graph - std::vector newNodeIDFromOldNodeIDMap(numberOfNodes, UINT_MAX); + std::vector new_node_id_from_orig_id_map(number_of_nodes, UINT_MAX); - // build forward and backward renumbering map and remap ids in remainingNodes and + // build forward and backward renumbering map and remap ids in remaining_nodes and // Priorities. - for (unsigned newNodeID = 0; newNodeID < remainingNodes.size(); ++newNodeID) + for (unsigned new_node_id = 0; new_node_id < remaining_nodes.size(); ++new_node_id) { // create renumbering maps in both directions - oldNodeIDFromNewNodeIDMap[newNodeID] = remainingNodes[newNodeID].id; - newNodeIDFromOldNodeIDMap[remainingNodes[newNodeID].id] = newNodeID; - newNodePriority[newNodeID] = nodePriority[remainingNodes[newNodeID].id]; - remainingNodes[newNodeID].id = newNodeID; + orig_node_id_to_new_id_map[new_node_id] = remaining_nodes[new_node_id].id; + new_node_id_from_orig_id_map[remaining_nodes[new_node_id].id] = new_node_id; + new_node_priority[new_node_id] = + node_priorities[remaining_nodes[new_node_id].id]; + remaining_nodes[new_node_id].id = new_node_id; } - TemporaryStorage &tempStorage = TemporaryStorage::GetInstance(); + TemporaryStorage &temporary_storage = TemporaryStorage::GetInstance(); // walk over all nodes - for (unsigned i = 0; i < _graph->GetNumberOfNodes(); ++i) + for (unsigned i = 0; i < contractor_graph->GetNumberOfNodes(); ++i) { const NodeID start = i; - for (_DynamicGraph::EdgeIterator currentEdge = _graph->BeginEdges(start); - currentEdge < _graph->EndEdges(start); - ++currentEdge) + auto last_edge = contractor_graph->EndEdges(start); + for (auto current_edge = contractor_graph->BeginEdges(start); + current_edge < last_edge; + ++current_edge) { - _DynamicGraph::EdgeData &data = _graph->GetEdgeData(currentEdge); - const NodeID target = _graph->GetTarget(currentEdge); - if (UINT_MAX == newNodeIDFromOldNodeIDMap[i]) + ContractorGraph::EdgeData &data = + contractor_graph->GetEdgeData(current_edge); + const NodeID target = contractor_graph->GetTarget(current_edge); + if (UINT_MAX == new_node_id_from_orig_id_map[i]) { // Save edges of this node w/o renumbering. - tempStorage.WriteToSlot( + temporary_storage.WriteToSlot( edge_storage_slot, (char *)&start, sizeof(NodeID)); - tempStorage.WriteToSlot( + temporary_storage.WriteToSlot( edge_storage_slot, (char *)&target, sizeof(NodeID)); - tempStorage.WriteToSlot( - edge_storage_slot, (char *)&data, sizeof(_DynamicGraph::EdgeData)); + temporary_storage.WriteToSlot(edge_storage_slot, + (char *)&data, + sizeof(ContractorGraph::EdgeData)); ++temp_edge_counter; } else { // node is not yet contracted. // add (renumbered) outgoing edges to new DynamicGraph. - _ContractorEdge newEdge; - newEdge.source = newNodeIDFromOldNodeIDMap[start]; - newEdge.target = newNodeIDFromOldNodeIDMap[target]; - newEdge.data = data; - newEdge.data.originalViaNodeID = true; - BOOST_ASSERT_MSG(UINT_MAX != newNodeIDFromOldNodeIDMap[start], + ContractorEdge new_edge; + new_edge.source = new_node_id_from_orig_id_map[start]; + new_edge.target = new_node_id_from_orig_id_map[target]; + new_edge.data = data; + new_edge.data.is_original_via_node_ID = true; + BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[start], "new start id not resolveable"); - BOOST_ASSERT_MSG(UINT_MAX != newNodeIDFromOldNodeIDMap[target], + BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[target], "new target id not resolveable"); - newSetOfEdges.push_back(newEdge); + new_edge_set.push_back(new_edge); } } } // Delete map from old NodeIDs to new ones. - std::vector().swap(newNodeIDFromOldNodeIDMap); + new_node_id_from_orig_id_map.clear(); + new_node_id_from_orig_id_map.shrink_to_fit(); // Replace old priorities array by new one - nodePriority.swap(newNodePriority); - // Delete old nodePriority vector - std::vector().swap(newNodePriority); + node_priorities.swap(new_node_priority); + // Delete old node_priorities vector + std::vector().swap(new_node_priority); // old Graph is removed - _graph.reset(); + contractor_graph.reset(); // create new graph - std::sort(newSetOfEdges.begin(), newSetOfEdges.end()); - _graph = std::make_shared<_DynamicGraph>(remainingNodes.size(), newSetOfEdges); + std::sort(new_edge_set.begin(), new_edge_set.end()); + contractor_graph = + std::make_shared(remaining_nodes.size(), new_edge_set); - newSetOfEdges.clear(); - flushedContractor = true; + new_edge_set.clear(); + flushed_contractor = true; // INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH! // reinitialize heaps and ThreadData objects with appropriate size - for (unsigned threadNum = 0; threadNum < maxThreads; ++threadNum) + for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id) { - threadData.push_back(new _ThreadData(_graph->GetNumberOfNodes())); + thread_data_list.push_back( + new ContractorThreadData(contractor_graph->GetNumberOfNodes())); } } - const int last = (int)remainingNodes.size(); + const int last = (int)remaining_nodes.size(); #pragma omp parallel { // determine independent node set - _ThreadData *const data = threadData[omp_get_thread_num()]; + ContractorThreadData *const data = thread_data_list[omp_get_thread_num()]; #pragma omp for schedule(guided) for (int i = 0; i < last; ++i) { - const NodeID node = remainingNodes[i].id; - remainingNodes[i].isIndependent = - _IsIndependent(nodePriority /*, nodeData*/, data, node); + const NodeID node = remaining_nodes[i].id; + remaining_nodes[i].is_independent = + IsNodeIndependent(node_priorities, data, node); } } - _NodePartitionor functor; - const std::vector<_RemainingNodeData>::const_iterator first = - stable_partition(remainingNodes.begin(), remainingNodes.end(), functor); - const int firstIndependent = first - remainingNodes.begin(); + const auto first = stable_partition(remaining_nodes.begin(), + remaining_nodes.end(), + [](RemainingNodeData node_data) + { return !node_data.is_independent; }); + const int first_independent_node = first - remaining_nodes.begin(); // contract independent nodes #pragma omp parallel { - _ThreadData *data = threadData[omp_get_thread_num()]; + ContractorThreadData *data = thread_data_list[omp_get_thread_num()]; #pragma omp for schedule(guided) nowait - for (int position = firstIndependent; position < last; ++position) + for (int position = first_independent_node; position < last; ++position) { - NodeID x = remainingNodes[position].id; - _Contract(data, x); - // nodePriority[x] = -1; + NodeID x = remaining_nodes[position].id; + ContractNode(data, x); } - std::sort(data->insertedEdges.begin(), data->insertedEdges.end()); + std::sort(data->inserted_edges.begin(), data->inserted_edges.end()); } #pragma omp parallel { - _ThreadData *data = threadData[omp_get_thread_num()]; + ContractorThreadData *data = thread_data_list[omp_get_thread_num()]; #pragma omp for schedule(guided) nowait - for (int position = firstIndependent; position < last; ++position) + for (int position = first_independent_node; position < last; ++position) { - NodeID x = remainingNodes[position].id; - _DeleteIncomingEdges(data, x); + NodeID x = remaining_nodes[position].id; + DeleteIncomingEdges(data, x); } } - //insert new edges - for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) { - _ThreadData& data = *threadData[threadNum]; - for(const _ContractorEdge& edge : data.insertedEdges) { - _DynamicGraph::EdgeIterator currentEdgeID = _graph->FindEdge(edge.source, edge.target); - if(currentEdgeID < _graph->EndEdges(edge.source) ) { - _DynamicGraph::EdgeData & currentEdgeData = _graph->GetEdgeData(currentEdgeID); - if(currentEdgeData.shortcut && - edge.data.forward == currentEdgeData.forward && - edge.data.backward == currentEdgeData.backward && - edge.data.distance < currentEdgeData.distance) + // insert new edges + for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id) + { + ContractorThreadData &data = *thread_data_list[thread_id]; + for (const ContractorEdge &edge : data.inserted_edges) + { + auto current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target); + if (current_edge_ID < contractor_graph->EndEdges(edge.source)) + { + ContractorGraph::EdgeData ¤t_data = + contractor_graph->GetEdgeData(current_edge_ID); + if (current_data.shortcut && edge.data.forward == current_data.forward && + edge.data.backward == current_data.backward && + edge.data.distance < current_data.distance) { // found a duplicate edge with smaller weight, update it. - currentEdgeData = edge.data; - // currentEdgeData.distance = std::min(currentEdgeData.distance, - // edge.data.distance); + current_data = edge.data; continue; } } - _graph->InsertEdge(edge.source, edge.target, edge.data); + contractor_graph->InsertEdge(edge.source, edge.target, edge.data); } - data.insertedEdges.clear(); + data.inserted_edges.clear(); } // update priorities #pragma omp parallel { - _ThreadData *data = threadData[omp_get_thread_num()]; + ContractorThreadData *data = thread_data_list[omp_get_thread_num()]; #pragma omp for schedule(guided) nowait - for (int position = firstIndependent; position < last; ++position) + for (int position = first_independent_node; position < last; ++position) { - NodeID x = remainingNodes[position].id; - _UpdateNeighbours(nodePriority, nodeData, data, x); + NodeID x = remaining_nodes[position].id; + UpdateNodeNeighbours(node_priorities, node_data, data, x); } } // remove contracted nodes from the pool - numberOfContractedNodes += last - firstIndependent; - remainingNodes.resize(firstIndependent); - std::vector<_RemainingNodeData>(remainingNodes).swap(remainingNodes); + number_of_contracted_nodes += last - first_independent_node; + remaining_nodes.resize(first_independent_node); + std::vector(remaining_nodes).swap(remaining_nodes); // unsigned maxdegree = 0; // unsigned avgdegree = 0; // unsigned mindegree = UINT_MAX; // unsigned quaddegree = 0; // - // for(unsigned i = 0; i < remainingNodes.size(); ++i) { - // unsigned degree = _graph->EndEdges(remainingNodes[i].first) - - // _graph->BeginEdges(remainingNodes[i].first); + // for(unsigned i = 0; i < remaining_nodes.size(); ++i) { + // unsigned degree = contractor_graph->EndEdges(remaining_nodes[i].first) + // - + // contractor_graph->BeginEdges(remaining_nodes[i].first); // if(degree > maxdegree) // maxdegree = degree; // if(degree < mindegree) @@ -503,86 +504,86 @@ class Contractor // quaddegree += (degree*degree); // } // - // avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); - // quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); + // avgdegree /= std::max((unsigned)1,(unsigned)remaining_nodes.size() ); + // quaddegree /= std::max((unsigned)1,(unsigned)remaining_nodes.size() ); // - // SimpleLogger().Write() << "rest: " << remainingNodes.size() << ", max: " + // SimpleLogger().Write() << "rest: " << remaining_nodes.size() << ", max: " // << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", // quad: " << quaddegree; - p.printStatus(numberOfContractedNodes); + p.printStatus(number_of_contracted_nodes); } - for(_ThreadData * data : threadData) { - delete data; + for (ContractorThreadData *data : thread_data_list) + { + delete data; } - threadData.clear(); + thread_data_list.clear(); } template inline void GetEdges(DeallocatingVector &edges) { - Percent p(_graph->GetNumberOfNodes()); + Percent p(contractor_graph->GetNumberOfNodes()); SimpleLogger().Write() << "Getting edges of minimized graph"; - NodeID numberOfNodes = _graph->GetNumberOfNodes(); - if (_graph->GetNumberOfNodes()) + NodeID number_of_nodes = contractor_graph->GetNumberOfNodes(); + if (contractor_graph->GetNumberOfNodes()) { - Edge newEdge; - for (NodeID node = 0; node < numberOfNodes; ++node) + Edge new_edge; + for (NodeID node = 0; node < number_of_nodes; ++node) { p.printStatus(node); - for (_DynamicGraph::EdgeIterator edge = _graph->BeginEdges(node), - endEdges = _graph->EndEdges(node); - edge < endEdges; - ++edge) + auto endEdges = contractor_graph->EndEdges(node); + for (auto edge = contractor_graph->BeginEdges(node); edge < endEdges; ++edge) { - const NodeID target = _graph->GetTarget(edge); - const _DynamicGraph::EdgeData &data = _graph->GetEdgeData(edge); - if (!oldNodeIDFromNewNodeIDMap.empty()) + const NodeID target = contractor_graph->GetTarget(edge); + const ContractorGraph::EdgeData &data = contractor_graph->GetEdgeData(edge); + if (!orig_node_id_to_new_id_map.empty()) { - newEdge.source = oldNodeIDFromNewNodeIDMap[node]; - newEdge.target = oldNodeIDFromNewNodeIDMap[target]; + new_edge.source = orig_node_id_to_new_id_map[node]; + new_edge.target = orig_node_id_to_new_id_map[target]; } else { - newEdge.source = node; - newEdge.target = target; + new_edge.source = node; + new_edge.target = target; } - BOOST_ASSERT_MSG(UINT_MAX != newEdge.source, "Source id invalid"); - BOOST_ASSERT_MSG(UINT_MAX != newEdge.target, "Target id invalid"); - newEdge.data.distance = data.distance; - newEdge.data.shortcut = data.shortcut; - if (!data.originalViaNodeID && !oldNodeIDFromNewNodeIDMap.empty()) + BOOST_ASSERT_MSG(UINT_MAX != new_edge.source, "Source id invalid"); + BOOST_ASSERT_MSG(UINT_MAX != new_edge.target, "Target id invalid"); + new_edge.data.distance = data.distance; + new_edge.data.shortcut = data.shortcut; + if (!data.is_original_via_node_ID && !orig_node_id_to_new_id_map.empty()) { - newEdge.data.id = oldNodeIDFromNewNodeIDMap[data.id]; + new_edge.data.id = orig_node_id_to_new_id_map[data.id]; } else { - newEdge.data.id = data.id; + new_edge.data.id = data.id; } - BOOST_ASSERT_MSG(newEdge.data.id != INT_MAX, // 2^31 + BOOST_ASSERT_MSG(new_edge.data.id != INT_MAX, // 2^31 "edge id invalid"); - newEdge.data.forward = data.forward; - newEdge.data.backward = data.backward; - edges.push_back(newEdge); + new_edge.data.forward = data.forward; + new_edge.data.backward = data.backward; + edges.push_back(new_edge); } } } - _graph.reset(); - std::vector().swap(oldNodeIDFromNewNodeIDMap); - BOOST_ASSERT(0 == oldNodeIDFromNewNodeIDMap.capacity()); + contractor_graph.reset(); + orig_node_id_to_new_id_map.clear(); + orig_node_id_to_new_id_map.shrink_to_fit(); - TemporaryStorage &tempStorage = TemporaryStorage::GetInstance(); + BOOST_ASSERT(0 == orig_node_id_to_new_id_map.capacity()); + TemporaryStorage &temporary_storage = TemporaryStorage::GetInstance(); // loads edges of graph before renumbering, no need for further numbering action. NodeID start; NodeID target; - _DynamicGraph::EdgeData data; + ContractorGraph::EdgeData data; Edge restored_edge; for (unsigned i = 0; i < temp_edge_counter; ++i) { - tempStorage.ReadFromSlot(edge_storage_slot, (char *)&start, sizeof(NodeID)); - tempStorage.ReadFromSlot(edge_storage_slot, (char *)&target, sizeof(NodeID)); - tempStorage.ReadFromSlot( - edge_storage_slot, (char *)&data, sizeof(_DynamicGraph::EdgeData)); + temporary_storage.ReadFromSlot(edge_storage_slot, (char *)&start, sizeof(NodeID)); + temporary_storage.ReadFromSlot(edge_storage_slot, (char *)&target, sizeof(NodeID)); + temporary_storage.ReadFromSlot( + edge_storage_slot, (char *)&data, sizeof(ContractorGraph::EdgeData)); restored_edge.source = start; restored_edge.target = target; restored_edge.data.distance = data.distance; @@ -592,236 +593,255 @@ class Contractor restored_edge.data.backward = data.backward; edges.push_back(restored_edge); } - tempStorage.DeallocateSlot(edge_storage_slot); + temporary_storage.DeallocateSlot(edge_storage_slot); } private: - inline void _Dijkstra(const int maxDistance, - const unsigned numTargets, - const int maxNodes, - _ThreadData *const data, - const NodeID middleNode) + inline void Dijkstra(const int max_distance, + const unsigned number_of_targets, + const int maxNodes, + ContractorThreadData *const data, + const NodeID middleNode) { - _Heap &heap = data->heap; + ContractorHeap &heap = data->heap; int nodes = 0; - unsigned targetsFound = 0; + unsigned number_of_targets_found = 0; while (heap.Size() > 0) { const NodeID node = heap.DeleteMin(); const int distance = heap.GetKey(node); - const short currentHop = heap.GetData(node).hop + 1; + const short current_hop = heap.GetData(node).hop + 1; if (++nodes > maxNodes) + { return; + } // Destination settled? - if (distance > maxDistance) + if (distance > max_distance) + { return; + } if (heap.GetData(node).target) { - ++targetsFound; - if (targetsFound >= numTargets) + ++number_of_targets_found; + if (number_of_targets_found >= number_of_targets) { return; } } // iterate over all edges of node - for (_DynamicGraph::EdgeIterator edge = _graph->BeginEdges(node), - endEdges = _graph->EndEdges(node); - edge != endEdges; - ++edge) + auto end_edges = contractor_graph->EndEdges(node); + for (auto edge = contractor_graph->BeginEdges(node); edge != end_edges; ++edge) { - const ContractorEdgeData &data = _graph->GetEdgeData(edge); + const ContractorEdgeData &data = contractor_graph->GetEdgeData(edge); if (!data.forward) { continue; } - const NodeID to = _graph->GetTarget(edge); + const NodeID to = contractor_graph->GetTarget(edge); if (middleNode == to) { continue; } - const int toDistance = distance + data.distance; + const int to_distance = distance + data.distance; // New Node discovered -> Add to Heap + Node Info Storage if (!heap.WasInserted(to)) { - heap.Insert(to, toDistance, _HeapData(currentHop, false)); + heap.Insert(to, to_distance, ContractorHeapData(current_hop, false)); } // Found a shorter Path -> Update distance - else if (toDistance < heap.GetKey(to)) + else if (to_distance < heap.GetKey(to)) { - heap.DecreaseKey(to, toDistance); - heap.GetData(to).hop = currentHop; + heap.DecreaseKey(to, to_distance); + heap.GetData(to).hop = current_hop; } } } } - inline float - _Evaluate(_ThreadData *const data, _PriorityData *const nodeData, const NodeID node) + inline float EvaluateNodePriority(ContractorThreadData *const data, + NodePriorityData *const node_data, + const NodeID node) { - _ContractionInformation stats; + ContractionStats stats; // perform simulated contraction - _Contract(data, node, &stats); + ContractNode(data, node, &stats); // Result will contain the priority float result; - if (0 == (stats.edgesDeleted * stats.originalEdgesDeleted)) - result = 1 * nodeData->depth; + if (0 == (stats.edges_deleted_count * stats.original_edges_deleted_count)) + { + result = 1 * node_data->depth; + } else - result = 2 * (((float)stats.edgesAdded) / stats.edgesDeleted) + - 4 * (((float)stats.originalEdgesAdded) / stats.originalEdgesDeleted) + - 1 * nodeData->depth; - assert(result >= 0); + { + result = 2 * (((float)stats.edges_added_count) / stats.edges_deleted_count) + + 4 * (((float)stats.original_edges_added_count) / + stats.original_edges_deleted_count) + + 1 * node_data->depth; + } + BOOST_ASSERT(result >= 0); return result; } - template - inline bool _Contract(_ThreadData *data, NodeID node, _ContractionInformation *stats = NULL) + template + inline bool + ContractNode(ContractorThreadData *data, NodeID node, ContractionStats *stats = NULL) { - _Heap &heap = data->heap; - int insertedEdgesSize = data->insertedEdges.size(); - std::vector<_ContractorEdge> &insertedEdges = data->insertedEdges; + ContractorHeap &heap = data->heap; + int inserted_edges_size = data->inserted_edges.size(); + std::vector &inserted_edges = data->inserted_edges; - for (_DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges(node), - endInEdges = _graph->EndEdges(node); - inEdge != endInEdges; - ++inEdge) + auto end_in_edges = contractor_graph->EndEdges(node); + for (auto in_edge = contractor_graph->BeginEdges(node); in_edge != end_in_edges; ++in_edge) { - const ContractorEdgeData &inData = _graph->GetEdgeData(inEdge); - const NodeID source = _graph->GetTarget(inEdge); - if (Simulate) + const ContractorEdgeData &in_data = contractor_graph->GetEdgeData(in_edge); + const NodeID source = contractor_graph->GetTarget(in_edge); + if (RUNSIMULATION) { - assert(stats != NULL); - ++stats->edgesDeleted; - stats->originalEdgesDeleted += inData.originalEdges; + BOOST_ASSERT(stats != NULL); + ++stats->edges_deleted_count; + stats->original_edges_deleted_count += in_data.originalEdges; } - if (!inData.backward) + if (!in_data.backward) + { continue; + } heap.Clear(); - heap.Insert(source, 0, _HeapData()); - int maxDistance = 0; - unsigned numTargets = 0; + heap.Insert(source, 0, ContractorHeapData()); + int max_distance = 0; + unsigned number_of_targets = 0; - for (_DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges(node), - endOutEdges = _graph->EndEdges(node); - outEdge != endOutEdges; - ++outEdge) + auto end_out_edges = contractor_graph->EndEdges(node); + for (auto out_edge = contractor_graph->BeginEdges(node); out_edge != end_out_edges; + ++out_edge) { - const ContractorEdgeData &outData = _graph->GetEdgeData(outEdge); - if (!outData.forward) + const ContractorEdgeData &out_data = contractor_graph->GetEdgeData(out_edge); + if (!out_data.forward) { continue; } - const NodeID target = _graph->GetTarget(outEdge); - const int pathDistance = inData.distance + outData.distance; - maxDistance = std::max(maxDistance, pathDistance); + const NodeID target = contractor_graph->GetTarget(out_edge); + const int path_distance = in_data.distance + out_data.distance; + max_distance = std::max(max_distance, path_distance); if (!heap.WasInserted(target)) { - heap.Insert(target, INT_MAX, _HeapData(0, true)); - ++numTargets; + heap.Insert(target, INT_MAX, ContractorHeapData(0, true)); + ++number_of_targets; } } - if (Simulate) + if (RUNSIMULATION) { - _Dijkstra(maxDistance, numTargets, 1000, data, node); + Dijkstra(max_distance, number_of_targets, 1000, data, node); } else { - _Dijkstra(maxDistance, numTargets, 2000, data, node); + Dijkstra(max_distance, number_of_targets, 2000, data, node); } - for (_DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges(node), - endOutEdges = _graph->EndEdges(node); - outEdge != endOutEdges; - ++outEdge) + for (auto out_edge = contractor_graph->BeginEdges(node), + endOutEdges = contractor_graph->EndEdges(node); + out_edge != endOutEdges; + ++out_edge) { - const ContractorEdgeData &outData = _graph->GetEdgeData(outEdge); - if (!outData.forward) + const ContractorEdgeData &out_data = contractor_graph->GetEdgeData(out_edge); + if (!out_data.forward) { continue; } - const NodeID target = _graph->GetTarget(outEdge); - const int pathDistance = inData.distance + outData.distance; + const NodeID target = contractor_graph->GetTarget(out_edge); + const int path_distance = in_data.distance + out_data.distance; const int distance = heap.GetKey(target); - if (pathDistance < distance) + if (path_distance < distance) { - if (Simulate) + if (RUNSIMULATION) { - assert(stats != NULL); - stats->edgesAdded += 2; - stats->originalEdgesAdded += - 2 * (outData.originalEdges + inData.originalEdges); + BOOST_ASSERT(stats != NULL); + stats->edges_added_count += 2; + stats->original_edges_added_count += + 2 * (out_data.originalEdges + in_data.originalEdges); } else { - _ContractorEdge newEdge; - newEdge.source = source; - newEdge.target = target; - newEdge.data = - ContractorEdgeData(pathDistance, - outData.originalEdges + inData.originalEdges, - node /*, 0, inData.turnInstruction*/, + ContractorEdge new_edge; + new_edge.source = source; + new_edge.target = target; + new_edge.data = + ContractorEdgeData(path_distance, + out_data.originalEdges + in_data.originalEdges, + node /*, 0, in_data.turnInstruction*/, true, true, false); ; - insertedEdges.push_back(newEdge); - std::swap(newEdge.source, newEdge.target); - newEdge.data.forward = false; - newEdge.data.backward = true; - insertedEdges.push_back(newEdge); + inserted_edges.push_back(new_edge); + std::swap(new_edge.source, new_edge.target); + new_edge.data.forward = false; + new_edge.data.backward = true; + inserted_edges.push_back(new_edge); } } } } - if (!Simulate) + if (!RUNSIMULATION) { - for (int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; ++i) + int iend = inserted_edges.size(); + for (int i = inserted_edges_size; i < iend; ++i) { bool found = false; for (int other = i + 1; other < iend; ++other) { - if (insertedEdges[other].source != insertedEdges[i].source) + if (inserted_edges[other].source != inserted_edges[i].source) + { continue; - if (insertedEdges[other].target != insertedEdges[i].target) + } + if (inserted_edges[other].target != inserted_edges[i].target) + { continue; - if (insertedEdges[other].data.distance != insertedEdges[i].data.distance) + } + if (inserted_edges[other].data.distance != inserted_edges[i].data.distance) + { continue; - if (insertedEdges[other].data.shortcut != insertedEdges[i].data.shortcut) + } + if (inserted_edges[other].data.shortcut != inserted_edges[i].data.shortcut) + { continue; - insertedEdges[other].data.forward |= insertedEdges[i].data.forward; - insertedEdges[other].data.backward |= insertedEdges[i].data.backward; + } + inserted_edges[other].data.forward |= inserted_edges[i].data.forward; + inserted_edges[other].data.backward |= inserted_edges[i].data.backward; found = true; break; } - if ( !found ) { - insertedEdges[insertedEdgesSize++] = insertedEdges[i]; + if (!found) + { + inserted_edges[inserted_edges_size++] = inserted_edges[i]; } } - insertedEdges.resize(insertedEdgesSize); + inserted_edges.resize(inserted_edges_size); } return true; } - inline void _DeleteIncomingEdges(_ThreadData *data, const NodeID node) + inline void DeleteIncomingEdges(ContractorThreadData *data, const NodeID node) { std::vector &neighbours = data->neighbours; neighbours.clear(); // find all neighbours - for (_DynamicGraph::EdgeIterator e = _graph->BeginEdges(node); e < _graph->EndEdges(node); - ++e) + for (auto e = contractor_graph->BeginEdges(node); e < contractor_graph->EndEdges(node); ++e) { - const NodeID u = _graph->GetTarget(e); + const NodeID u = contractor_graph->GetTarget(e); if (u != node) + { neighbours.push_back(u); + } } // eliminate duplicate entries ( forward + backward edges ) std::sort(neighbours.begin(), neighbours.end()); @@ -829,68 +849,72 @@ class Contractor for (int i = 0, e = (int)neighbours.size(); i < e; ++i) { - _graph->DeleteEdgesTo(neighbours[i], node); + contractor_graph->DeleteEdgesTo(neighbours[i], node); } } - inline bool _UpdateNeighbours(std::vector &priorities, - std::vector<_PriorityData> &nodeData, - _ThreadData *const data, - const NodeID node) + inline bool UpdateNodeNeighbours(std::vector &priorities, + std::vector &node_data, + ContractorThreadData *const data, + const NodeID node) { std::vector &neighbours = data->neighbours; neighbours.clear(); // find all neighbours - for (_DynamicGraph::EdgeIterator e = _graph->BeginEdges(node), - endEdges = _graph->EndEdges(node); - e < endEdges; - ++e) + auto end_edges = contractor_graph->EndEdges(node); + for (auto e = contractor_graph->BeginEdges(node); e < end_edges; ++e) { - const NodeID u = _graph->GetTarget(e); + const NodeID u = contractor_graph->GetTarget(e); if (u == node) + { continue; + } neighbours.push_back(u); - nodeData[u].depth = (std::max)(nodeData[node].depth + 1, nodeData[u].depth); + node_data[u].depth = (std::max)(node_data[node].depth + 1, node_data[u].depth); } // eliminate duplicate entries ( forward + backward edges ) std::sort(neighbours.begin(), neighbours.end()); neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin()); - for(const NodeID u : neighbours) { - priorities[u] = _Evaluate( data, &( nodeData )[u], u ); + // re-evaluate priorities of neighboring nodes + for (const NodeID u : neighbours) + { + priorities[u] = EvaluateNodePriority(data, &(node_data)[u], u); } return true; } - inline bool _IsIndependent( - const std::vector &priorities /*, const std::vector< _PriorityData >& nodeData*/, - _ThreadData *const data, + inline bool IsNodeIndependent( + const std::vector &priorities /*, const std::vector< NodePriorityData >& node_data*/, + ContractorThreadData *const data, NodeID node) const { - const double priority = priorities[node]; + const float priority = priorities[node]; std::vector &neighbours = data->neighbours; neighbours.clear(); - for (_DynamicGraph::EdgeIterator e = _graph->BeginEdges(node); e < _graph->EndEdges(node); - ++e) + for (auto e = contractor_graph->BeginEdges(node); e < contractor_graph->EndEdges(node); ++e) { - const NodeID target = _graph->GetTarget(e); + const NodeID target = contractor_graph->GetTarget(e); if (node == target) + { continue; - const double targetPriority = priorities[target]; - assert(targetPriority >= 0); + } + const float target_priority = priorities[target]; + BOOST_ASSERT(target_priority >= 0); // found a neighbour with lower priority? - if (priority > targetPriority) + if (priority > target_priority) + { return false; + } // tie breaking - if (std::abs(priority - targetPriority) < std::numeric_limits::epsilon() && + if (std::abs(priority - target_priority) < std::numeric_limits::epsilon() && bias(node, target)) { return false; } - // TODO: C++11 copy_if with lambda neighbours.push_back(target); } @@ -898,22 +922,27 @@ class Contractor neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin()); // 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) + auto end_edges = contractor_graph->EndEdges(u); + for (auto e = contractor_graph->BeginEdges(u); e < end_edges; ++e) { - const NodeID target = _graph->GetTarget(e); + const NodeID target = contractor_graph->GetTarget(e); if (node == target) + { continue; - - const double targetPriority = priorities[target]; - assert( targetPriority >= 0 ); - //found a neighbour with lower priority? - if ( priority > targetPriority) + } + const float target_priority = priorities[target]; + assert(target_priority >= 0); + // found a neighbour with lower priority? + if (priority > target_priority) + { return false; - //tie breaking - if ( std::abs(priority - targetPriority) < std::numeric_limits::epsilon() && bias(node, target) ) { + } + // tie breaking + if (std::abs(priority - target_priority) < std::numeric_limits::epsilon() && + bias(node, target)) + { return false; } } @@ -921,28 +950,27 @@ class Contractor return true; } - - /** - * 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 { - unsigned short hasha = fastHash(a); - unsigned short hashb = fastHash(b); + unsigned short hasha = fast_hash(a); + unsigned short hashb = fast_hash(b); // The compiler optimizes that to conditional register flags but without branching // statements! if (hasha != hashb) + { return hasha < hashb; + } return a < b; } - std::shared_ptr<_DynamicGraph> _graph; - std::vector<_DynamicGraph::InputEdge> contractedEdges; + std::shared_ptr contractor_graph; + std::vector contracted_edge_list; unsigned edge_storage_slot; uint64_t temp_edge_counter; - std::vector oldNodeIDFromNewNodeIDMap; - XORFastHash fastHash; + std::vector orig_node_id_to_new_id_map; + XORFastHash fast_hash; }; -#endif // CONTRACTOR_H_INCLUDED +#endif // CONTRACTOR_H diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index b138a9c8a..5c4f62a94 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -26,16 +26,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "EdgeBasedGraphFactory.h" +#include "../Algorithms/BFSComponentExplorer.h" +#include "../DataStructures/Percent.h" #include "../Util/ComputeAngle.h" +#include "../Util/LuaUtil.h" +#include "../Util/SimpleLogger.h" #include "../Util/TimingUtil.h" -#include "BFSComponentExplorer.h" #include -#include #include -#include -#include +#include EdgeBasedGraphFactory::EdgeBasedGraphFactory( const std::shared_ptr &node_based_graph, @@ -52,7 +53,6 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( // insert into unordered sets for fast lookup m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end()); - m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end()); } @@ -65,7 +65,7 @@ void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector &nodes) { #ifndef NDEBUG - BOOST_FOREACH (const EdgeBasedNode &node, m_edge_based_node_list) + for (const EdgeBasedNode &node : m_edge_based_node_list) { BOOST_ASSERT(m_node_info_list.at(node.u).lat != INT_MAX); @@ -77,10 +77,8 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector &nodes) nodes.swap(m_edge_based_node_list); } -void EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeIterator u, - NodeIterator v, - EdgeIterator e1, - bool belongs_to_tiny_cc) +void +EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool belongs_to_tiny_cc) { // merge edges together into one EdgeBasedNode BOOST_ASSERT(u != SPECIAL_NODEID); @@ -179,19 +177,18 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeIterator u, BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_start_coordinate_id); // build edges - m_edge_based_node_list.emplace_back( - EdgeBasedNode(forward_data.edgeBasedNodeID, - reverse_data.edgeBasedNodeID, - current_edge_start_coordinate_id, - current_edge_target_coordinate_id, - forward_data.nameID, - forward_geometry[i].second, - reverse_geometry[i].second, - forward_dist_prefix_sum[i], - reverse_dist_prefix_sum[i], - m_geometry_compressor.GetPositionForID(e1), - i, - belongs_to_tiny_cc)); + m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID, + reverse_data.edgeBasedNodeID, + current_edge_start_coordinate_id, + current_edge_target_coordinate_id, + forward_data.nameID, + forward_geometry[i].second, + reverse_geometry[i].second, + forward_dist_prefix_sum[i], + reverse_dist_prefix_sum[i], + m_geometry_compressor.GetPositionForID(e1), + i, + belongs_to_tiny_cc); current_edge_start_coordinate_id = current_edge_target_coordinate_id; BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed()); @@ -278,10 +275,10 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename, m_geometry_compressor.SerializeInternalVector(geometry_filename); SimpleLogger().Write() << "Timing statistics for edge-expanded graph:"; - SimpleLogger().Write() << "Geometry compression: " << TIMER_SEC(geometry) << "s"; - SimpleLogger().Write() << "Renumbering edges: " << TIMER_SEC(renumber) << "s"; - SimpleLogger().Write() << "Generating nodes: " << TIMER_SEC(generate_nodes) << "s"; - SimpleLogger().Write() << "Generating edges: " << TIMER_SEC(generate_edges) << "s"; + SimpleLogger().Write() << "Geometry compression: " << TIMER_MSEC(geometry)*0.001 << "s"; + SimpleLogger().Write() << "Renumbering edges: " << TIMER_MSEC(renumber)*0.001 << "s"; + SimpleLogger().Write() << "Generating nodes: " << TIMER_MSEC(generate_nodes)*0.001 << "s"; + SimpleLogger().Write() << "Generating edges: " << TIMER_MSEC(generate_edges)*0.001 << "s"; } void EdgeBasedGraphFactory::CompressGeometry() @@ -312,26 +309,26 @@ void EdgeBasedGraphFactory::CompressGeometry() 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 EdgeID forward_e2 = m_node_based_graph->BeginEdges(v) + reverse_edge_order; BOOST_ASSERT(SPECIAL_EDGEID != forward_e2); - const EdgeIterator reverse_e2 = m_node_based_graph->BeginEdges(v) + 1 - reverse_edge_order; + const EdgeID reverse_e2 = m_node_based_graph->BeginEdges(v) + 1 - reverse_edge_order; BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2); const EdgeData &fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2); const EdgeData &rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2); - const NodeIterator w = m_node_based_graph->GetTarget(forward_e2); + const NodeID w = m_node_based_graph->GetTarget(forward_e2); BOOST_ASSERT(SPECIAL_NODEID != w); BOOST_ASSERT(v != w); - const NodeIterator u = m_node_based_graph->GetTarget(reverse_e2); + const NodeID u = m_node_based_graph->GetTarget(reverse_e2); BOOST_ASSERT(SPECIAL_NODEID != u); BOOST_ASSERT(u != v); - const EdgeIterator forward_e1 = m_node_based_graph->FindEdge(u, v); + const EdgeID forward_e1 = m_node_based_graph->FindEdge(u, v); BOOST_ASSERT(m_node_based_graph->EndEdges(u) != forward_e1); BOOST_ASSERT(SPECIAL_EDGEID != forward_e1); BOOST_ASSERT(v == m_node_based_graph->GetTarget(forward_e1)); - const EdgeIterator reverse_e1 = m_node_based_graph->FindEdge(w, v); + const EdgeID reverse_e1 = m_node_based_graph->FindEdge(w, v); BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1); BOOST_ASSERT(v == m_node_based_graph->GetTarget(reverse_e1)); @@ -345,7 +342,8 @@ void EdgeBasedGraphFactory::CompressGeometry() } if ( // TODO: rename to IsCompatibleTo - fwd_edge_data1.IsEqualTo(fwd_edge_data2) && rev_edge_data1.IsEqualTo(rev_edge_data2)) + fwd_edge_data1.IsEqualTo(fwd_edge_data2) && + rev_edge_data1.IsEqualTo(rev_edge_data2)) { // Get distances before graph is modified const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance; @@ -426,10 +424,10 @@ void EdgeBasedGraphFactory::CompressGeometry() } } 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() << "Edge compression ratio: " - << new_edge_count / (double)original_number_of_edges; + SimpleLogger().Write() << "Node compression ratio: " << new_node_count / + (double)original_number_of_nodes; + SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count / + (double)original_number_of_edges; } /** @@ -442,7 +440,7 @@ void EdgeBasedGraphFactory::RenumberEdges() for (NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes(); ++current_node) { - for (EdgeIterator current_edge = m_node_based_graph->BeginEdges(current_node); + for (EdgeID current_edge = m_node_based_graph->BeginEdges(current_node); current_edge < m_node_based_graph->EndEdges(current_node); ++current_edge) { @@ -459,7 +457,6 @@ void EdgeBasedGraphFactory::RenumberEdges() BOOST_ASSERT(SPECIAL_NODEID != edge_data.edgeBasedNodeID); } } - m_number_of_edge_based_nodes = numbered_edges_count; } @@ -476,14 +473,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes() component_explorer.run(); - SimpleLogger().Write() << "identified: " << component_explorer.getNumberOfComponents() + SimpleLogger().Write() << "identified: " << component_explorer.GetNumberOfComponents() << " many components"; SimpleLogger().Write() << "generating edge-expanded nodes"; Percent p(m_node_based_graph->GetNumberOfNodes()); // loop over all edges and generate new set of nodes - for (NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u) + for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u) { BOOST_ASSERT(u != SPECIAL_NODEID); BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes()); @@ -513,8 +510,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes() // Note: edges that end on barrier nodes or on a turn restriction // may actually be in two distinct components. We choose the smallest - const unsigned size_of_component = std::min(component_explorer.getComponentSize(u), - component_explorer.getComponentSize(v)); + const unsigned size_of_component = std::min(component_explorer.GetComponentSize(u), + component_explorer.GetComponentSize(v)); const bool component_is_tiny = (size_of_component < 1000); InsertEdgeBasedNode(u, v, e1, component_is_tiny); @@ -555,10 +552,10 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg Percent p(m_node_based_graph->GetNumberOfNodes()); - for (NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u) + for (NodeID 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); + for (EdgeID e1 = m_node_based_graph->BeginEdges(u), + last_edge_u = m_node_based_graph->EndEdges(u); e1 < last_edge_u; ++e1) { @@ -568,13 +565,13 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg } ++node_based_edge_counter; - const NodeIterator v = m_node_based_graph->GetTarget(e1); + const NodeID v = m_node_based_graph->GetTarget(e1); 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()); - for (EdgeIterator e2 = m_node_based_graph->BeginEdges(v), - last_edge_v = m_node_based_graph->EndEdges(v); + for (EdgeID e2 = m_node_based_graph->BeginEdges(v), + last_edge_v = m_node_based_graph->EndEdges(v); e2 < last_edge_v; ++e2) { @@ -582,7 +579,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg { continue; } - const NodeIterator w = m_node_based_graph->GetTarget(e2); + const NodeID w = m_node_based_graph->GetTarget(e2); if ((to_node_of_only_restriction != SPECIAL_NODEID) && (w != to_node_of_only_restriction)) @@ -648,11 +645,11 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg ++compressed; } - original_edge_data_vector.push_back(OriginalEdgeData( + original_edge_data_vector.emplace_back( (edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v), edge_data1.nameID, turn_instruction, - edge_is_compressed)); + edge_is_compressed); ++original_edges_counter; @@ -706,10 +703,7 @@ int EdgeBasedGraphFactory::GetTurnPenalty(const NodeID u, // call lua profile to compute turn penalty return luabind::call_function(lua_state, "turn_function", 180. - angle); } - catch (const luabind::error &er) - { - SimpleLogger().Write(logWARNING) << er.what(); - } + catch (const luabind::error &er) { SimpleLogger().Write(logWARNING) << er.what(); } } return 0; } @@ -722,8 +716,8 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID return TurnInstruction::UTurn; } - const EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v); - const EdgeIterator edge2 = m_node_based_graph->FindEdge(v, w); + const EdgeID edge1 = m_node_based_graph->FindEdge(u, v); + const EdgeID edge2 = m_node_based_graph->FindEdge(v, w); const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1); const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2); diff --git a/Contractor/EdgeBasedGraphFactory.h b/Contractor/EdgeBasedGraphFactory.h index 7fdb21e84..5292fc2b3 100644 --- a/Contractor/EdgeBasedGraphFactory.h +++ b/Contractor/EdgeBasedGraphFactory.h @@ -34,32 +34,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DynamicGraph.h" #include "../DataStructures/EdgeBasedNode.h" -#include "../DataStructures/HashTable.h" #include "../DataStructures/OriginalEdgeData.h" -#include "../DataStructures/Percent.h" -#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryNode.h" #include "../DataStructures/TurnInstructions.h" #include "../DataStructures/Restriction.h" #include "../DataStructures/NodeBasedGraph.h" #include "../DataStructures/RestrictionMap.h" -#include "../Util/LuaUtil.h" -#include "../Util/SimpleLogger.h" - #include "GeometryCompressor.h" -#include #include #include #include #include +#include #include +#include #include -class EdgeBasedGraphFactory : boost::noncopyable +struct lua_State; + +class EdgeBasedGraphFactory { public: + EdgeBasedGraphFactory() = delete; + EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete; + struct SpeedProfileProperties; explicit EdgeBasedGraphFactory(const std::shared_ptr &node_based_graph, @@ -71,7 +71,7 @@ class EdgeBasedGraphFactory : boost::noncopyable void Run(const std::string &original_edge_data_filename, const std::string &geometry_filename, - lua_State *myLuaState); + lua_State *lua_state); void GetEdgeBasedEdges(DeallocatingVector &edges); @@ -79,7 +79,7 @@ class EdgeBasedGraphFactory : boost::noncopyable TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const; - int GetTurnPenalty(const NodeID u, const NodeID v, const NodeID w, lua_State *myLuaState) const; + int GetTurnPenalty(const NodeID u, const NodeID v, const NodeID w, lua_State *lua_state) const; unsigned GetNumberOfEdgeBasedNodes() const; @@ -96,8 +96,6 @@ class EdgeBasedGraphFactory : boost::noncopyable } speed_profile; private: - typedef NodeBasedDynamicGraph::NodeIterator NodeIterator; - typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator; typedef NodeBasedDynamicGraph::EdgeData EdgeData; unsigned m_number_of_edge_based_nodes; @@ -120,10 +118,7 @@ class EdgeBasedGraphFactory : boost::noncopyable void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename, lua_State *lua_state); - void InsertEdgeBasedNode(NodeBasedDynamicGraph::NodeIterator u, - NodeBasedDynamicGraph::NodeIterator v, - NodeBasedDynamicGraph::EdgeIterator e1, - bool belongsToTinyComponent); + void InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool belongsToTinyComponent); void FlushVectorToStream(std::ofstream &edge_data_file, std::vector &original_edge_data_vector) const; diff --git a/Contractor/GeometryCompressor.cpp b/Contractor/GeometryCompressor.cpp index 8a9ba6f5d..da6d0f237 100644 --- a/Contractor/GeometryCompressor.cpp +++ b/Contractor/GeometryCompressor.cpp @@ -48,7 +48,7 @@ void GeometryCompressor::IncreaseFreeList() m_compressed_geometries.resize(m_compressed_geometries.size() + 100); for (unsigned i = 100; i > 0; --i) { - m_free_list.push_back(current_free_list_maximum); + m_free_list.emplace_back(current_free_list_maximum); ++current_free_list_maximum; } } @@ -60,8 +60,7 @@ bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const { - boost::unordered_map::const_iterator map_iterator; - map_iterator = m_edge_id_to_list_index_map.find(edge_id); + auto map_iterator = m_edge_id_to_list_index_map.find(edge_id); BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end()); BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size()); return map_iterator->second; @@ -77,7 +76,7 @@ void GeometryCompressor::SerializeInternalVector(const std::string &path) const // write indices array unsigned prefix_sum_of_list_indices = 0; - for (auto &elem : m_compressed_geometries) + for (const auto &elem : m_compressed_geometries) { geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned)); @@ -146,8 +145,7 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1, m_free_list.pop_back(); } - const boost::unordered_map::const_iterator iter = - m_edge_id_to_list_index_map.find(edge_id_1); + const auto iter = m_edge_id_to_list_index_map.find(edge_id_1); BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end()); const unsigned edge_bucket_id1 = iter->second; BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1)); @@ -157,7 +155,7 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1, if (edge_bucket_list1.empty()) { - edge_bucket_list1.push_back(std::make_pair(via_node_id, weight1)); + edge_bucket_list1.emplace_back(via_node_id, weight1); } BOOST_ASSERT(0 < edge_bucket_list1.size()); @@ -182,13 +180,13 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1, m_edge_id_to_list_index_map.find(edge_id_2)); edge_bucket_list2.clear(); BOOST_ASSERT(0 == edge_bucket_list2.size()); - m_free_list.push_back(list_to_remove_index); + m_free_list.emplace_back(list_to_remove_index); BOOST_ASSERT(list_to_remove_index == m_free_list.back()); } else { // we are certain that the second edge is atomic. - edge_bucket_list1.push_back(std::make_pair(target_node_id, weight2)); + edge_bucket_list1.emplace_back(target_node_id, weight2); } } diff --git a/Contractor/TemporaryStorage.cpp b/Contractor/TemporaryStorage.cpp index 582d7e66f..5301f11b4 100644 --- a/Contractor/TemporaryStorage.cpp +++ b/Contractor/TemporaryStorage.cpp @@ -27,6 +27,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "TemporaryStorage.h" +StreamData::StreamData() + : write_mode(true), temp_path(boost::filesystem::unique_path(temp_directory.append( + 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(std::make_shared()) +{ + if (temp_file->fail()) + { + throw OSRMException("temporary file could not be created"); + } +} + TemporaryStorage::TemporaryStorage() { temp_directory = boost::filesystem::temp_directory_path(); } TemporaryStorage &TemporaryStorage::GetInstance() @@ -50,14 +63,8 @@ void TemporaryStorage::RemoveAll() int TemporaryStorage::AllocateSlot() { boost::mutex::scoped_lock lock(mutex); - try - { - stream_data_list.push_back(StreamData()); - } - catch (boost::filesystem::filesystem_error &e) - { - Abort(e); - } + try { stream_data_list.push_back(StreamData()); } + catch (boost::filesystem::filesystem_error &e) { Abort(e); } CheckIfTemporaryDeviceFull(); return stream_data_list.size() - 1; } @@ -79,10 +86,7 @@ void TemporaryStorage::DeallocateSlot(const int slot_id) boost::filesystem::remove(data.temp_path); } - catch (boost::filesystem::filesystem_error &e) - { - Abort(e); - } + catch (boost::filesystem::filesystem_error &e) { Abort(e); } } void TemporaryStorage::WriteToSlot(const int slot_id, char *pointer, const std::size_t size) @@ -103,10 +107,7 @@ void TemporaryStorage::WriteToSlot(const int slot_id, char *pointer, const std:: } data.buffer.insert(data.buffer.end(), pointer, pointer + size); } - catch (boost::filesystem::filesystem_error &e) - { - Abort(e); - } + catch (boost::filesystem::filesystem_error &e) { Abort(e); } } void TemporaryStorage::ReadFromSlot(const int slot_id, char *pointer, const std::size_t size) { @@ -125,10 +126,7 @@ void TemporaryStorage::ReadFromSlot(const int slot_id, char *pointer, const std: BOOST_ASSERT(!data.write_mode); data.temp_file->read(pointer, size); } - catch (boost::filesystem::filesystem_error &e) - { - Abort(e); - } + catch (boost::filesystem::filesystem_error &e) { Abort(e); } } uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice() @@ -140,10 +138,7 @@ uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice() boost::filesystem::space_info s = boost::filesystem::space(p); value = s.free; } - catch (boost::filesystem::filesystem_error &e) - { - Abort(e); - } + catch (boost::filesystem::filesystem_error &e) { Abort(e); } return value; } @@ -166,10 +161,7 @@ boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id) boost::mutex::scoped_lock lock(*data.readWriteMutex); position = data.temp_file->tellp(); } - catch (boost::filesystem::filesystem_error &e) - { - Abort(e); - } + catch (boost::filesystem::filesystem_error &e) { Abort(e); } return position; } diff --git a/Contractor/TemporaryStorage.h b/Contractor/TemporaryStorage.h index 5864cc684..ca8598b6d 100644 --- a/Contractor/TemporaryStorage.h +++ b/Contractor/TemporaryStorage.h @@ -42,15 +42,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include -/** - * This class implements a singleton file storage for temporary data. - * temporary slots can be accessed by other objects through an int - * On deallocation every slot gets deallocated - * - * Access is sequential, which means, that there is no random access - * -> Data is written in first phase and reread in second. - */ +struct StreamData +{ + bool write_mode; + boost::filesystem::path temp_path; + std::shared_ptr temp_file; + std::shared_ptr readWriteMutex; + std::vector buffer; + + StreamData(); +}; + +// This class implements a singleton file storage for temporary data. +// temporary slots can be accessed by other objects through an int +// On deallocation every slot gets deallocated +// +// Access is sequential, which means, that there is no random access +// -> Data is written in first phase and reread in second. static boost::filesystem::path temp_directory; static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%"); @@ -78,27 +88,6 @@ class TemporaryStorage void Abort(const boost::filesystem::filesystem_error &e); void CheckIfTemporaryDeviceFull(); - struct StreamData - { - bool write_mode; - boost::filesystem::path temp_path; - std::shared_ptr temp_file; - std::shared_ptr readWriteMutex; - std::vector buffer; - - StreamData() - : write_mode(true), temp_path(boost::filesystem::unique_path(temp_directory.append( - 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(std::make_shared()) - { - if (temp_file->fail()) - { - throw OSRMException("temporary file could not be created"); - } - } - }; // vector of file streams that is used to store temporary data boost::mutex mutex; std::vector stream_data_list;