Skip to content

Commit

Permalink
Initial Import.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dennis Luxen committed Jul 9, 2010
1 parent a44a309 commit d4a64d2
Show file tree
Hide file tree
Showing 28 changed files with 5,010 additions and 0 deletions.
7 changes: 7 additions & 0 deletions AUTHORS.TXT
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The following people contributed code to the Open Source Routing Machine:

Christian Vetter
Dennis Luxen

Note:
http server ripped from Boost http example 3
253 changes: 253 additions & 0 deletions Contractor/BinaryHeap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
/*
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>

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 SparseStorage {
public:

SparseStorage( 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, 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;
}

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
Loading

0 comments on commit d4a64d2

Please sign in to comment.