graph is built in-place, so memory peak usage is halved.

This commit is contained in:
DennisOSRM 2011-12-15 17:48:00 +01:00
parent a098e38c5a
commit ad77d6cfec
4 changed files with 112 additions and 28 deletions

View File

@ -49,12 +49,18 @@ public:
}
};
struct _StrNode {
//index of the first edge
EdgeIterator firstEdge;
};
struct _StrEdge {
NodeID target;
EdgeDataT data;
};
StaticGraph( const int nodes, std::vector< InputEdge > &graph ) {
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( graph.begin(), graph.end() );
#else
std::sort( graph.begin(), graph.end() );
#endif
_numNodes = nodes;
_numEdges = ( EdgeIterator ) graph.size();
_nodes.resize( _numNodes + 1);
@ -79,6 +85,14 @@ public:
}
}
StaticGraph( std::vector<_StrNode> & nodes, std::vector<_StrEdge> & edges) {
_numNodes = nodes.size();
_numEdges = edges.size();
_nodes.swap(nodes);
_edges.swap(edges);
}
unsigned GetNumberOfNodes() const {
return _numNodes;
}
@ -142,16 +156,6 @@ public:
private:
struct _StrNode {
//index of the first edge
EdgeIterator firstEdge;
};
struct _StrEdge {
NodeID target;
EdgeDataT data;
};
NodeIterator _numNodes;
EdgeIterator _numEdges;

View File

@ -41,10 +41,14 @@ struct ObjectsForQueryStruct {
std::cout << "[objects] loading query data structures ..." << std::flush;
ifstream hsgrInStream(hsgrPath.c_str(), ios::binary);
//Deserialize road network graph
std::vector< InputEdge> edgeList;
const int n = readHSGRFromStream(hsgrInStream, edgeList);
graph = new QueryGraph(n, edgeList);
std::vector< InputEdge >().swap( edgeList ); //free memory
std::vector< QueryGraph::_StrNode> nodeList;
std::vector< QueryGraph::_StrEdge> edgeList;
const int n = readHSGRFromStream(hsgrInStream, nodeList, edgeList);
graph = new QueryGraph(nodeList, edgeList);
INFO("Graph has " << graph->GetNumberOfNodes() << " nodes");
INFO("Graph has " << graph->GetNumberOfEdges() << " edges");
//Init nearest neighbor data structure
ifstream nodesInStream(nodesPath.c_str(), ios::binary);

View File

@ -354,6 +354,31 @@ NodeID readDDSGGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
return numberOfNodes;
}
template<typename NodeT, typename EdgeT>
unsigned readHSGRFromStream(istream &in, vector<NodeT>& nodeList, vector<EdgeT> & edgeList) {
unsigned numberOfNodes = 0;
in.read((char*) & numberOfNodes, sizeof(unsigned));
INFO("Loading " << numberOfNodes << " nodes");
nodeList.resize(numberOfNodes);
NodeT currentNode;
for(unsigned nodeCounter = 0; nodeCounter < numberOfNodes; ++nodeCounter ) {
in.read((char*) &currentNode, sizeof(NodeT));
nodeList[nodeCounter] = currentNode;
}
unsigned numberOfEdges = 0;
in.read((char*) &numberOfEdges, sizeof(unsigned));
INFO("Loading " << numberOfEdges << " edges");
edgeList.resize(numberOfEdges);
EdgeT currentEdge;
for(unsigned edgeCounter = 0; edgeCounter < numberOfEdges; ++edgeCounter) {
in.read((char*) &currentEdge, sizeof(EdgeT));
edgeList[edgeCounter] = currentEdge;
}
return numberOfNodes;
}
template<typename EdgeT>
unsigned readHSGRFromStream(istream &in, vector<EdgeT> & edgeList) {
NodeID numberOfNodes = 0;

View File

@ -160,18 +160,69 @@ int main (int argc, char *argv[]) {
cleanup->GetData(cleanedEdgeList);
DELETE( cleanup );
INFO("Serializing edges ");
INFO("Building Node Array");
// std::sort( graph.begin(), graph.end() );
sort(cleanedEdgeList.begin(), cleanedEdgeList.end());
unsigned numberOfNodes = 0;
unsigned numberOfEdges = cleanedEdgeList.size();
INFO("Serializing compacted graph");
ofstream edgeOutFile(edgeOut, ios::binary);
Percent p(cleanedEdgeList.size());
BOOST_FOREACH(InputEdge & edge, cleanedEdgeList) {
p.printIncrement();
edgeOutFile.write((char *)&(edge.data), sizeof(EdgeData));
edgeOutFile.write((char *)&(edge.source), sizeof(NodeID));
edgeOutFile.write((char *)&(edge.target), sizeof(NodeID));
if(edge.source > numberOfNodes) {
numberOfNodes = edge.source;
}
if(edge.target > numberOfNodes) {
numberOfNodes = edge.target;
}
}
// _numNodes = nodes;
// _numEdges = ( EdgeIterator ) graph.size();
numberOfNodes+=1;
std::vector< StaticGraph<EdgeData>::_StrNode > _nodes;
// std::vector< StaticGraph<EdgeData>::_StrEdge > _edges;
_nodes.resize( numberOfNodes);
StaticGraph<EdgeData>::EdgeIterator edge = 0;
StaticGraph<EdgeData>::EdgeIterator position = 0;
for ( StaticGraph<EdgeData>::NodeIterator node = 0; node <= numberOfNodes; ++node ) {
StaticGraph<EdgeData>::EdgeIterator lastEdge = edge;
while ( edge < numberOfEdges && cleanedEdgeList[edge].source == node )
++edge;
_nodes[node].firstEdge = position; //=edge
position += edge - lastEdge; //remove
}
//Serialize numberOfNodes, nodes
edgeOutFile.write((char*) &numberOfNodes, sizeof(unsigned));
edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes));
//Serialize number of Edges
edgeOutFile.write((char*) &position, sizeof(unsigned));
edge = 0;
int counter = 0;
StaticGraph<EdgeData>::_StrEdge currentEdge;
for ( StaticGraph<EdgeData>::NodeIterator node = 0; node < numberOfNodes; ++node ) {
for ( StaticGraph<EdgeData>::EdgeIterator i = _nodes[node].firstEdge, e = _nodes[node+1].firstEdge; i != e; ++i ) {
currentEdge.target = cleanedEdgeList[edge].target;
currentEdge.data = cleanedEdgeList[edge].data;
if(currentEdge.data.distance <= 0) {
INFO("Edge: " << i << ",source: " << cleanedEdgeList[edge].source << ", target: " << cleanedEdgeList[edge].target << ", dist: " << currentEdge.data.distance);
ERR("Failed at edges of node " << node << " of " << numberOfNodes);
}
//Serialize edges
edgeOutFile.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
++edge;
++counter;
}
}
INFO("Written " << counter << " edges, expected " << position);
edgeOutFile.close();
cleanedEdgeList.clear();
_nodes.clear();
INFO("finished preprocessing");
return 0;
}