1 // Copyright (C) 2010-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef _OBJECTPOOL_HXX_
21 #define _OBJECTPOOL_HXX_
26 #include "SMDS_Iterator.hxx"
30 // assure deallocation of memory of a vector
31 template<class Y> void clearVector(Y & v )
33 Y emptyVec; v.swap( emptyVec );
37 template<class X> class ObjectPoolIterator;
39 template<class X> class ObjectPool
43 std::vector<X*> _chunkList;
44 std::vector<bool> _freeList;
45 int _nextFree; // either the 1st hole or last added
46 int _maxAvail; // nb allocated elements
48 int _maxOccupied; // max used ID
52 friend class ObjectPoolIterator<X>;
56 // Don't iterate on the _freeList if all the "holes"
57 // are filled. Go straight to the last occupied ID + 1
59 return std::min(_maxOccupied + 1, _maxAvail);
61 for (int i = _nextFree; i < _maxAvail; i++)
62 if (_freeList[i] == true)
70 void checkDelete(int chunkId)
72 int i0 = _chunkSize * chunkId;
73 int i1 = _chunkSize * (chunkId + 1);
74 for (int i = i0; i < i1; i++)
75 if (_freeList[i] == false)
77 std::cerr << "a chunk to delete" << std::endl;
78 // compactage des vecteurs un peu lourd, pas necessaire
79 //X* chunk = _chunkList[chunkId];
84 ObjectPool(int nblk = 1024)
98 for (size_t i = 0; i < _chunkList.size(); i++)
99 delete[] _chunkList[i];
105 _nextFree = getNextFree();
106 if (_nextFree == _maxAvail)
108 X* newChunk = new X[_chunkSize];
109 _chunkList.push_back(newChunk);
110 _freeList.insert(_freeList.end(), _chunkSize, true);
111 _maxAvail += _chunkSize;
112 _freeList[_nextFree] = false;
117 int chunkId = _nextFree / _chunkSize;
118 int rank = _nextFree - chunkId * _chunkSize;
119 _freeList[_nextFree] = false;
120 obj = _chunkList[chunkId] + rank;
122 if (_nextFree <= _maxOccupied)
128 _maxOccupied = _nextFree;
136 if ( obj >= _chunkList[ _lastDelChunk ] &&
137 obj < _chunkList[ _lastDelChunk ] + _chunkSize )
140 for ( ; i < _chunkList.size(); i++ )
142 if ( obj >= _chunkList[ i ] &&
143 obj < _chunkList[ i ] + _chunkSize )
146 X* chunk = _chunkList[i];
147 long adrobj = (long) (obj);
148 long adrmin = (long) (chunk);
149 int rank = (adrobj - adrmin) / sizeof(X);
150 int toFree = i * _chunkSize + rank;
151 _freeList[toFree] = true;
152 if (toFree < _nextFree)
154 if (toFree < _maxOccupied)
168 for (size_t i = 0; i < _chunkList.size(); i++)
169 delete[] _chunkList[i];
170 clearVector( _chunkList );
171 clearVector( _freeList );
174 // nb allocated elements
177 return _freeList.size();
181 size_t nbElements() const
183 return _maxOccupied + 1 - _nbHoles;
186 // return an element w/o any check
187 const X* operator[]( size_t i ) const // i < size()
189 int chunkId = i / _chunkSize;
190 int rank = i - chunkId * _chunkSize;
191 return _chunkList[ chunkId ] + rank;
194 // return only being used element
195 const X* at( size_t i ) const // i < size()
197 if ( i >= size() || _freeList[ i ] )
200 int chunkId = i / _chunkSize;
201 int rank = i - chunkId * _chunkSize;
202 return _chunkList[ chunkId ] + rank;
205 // void destroy(int toFree)
207 // // no control 0<= toFree < _freeList.size()
208 // _freeList[toFree] = true;
209 // if (toFree < _nextFree)
210 // _nextFree = toFree;
215 template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
217 const ObjectPool<X>& _pool;
221 ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
223 if ( more() && _pool._freeList[ _i ] == true )
232 return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
235 virtual const X* next()
244 for ( ++_i; _i <= _pool._maxOccupied; ++_i )
245 if ( _pool._freeList[ _i ] == false )