This is a large update that brings many internal and architectural changes. The most obvious change to the user is the presence of configuration files for extractLargeNetwork and routed. Optimistically speaking, it should not break anything. Thanks to rskr for support patches and suggestions.

This commit is contained in:
Dennis Luxen
2011-01-09 21:42:27 +00:00
parent f45af2ba72
commit bfd2a8aee2
34 changed files with 2214 additions and 1655 deletions
+274
View File
@@ -0,0 +1,274 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef BINARYHEAP_H_INCLUDED
#define BINARYHEAP_H_INCLUDED
//Not compatible with non contiguous node ids
#include <cassert>
#include <vector>
#include <algorithm>
#include <map>
#include <google/dense_hash_map>
#include <google/sparse_hash_map>
template< typename NodeID, typename Key >
class ArrayStorage {
public:
ArrayStorage( size_t size )
: positions( new Key[size] ) {}
~ArrayStorage() {
delete[] positions;
}
Key &operator[]( NodeID node ) {
return positions[node];
}
void Clear() {}
private:
Key* positions;
};
template< typename NodeID, typename Key >
class MapStorage {
public:
MapStorage( size_t size = 0 ) {}
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
std::map< NodeID, Key > nodes;
};
template< typename NodeID, typename Key >
class DenseStorage {
public:
DenseStorage( size_t size = 0 ) { nodes.set_empty_key(UINT_MAX); }
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
google::dense_hash_map< NodeID, Key > nodes;
};
template< typename NodeID, typename Key >
class SparseStorage {
public:
SparseStorage( size_t size = 0 ) { }
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
google::sparse_hash_map< NodeID, Key > nodes;
};
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage< NodeID, Key > >
class BinaryHeap {
private:
BinaryHeap( const BinaryHeap& right );
void operator=( const BinaryHeap& right );
public:
typedef Weight WeightType;
typedef Data DataType;
BinaryHeap( size_t maxID )
: nodeIndex( maxID ) {
Clear();
}
void Clear() {
heap.resize( 1 );
insertedNodes.clear();
heap[0].weight = 0;
nodeIndex.Clear();
}
Key Size() const {
return ( Key )( heap.size() - 1 );
}
void Insert( NodeID node, Weight weight, const Data &data ) {
HeapElement element;
element.index = ( NodeID ) insertedNodes.size();
element.weight = weight;
const Key key = ( Key ) heap.size();
heap.push_back( element );
insertedNodes.push_back( HeapNode( node, key, weight, data ) );
nodeIndex[node] = element.index;
Upheap( key );
CheckHeap();
}
Data& GetData( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
}
Weight& GetKey( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].weight;
}
bool WasRemoved( NodeID node ) {
assert( WasInserted( node ) );
const Key index = nodeIndex[node];
return insertedNodes[index].key == 0;
}
bool WasInserted( NodeID node ) {
const Key index = nodeIndex[node];
if ( index >= ( Key ) insertedNodes.size() )
return false;
return insertedNodes[index].node == node;
}
NodeID Min() const {
assert( heap.size() > 1 );
return insertedNodes[heap[1].index].node;
}
NodeID DeleteMin() {
assert( heap.size() > 1 );
const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1];
heap.pop_back();
if ( heap.size() > 1 )
Downheap( 1 );
insertedNodes[removedIndex].key = 0;
CheckHeap();
return insertedNodes[removedIndex].node;
}
void DeleteAll() {
for ( typename std::vector< HeapElement >::iterator i = heap.begin() + 1, iend = heap.end(); i != iend; ++i )
insertedNodes[i->index].key = 0;
heap.resize( 1 );
heap[0].weight = 0;
}
void DecreaseKey( NodeID node, Weight weight ) {
const Key index = nodeIndex[node];
Key key = insertedNodes[index].key;
assert ( key != 0 );
insertedNodes[index].weight = weight;
heap[key].weight = weight;
Upheap( key );
CheckHeap();
}
private:
class HeapNode {
public:
HeapNode() {
}
HeapNode( NodeID n, Key k, Weight w, Data d )
: node( n ), key( k ), weight( w ), data( d ) {
}
NodeID node;
Key key;
Weight weight;
Data data;
};
struct HeapElement {
Key index;
Weight weight;
};
std::vector< HeapNode > insertedNodes;
std::vector< HeapElement > heap;
IndexStorage nodeIndex;
void Downheap( Key key ) {
const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key << 1;
while ( nextKey < ( Key ) heap.size() ) {
const Key nextKeyOther = nextKey + 1;
if ( ( nextKeyOther < ( Key ) heap.size() ) )
if ( heap[nextKey].weight > heap[nextKeyOther].weight )
nextKey = nextKeyOther;
if ( weight <= heap[nextKey].weight )
break;
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
key = nextKey;
nextKey <<= 1;
}
heap[key].index = droppingIndex;
heap[key].weight = weight;
insertedNodes[droppingIndex].key = key;
}
void Upheap( Key key ) {
const Key risingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) {
assert( nextKey != 0 );
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
key = nextKey;
nextKey >>= 1;
}
heap[key].index = risingIndex;
heap[key].weight = weight;
insertedNodes[risingIndex].key = key;
}
void CheckHeap() {
/*for ( Key i = 2; i < heap.size(); ++i ) {
assert( heap[i].weight >= heap[i >> 1].weight );
}*/
}
};
#endif //#ifndef BINARYHEAP_H_INCLUDED
+14
View File
@@ -37,9 +37,23 @@ public:
void Add(const keyT& key, const valueT& value){
table[key] = value;
}
void Set(const keyT& key, const valueT& value){
table[key] = value;
}
valueT Find(const keyT& key) {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
}
bool Holds(const keyT& key) {
if(table.find(key) == table.end())
return false;
return true;
}
void EraseAll() {
table.clear();
}
private:
MyHashTable table;
};
+7 -15
View File
@@ -60,8 +60,7 @@ static unsigned getFileIndexForLatLon(const int lt, const int ln)
return fileIndex;
}
static unsigned getRAMIndexFromFileIndex(const int fileIndex)
{
static unsigned getRAMIndexFromFileIndex(const int fileIndex) {
unsigned fileLine = fileIndex / 32768;
fileLine = fileLine / 32;
fileLine = fileLine * 1024;
@@ -158,22 +157,17 @@ class NNGrid {
ifstream stream;
};
struct ThreadLookupTable{
HashTable<unsigned, unsigned> table;
};
typedef HashTable<unsigned, unsigned> ThreadLookupTable;
public:
ThreadLookupTable threadLookup;
NNGrid() { ramIndexTable.resize((1024*1024), UINT_MAX); if( WriteAccess) { entries = new stxxl::vector<GridEdgeData>(); }}
NNGrid(const char* rif, const char* iif) {
NNGrid(const char* rif, const char* iif, unsigned numberOfThreads = omp_get_num_procs()) {
ramIndexTable.resize((1024*1024), UINT_MAX);
// indexInFile.open(iif, std::ios::in | std::ios::binary);
ramInFile.open(rif, std::ios::in | std::ios::binary);
cout << "opening grid file for " << omp_get_num_procs() << " threads" << endl;
for(int i = 0; i< omp_get_num_procs(); i++) {
indexFileStreams.push_back(new _ThreadData(iif));
}
@@ -183,19 +177,17 @@ public:
if(ramInFile.is_open()) ramInFile.close();
// if(indexInFile.is_open()) indexInFile.close();
if (WriteAccess)
{
if (WriteAccess) {
delete entries;
}
#pragma omp parallel for
for(int i = 0; i< indexFileStreams.size(); i++) {
delete indexFileStreams[i];
}
threadLookup.EraseAll();
}
void OpenIndexFiles()
{
void OpenIndexFiles() {
assert(ramInFile.is_open());
// assert(indexInFile.is_open());
@@ -513,7 +505,7 @@ private:
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_Edge>& result)
{
// cout << "thread: " << boost::this_thread::get_id() << ", hash: " << boost_thread_id_hash(boost::this_thread::get_id()) << ", id: " << threadLookup.table.Find(boost_thread_id_hash(boost::this_thread::get_id())) << endl;
unsigned threadID = threadLookup.table.Find(boost_thread_id_hash(boost::this_thread::get_id()));
unsigned threadID = threadLookup.Find(boost_thread_id_hash(boost::this_thread::get_id()));
unsigned ramIndex = getRAMIndexFromFileIndex(fileIndex);
unsigned startIndexInFile = ramIndexTable[ramIndex];
// ifstream indexInFile( indexFileStreams[threadID]->stream );
+23 -17
View File
@@ -33,19 +33,24 @@ typedef NNGrid::NNGrid<false> ReadOnlyGrid;
class NodeInformationHelpDesk{
public:
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput) { numberOfNodes = 0; int2ExtNodeMap = new vector<_Coordinate>(); g = new ReadOnlyGrid(ramIndexInput,fileIndexInput); }
~NodeInformationHelpDesk() { delete int2ExtNodeMap; delete g; }
void initNNGrid(ifstream& in)
{
while(!in.eof())
{
NodeInfo b;
in.read((char *)&b, sizeof(b));
int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon));
numberOfNodes++;
}
in.close();
g->OpenIndexFiles();
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput) {
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
int2ExtNodeMap = new vector<_Coordinate>();
numberOfNodes = 0;
}
~NodeInformationHelpDesk() {
delete int2ExtNodeMap;
delete readOnlyGrid;
}
void initNNGrid(ifstream& in) {
while(!in.eof()) {
NodeInfo b;
in.read((char *)&b, sizeof(b));
int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon));
numberOfNodes++;
}
in.close();
readOnlyGrid->OpenIndexFiles();
}
inline int getLatitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lat; }
@@ -53,21 +58,22 @@ public:
inline int getLongitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lon; }
NodeID getNumberOfNodes() const { return numberOfNodes; }
NodeID getNumberOfNodes2() const { return int2ExtNodeMap->size(); }
inline void findNearestNodeCoordForLatLon(const _Coordinate coord, _Coordinate& result) {
result = g->FindNearestPointOnEdge(coord);
result = readOnlyGrid->FindNearestPointOnEdge(coord);
}
inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * phantomNodes) {
g->FindRoutingStarts(start, target, phantomNodes);
readOnlyGrid->FindRoutingStarts(start, target, phantomNodes);
}
inline void RegisterThread(const unsigned k, const unsigned v) {
g->threadLookup.table.Add(k, v);
readOnlyGrid->threadLookup.Add(k, v);
}
private:
vector<_Coordinate> * int2ExtNodeMap;
ReadOnlyGrid * g;
ReadOnlyGrid * readOnlyGrid;
unsigned numberOfNodes;
};