00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef SPARINGSTACK_H
00013 #define SPARINGSTACK_H
00014
00020 template <typename value_type, int elementsPerBlock, int noOfBlocks>
00021 class CommonPoolOfBlocks
00022 {
00023 public:
00027 class Block
00028 {
00029 public:
00031 Block()
00032 : _size( 0 ), _prev( 0 )
00033 {}
00034
00039 void push(const value_type &element) {
00040 _elements[_size++] = element;
00041 }
00042
00047 const value_type & top() const {return _elements[_size-1];}
00048
00053 void pop() {_size--;}
00054
00058 void clear() {_size = 0;}
00059
00061 bool empty() const {return (_size==0);}
00062
00064 bool full() const {return (_size==elementsPerBlock);}
00065
00067 int size() const {return _size;}
00068
00070 const value_type & operator[](int index) const {return _elements[index];}
00071
00073 void setPrevBlock(Block *const prev) {_prev = prev;}
00074
00076 Block * prevBlock() const {return _prev;}
00077
00078 private:
00080 int _size;
00081
00083 Block *_prev;
00084
00086 value_type _elements[elementsPerBlock];
00087 };
00088
00089
00091 CommonPoolOfBlocks()
00092 : _free( &_blocks[noOfBlocks-1] ), _reserveMemory( 0 ),
00093 _totalNoOfBlocks( noOfBlocks ), _noOfFreeBlocks( noOfBlocks )
00094 {
00095
00096 for (int i=noOfBlocks-1; i>0; i--)
00097 _blocks[i].setPrevBlock(&_blocks[i-1]);
00098 }
00099
00104 ~CommonPoolOfBlocks() {
00105 for (int i=0; i<_additionalBlocks.size(); i++) {
00106 delete[] _additionalBlocks[i];
00107 DS_VERBOSE1( std::cout << std::endl
00108 << "CommonPoolOfBlocks::~CommonPoolOfBlocks(): "
00109 << "additionally created blocks deleted." << std::endl );
00110 }
00111 }
00112
00114 Block * request() {
00115
00116 if ( ! _free ) {
00117
00118 int noOfNewBlocks = _reserveMemory / sizeof( Block );
00119 if (noOfNewBlocks == 0) {
00120
00121 std::cerr << "CommonPoolOfBlocks: request(): No free blocks available !"
00122 << std::endl;
00123 abort();
00124 }
00125
00126 DS_VERBOSE1( std::cout << std::endl << "CommonPoolOfBlocks::request(): "
00127 << noOfNewBlocks << " new blocks created." << std::endl );
00128
00129
00130 _reserveMemory -= noOfNewBlocks * sizeof( Block );
00131
00132 DS_LOGGING2( _totalNoOfBlocks += noOfNewBlocks;
00133 _noOfFreeBlocks += noOfNewBlocks );
00134
00135 Block *newBlocks = new Block[noOfNewBlocks];
00136 _additionalBlocks.push_back( newBlocks );
00137 for (int i=0; i<noOfNewBlocks; i++) {
00138 newBlocks[i].setPrevBlock( _free );
00139 _free = &newBlocks[i];
00140 }
00141 }
00142
00143 DS_LOGGING2( _noOfFreeBlocks-- );
00144
00145
00146 Block *block = _free;
00147 _free = _free->prevBlock();
00148 return block;
00149 }
00150
00152 void release(Block *block) {
00153 block->setPrevBlock(_free);
00154 _free = block;
00155
00156 DS_LOGGING2( _noOfFreeBlocks++ );
00157 }
00158
00164 void increaseReserveMemory(int newMemory) {
00165 _reserveMemory += newMemory;
00166 }
00167
00168
00169 DS_LOGGING2(
00171 int noOfBlocksUsed() const {return _totalNoOfBlocks - _noOfFreeBlocks;}
00172
00174 int noOfBlocksFree() const {return _noOfFreeBlocks;}
00175 )
00176
00177 private:
00179 Block _blocks[noOfBlocks];
00180
00182 Block *_free;
00183
00188 int _reserveMemory;
00189
00190 std::vector<Block*> _additionalBlocks;
00191
00197 int _totalNoOfBlocks;
00198
00200 int _noOfFreeBlocks;
00201
00202 };
00203
00204
00209 template <typename value_type, int elementsPerBlock, int noOfBlocks>
00210 class SparingStack
00211 {
00212 protected:
00214 typedef CommonPoolOfBlocks<value_type, elementsPerBlock, noOfBlocks> Pool;
00216 typedef Pool::Block Block;
00217
00218 public:
00220 SparingStack() : _top( &_bottom ) {}
00221
00223 ~SparingStack() {
00224 while (_top != &_bottom) {
00225 Block *oldBlock = _top;
00226 _top = _top->prevBlock();
00227 oldBlock->clear();
00228 _pool->release(oldBlock);
00229 }
00230 }
00231
00237 void setPool(Pool *pool) {_pool = pool;}
00238
00240 bool empty() const {return _top->empty();}
00241
00243 void push(const value_type &element) {
00244 if ( _top->full() ) {
00245
00246 Block *newBlock = _pool->request();
00247 newBlock->setPrevBlock(_top);
00248 _top = newBlock;
00249 }
00250 _top->push(element);
00251 }
00252
00254 const value_type & top() const {return _top->top();}
00255
00257 void pop() {
00258 _top->pop();
00259 if ( (_top->empty()) && (_top != &_bottom) ) {
00260
00261
00262 Block *oldBlock = _top;
00263 _top = _top->prevBlock();
00264 _pool->release(oldBlock);
00265 }
00266 }
00267
00269 int size() const {
00270 Block *current = _top;
00271 int blockCounter = 0;
00272 while (current != &_bottom) {
00273 blockCounter++;
00274 current = current->prevBlock();
00275 }
00276 return _top->size() + (blockCounter * DS_INT_EDGES_PER_BLOCK);
00277 }
00278
00279 protected:
00281 Pool *_pool;
00282
00284 Block *_top;
00285
00287 Block _bottom;
00288 };
00289
00290
00294 template <int elementsPerBlock, int noOfBlocks>
00295 class REWS_SparingStack : public SparingStack<RelabeledEdgeWithoutSource,
00296 elementsPerBlock,
00297 noOfBlocks>
00298 {
00299 public:
00307 NodeID determineMinEdge(MST &result) const {
00308
00309 RelabeledEdgeWithoutSource minEdge = top();
00310 Block *current = _top;
00311 while (true) {
00312 for (int index=current->size()-1; index >= 0; index--) {
00313 if ( (*current)[index] < minEdge ) minEdge = (*current)[index];
00314 }
00315 if (current == &_bottom) break;
00316 current = current->prevBlock();
00317 }
00318
00319
00320
00321 result.add( minEdge );
00322
00323 DS_VERBOSE2( std::cout << "( !!! MST::add = "
00324 << minEdge << " )" );
00325
00326 return minEdge.target();
00327 }
00328 };
00329
00330
00331 #endif // SPARINGSTACK_H