#define _OBJECTPOOL_HXX_
#include <vector>
-//#include <stack>
#include <iostream>
+#include "SMDS_Iterator.hxx"
+
namespace
{
// assure deallocation of memory of a vector
- template<class Y> void clearVector(std::vector<Y>& v )
+ template<class Y> void clearVector(Y & v )
{
- std::vector<Y> emptyVec; v.swap( emptyVec );
+ Y emptyVec; v.swap( emptyVec );
}
}
+template<class X> class ObjectPoolIterator;
+
template<class X> class ObjectPool
{
private:
- std::vector<X*> _chunkList;
+ std::vector<X*> _chunkList;
std::vector<bool> _freeList;
- int _nextFree;
- int _maxAvail;
- int _chunkSize;
- int _maxOccupied;
- int _nbHoles;
+ int _nextFree; // either the 1st hole or last added
+ int _maxAvail; // nb allocated elements
+ int _chunkSize;
+ int _maxOccupied; // max used ID
+ int _nbHoles;
+ int _lastDelChunk;
+
+ friend class ObjectPoolIterator<X>;
int getNextFree()
{
}
public:
- ObjectPool(int nblk)
+ ObjectPool(int nblk = 1024)
{
- _chunkSize = nblk;
- _nextFree = 0;
- _maxAvail = 0;
- _maxOccupied = 0;
- _nbHoles = 0;
+ _chunkSize = nblk;
+ _nextFree = 0;
+ _maxAvail = 0;
+ _maxOccupied = -1;
+ _nbHoles = 0;
+ _lastDelChunk = 0;
_chunkList.clear();
_freeList.clear();
}
_freeList.insert(_freeList.end(), _chunkSize, true);
_maxAvail += _chunkSize;
_freeList[_nextFree] = false;
- obj = newChunk; // &newChunk[0];
+ obj = newChunk;
}
else
{
int chunkId = _nextFree / _chunkSize;
int rank = _nextFree - chunkId * _chunkSize;
_freeList[_nextFree] = false;
- obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
+ obj = _chunkList[chunkId] + rank;
}
- if (_nextFree < _maxOccupied)
+ if (_nextFree <= _maxOccupied)
{
_nbHoles-=1;
}
{
_maxOccupied = _nextFree;
}
- //obj->init();
return obj;
}
void destroy(X* obj)
{
- long adrobj = (long) (obj);
- for (size_t i = 0; i < _chunkList.size(); i++)
+ size_t i = 0;
+ if ( obj >= _chunkList[ _lastDelChunk ] &&
+ obj < _chunkList[ _lastDelChunk ] + _chunkSize )
+ i = _lastDelChunk;
+ else
+ for ( ; i < _chunkList.size(); i++ )
{
- X* chunk = _chunkList[i];
- long adrmin = (long) (chunk);
- if (adrobj < adrmin)
- continue;
- long adrmax = (long) (chunk + _chunkSize);
- if (adrobj >= adrmax)
- continue;
- int rank = (adrobj - adrmin) / sizeof(X);
- int toFree = i * _chunkSize + rank;
- _freeList[toFree] = true;
- if (toFree < _nextFree)
- _nextFree = toFree;
- if (toFree < _maxOccupied)
- _nbHoles += 1;
- //obj->clean();
- //checkDelete(i); compactage non fait
- break;
+ if ( obj >= _chunkList[ i ] &&
+ obj < _chunkList[ i ] + _chunkSize )
+ break;
}
+ X* chunk = _chunkList[i];
+ long adrobj = (long) (obj);
+ long adrmin = (long) (chunk);
+ int rank = (adrobj - adrmin) / sizeof(X);
+ int toFree = i * _chunkSize + rank;
+ _freeList[toFree] = true;
+ if (toFree < _nextFree)
+ _nextFree = toFree;
+ if (toFree < _maxOccupied)
+ ++_nbHoles;
+ else
+ --_maxOccupied;
+ _lastDelChunk = i;
}
void clear()
_maxAvail = 0;
_maxOccupied = 0;
_nbHoles = 0;
+ _lastDelChunk = 0;
for (size_t i = 0; i < _chunkList.size(); i++)
delete[] _chunkList[i];
clearVector( _chunkList );
clearVector( _freeList );
}
+ // nb allocated elements
+ size_t size() const
+ {
+ return _freeList.size();
+ }
+
+ // nb used elements
+ size_t nbElements() const
+ {
+ return _maxOccupied + 1 - _nbHoles;
+ }
+
+ // return an element w/o any check
+ const X* operator[]( size_t i ) const // i < size()
+ {
+ int chunkId = i / _chunkSize;
+ int rank = i - chunkId * _chunkSize;
+ return _chunkList[ chunkId ] + rank;
+ }
+
+ // return only being used element
+ const X* at( size_t i ) const // i < size()
+ {
+ if ( i >= size() || _freeList[ i ] )
+ return 0;
+
+ int chunkId = i / _chunkSize;
+ int rank = i - chunkId * _chunkSize;
+ return _chunkList[ chunkId ] + rank;
+ }
+
// void destroy(int toFree)
// {
// // no control 0<= toFree < _freeList.size()
};
+template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
+{
+ const ObjectPool<X>& _pool;
+ int _i, _nbFound;
+public:
+
+ ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
+ {
+ if ( more() && _pool._freeList[ _i ] == true )
+ {
+ next();
+ --_nbFound;
+ }
+ }
+
+ virtual bool more()
+ {
+ return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
+ }
+
+ virtual const X* next()
+ {
+ const X* x = 0;
+ if ( more() )
+ {
+ x = _pool[ _i ];
+
+ ++_nbFound;
+
+ for ( ++_i; _i <= _pool._maxOccupied; ++_i )
+ if ( _pool._freeList[ _i ] == false )
+ break;
+ }
+ return x;
+ }
+};
+
#endif