X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FObjectPool.hxx;h=1c4781b22cc2d34ed2ffc800b5c0d7be230ebcab;hp=8c357ecc1068b36b14a08db695b14d61385fca0e;hb=6d32f944a0a115b6419184c50b57bf7c4eef5786;hpb=a17b36970bc61da1d664453c615754997c925b18 diff --git a/src/SMDS/ObjectPool.hxx b/src/SMDS/ObjectPool.hxx index 8c357ecc1..1c4781b22 100644 --- a/src/SMDS/ObjectPool.hxx +++ b/src/SMDS/ObjectPool.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2010-2019 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -21,29 +21,35 @@ #define _OBJECTPOOL_HXX_ #include -//#include #include +#include "SMDS_Iterator.hxx" + namespace { // assure deallocation of memory of a vector - template void clearVector(std::vector& v ) + template void clearVector(Y & v ) { - std::vector emptyVec; v.swap( emptyVec ); + Y emptyVec; v.swap( emptyVec ); } } +template class ObjectPoolIterator; + template class ObjectPool { private: - std::vector _chunkList; + std::vector _chunkList; std::vector _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; int getNextFree() { @@ -75,13 +81,14 @@ private: } 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(); } @@ -103,16 +110,16 @@ public: _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; } @@ -120,33 +127,35 @@ public: { _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() @@ -155,12 +164,44 @@ public: _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() @@ -171,4 +212,41 @@ public: }; +template class ObjectPoolIterator : public SMDS_Iterator +{ + const ObjectPool& _pool; + int _i, _nbFound; +public: + + ObjectPoolIterator( const ObjectPool& 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