00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef BUCKETS_H
00012 #define BUCKETS_H
00013
00014 #include <vector>
00015
00016 #include "../stxxl/containers/stack.h"
00017 #include "../data_structures/sparingStack.h"
00018
00019 #include "../data_structures/edgeVector.h"
00020 #include "../data_structures/mst.h"
00021
00022
00035 template <NodeCount nodesPerBucket = 1>
00036 class Buckets
00037 {
00038 public:
00039 typedef int BucketID;
00040
00041 private:
00043 typedef stxxl::STACK_GENERATOR<RelabeledEdge,
00044 stxxl::external,
00045 stxxl::grow_shrink2,
00046 DS_EXT_PAGE_SIZE,
00047 DS_EXT_BLOCK_SIZE>::result EdgesOfSeveralNodes;
00048
00050 typedef REWS_SparingStack<DS_INT_EDGES_PER_BLOCK, DS_INT_NO_OF_BLOCKS> EdgesOfOneNode;
00051
00053 typedef CommonPoolOfBlocks<RelabeledEdgeWithoutSource,
00054 DS_INT_EDGES_PER_BLOCK,
00055 DS_INT_NO_OF_BLOCKS> PoolEdgesOfOneNode;
00056
00057 public:
00059 static BucketID noOfExtBuckets(NodeCount noOfNodes, NodeCount noOfNodesInIntMem);
00060
00061
00070 Buckets(EdgeVector<Edge> &graph, MST &result,
00071 BucketID noOfBuckets, NodeCount noOfNodesInIntMem)
00072 : _graph( graph ), _result( result ), _extBuckets( noOfBuckets-1 ),
00073 _noOfNodesInIntMem( noOfNodesInIntMem ),
00074 _prefetchPool( DS_EXT_PREFETCH_POOL ), _writePool( DS_EXT_WRITE_POOL )
00075 {
00076 initBuckets();
00077 reduceNodes();
00078 }
00079
00084 InternalMemoryBucket* getIntMemBucket() {return _firstExtBucket;}
00085
00091 void add(const RelabeledEdge &edge);
00092
00093 private:
00095 EdgeVector<Edge> &_graph;
00096
00098 MST &_result;
00099
00101 NodeCount _noOfNodesInIntMem;
00102
00107 InternalMemoryBucket *_firstExtBucket;
00108
00113 std::vector<EdgesOfSeveralNodes*> _extBuckets;
00114
00116 stxxl::prefetch_pool<EdgesOfSeveralNodes::block_type> _prefetchPool;
00117
00119 stxxl::write_pool<EdgesOfSeveralNodes::block_type> _writePool;
00120
00125 EdgesOfOneNode _intBuckets[nodesPerBucket];
00126
00131 NodeID _firstNodeIDofCurrentBucket;
00132
00137 void initBuckets();
00138
00143 void reduceNodes();
00144
00152 BucketID bucketID(NodeID nodeID) const;
00153
00155 void addToExternalBucket(const RelabeledEdge &edge);
00156
00158 void addToExternalBucket(const RelabeledEdge &edge, BucketID newBucketID);
00159 };
00160
00161
00169 template <NodeCount nodesPerBucket>
00170 inline Buckets<nodesPerBucket>::BucketID Buckets<nodesPerBucket>::bucketID(NodeID nodeID)
00171 const
00172 {
00173 if (nodeID < _noOfNodesInIntMem) return -1;
00174 return (nodeID - _noOfNodesInIntMem) / nodesPerBucket;
00175 }
00176
00178 template <NodeCount nodesPerBucket>
00179 inline void Buckets<nodesPerBucket>::addToExternalBucket(const RelabeledEdge &edge)
00180 {
00181 if ( edge.isSelfLoop() ) return;
00182 addToExternalBucket( edge, bucketID(edge.source()) );
00183 }
00184
00186 template <NodeCount nodesPerBucket>
00187 inline void Buckets<nodesPerBucket>::addToExternalBucket(const RelabeledEdge &edge,
00188 BucketID newBucketID)
00189 {
00190 if (newBucketID == -1) {
00191
00192 _firstExtBucket->push_back( edge );
00193 }
00194 else {
00195 _extBuckets[newBucketID]->push( edge );
00196 }
00197 }
00198
00204 template <NodeCount nodesPerBucket>
00205 inline void Buckets<nodesPerBucket>::add(const RelabeledEdge &edge)
00206 {
00207 if (edge.source() >= _firstNodeIDofCurrentBucket) {
00208
00209
00210
00211 _intBuckets[edge.source() - _firstNodeIDofCurrentBucket]
00212 .push(edge);
00213 }
00214 else {
00215
00216
00217 addToExternalBucket( edge, bucketID(edge.source()) );
00218 }
00219 }
00220
00221 #endif // BUCKETS_H