00001 /**************************************************** 00002 * Bachelor Project: * 00003 * External Memory Minimum Spanning Trees * 00004 * by Dominik Schultes <mail@dominik-schultes.de> * 00005 * * 00006 * duplicatesRemover.h * 00007 * * 00008 * May 20, 2003 * 00009 ****************************************************/ 00010 00011 #ifndef DUPLICATESREMOVER_H 00012 #define DUPLICATESREMOVER_H 00013 00022 template <typename SuperContainer> 00023 class DuplicatesRemover 00024 { 00025 public: 00035 DuplicatesRemover(SuperContainer *superContainer) 00036 : _superContainer( superContainer ), _size( 0 ) 00037 {} 00038 00045 void insert(const RelabeledEdgeWithoutSource &edge, NodeID source) { 00046 int index = find( edge.target() ); 00047 if ( empty(index) ) { 00048 // There is NO edge with the same target node. 00049 if (_size == _maxSize) { 00050 // The container is full, so the current edge has to be 00051 // output directly. 00052 _superContainer->add( RelabeledEdge(edge, source) ); 00053 } 00054 else { 00055 // Add the edge to the container 00056 _hashMap[index] = HashMapElement( edge, _size ); 00057 _edges[_size++] = edge; 00058 } 00059 } 00060 else { 00061 // There is another edge with the same target node. 00062 // So this a duplicate ! 00063 DS_LOGGING2( logging.duplicates().increase() ); 00064 if (edge < _hashMap[index].first) { 00065 // The current edge has a lower weight than the existing edge. 00066 // Therefore the existing edge is replaced. 00067 _edges[ _hashMap[index].second ] = edge; 00068 _hashMap[index].first = edge; 00069 } 00070 } 00071 } 00072 00074 void clear(NodeID source) { 00075 while ( _size > 0 ) { 00076 clearLocal( _edges[--_size].target() ); 00077 _superContainer->add( RelabeledEdge(_edges[_size], source) ); 00078 } 00079 } 00080 00081 private: 00083 static const EdgeCount _maxSize = 1024; 00084 00086 static const EdgeCount _hashMapSize = 2 * _maxSize; 00087 00093 typedef std::pair<RelabeledEdgeWithoutSource, int> HashMapElement; 00094 00100 RelabeledEdgeWithoutSource _edges[_maxSize]; 00101 00103 HashMapElement _hashMap[_hashMapSize]; 00104 00106 EdgeCount _size; 00107 00115 SuperContainer *_superContainer; 00116 00118 int hashFunction(NodeID x) const { 00119 return x % _hashMapSize; 00120 } 00121 00127 int find(NodeID x) const { 00128 int i = hashFunction(x); 00129 while ((_hashMap[i].first.target() != x) && ( ! empty(i) )) 00130 i = (i+1) % _hashMapSize; 00131 return i; 00132 } 00133 00138 void clearLocal(NodeID x) { 00139 int i = hashFunction(x); 00140 while ( ! empty(i) ) { 00141 _hashMap[i].first = RelabeledEdgeWithoutSource(); 00142 i = (i+1) % _hashMapSize; 00143 } 00144 } 00145 00147 bool empty(int index) const { 00148 if ( (_hashMap[index].first.originalSource() == 0) && 00149 (_hashMap[index].first.originalTarget() == 0) ) return true; 00150 return false; 00151 } 00152 00153 }; 00154 00155 #endif // DUPLICATESREMOVER_H