Version: 9.16.0
ObjectPool.hxx
Go to the documentation of this file.
1// Copyright (C) 2010-2026 CEA, EDF, OPEN CASCADE
2//
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.
7//
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.
12//
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
16//
17// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18//
19
20#ifndef _OBJECTPOOL_HXX_
21#define _OBJECTPOOL_HXX_
22
23#include <vector>
24#include <iostream>
25
26#include "SMDS_Iterator.hxx"
27
28namespace
29{
30 // assure deallocation of memory of a vector
31 template<class Y> void clearVector(Y & v )
32 {
33 Y emptyVec; v.swap( emptyVec );
34 }
35}
36
37template<class X> class ObjectPoolIterator;
38
39template<class X> class ObjectPool
40{
41
42private:
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
51
52 friend class ObjectPoolIterator<X>;
53
55 {
56 // Don't iterate on the _freeList if all the "holes"
57 // are filled. Go straight to the last occupied ID + 1
58 if ( _nbHoles == 0 )
59 return std::min(_maxOccupied + 1, _maxAvail);
60
61 for (int i = _nextFree; i < _maxAvail; i++)
62 if (_freeList[i] == true)
63 {
64 return i;
65 break;
66 }
67 return _maxAvail;
68 }
69
70 void checkDelete(int chunkId)
71 {
72 int i0 = _chunkSize * chunkId;
73 int i1 = _chunkSize * (chunkId + 1);
74 for (int i = i0; i < i1; i++)
75 if (_freeList[i] == false)
76 return;
77 std::cerr << "a chunk to delete" << std::endl;
78 // compactage des vecteurs un peu lourd, pas necessaire
79 //X* chunk = _chunkList[chunkId];
80 //delete [] chunk;
81 }
82
83public:
84 ObjectPool(int nblk = 1024)
85 {
86 _chunkSize = nblk;
87 _nextFree = 0;
88 _maxAvail = 0;
89 _maxOccupied = -1;
90 _nbHoles = 0;
91 _lastDelChunk = 0;
92 _chunkList.clear();
93 _freeList.clear();
94 }
95
96 virtual ~ObjectPool()
97 {
98 for (size_t i = 0; i < _chunkList.size(); i++)
99 delete[] _chunkList[i];
100 }
101
103 {
104 X *obj = 0;
106 if (_nextFree == _maxAvail)
107 {
108 X* newChunk = new X[_chunkSize];
109 _chunkList.push_back(newChunk);
110 _freeList.insert(_freeList.end(), _chunkSize, true);
112 _freeList[_nextFree] = false;
113 obj = newChunk;
114 }
115 else
116 {
117 int chunkId = _nextFree / _chunkSize;
118 int rank = _nextFree - chunkId * _chunkSize;
119 _freeList[_nextFree] = false;
120 obj = _chunkList[chunkId] + rank;
121 }
122 if (_nextFree <= _maxOccupied)
123 {
124 _nbHoles-=1;
125 }
126 else
127 {
129 }
130 return obj;
131 }
132
133 void destroy(X* obj)
134 {
135 size_t i = 0;
136 if ( obj >= _chunkList[ _lastDelChunk ] &&
138 i = _lastDelChunk;
139 else
140 for ( ; i < _chunkList.size(); i++ )
141 {
142 if ( obj >= _chunkList[ i ] &&
143 obj < _chunkList[ i ] + _chunkSize )
144 break;
145 }
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)
153 _nextFree = toFree;
154 if (toFree < _maxOccupied)
155 ++_nbHoles;
156 else
157 --_maxOccupied;
158 _lastDelChunk = i;
159 }
160
161 void clear()
162 {
163 _nextFree = 0;
164 _maxAvail = 0;
165 _maxOccupied = 0;
166 _nbHoles = 0;
167 _lastDelChunk = 0;
168 for (size_t i = 0; i < _chunkList.size(); i++)
169 delete[] _chunkList[i];
170 clearVector( _chunkList );
171 clearVector( _freeList );
172 }
173
174 // nb allocated elements
175 size_t size() const
176 {
177 return _freeList.size();
178 }
179
180 // nb used elements
181 size_t nbElements() const
182 {
183 return _maxOccupied + 1 - _nbHoles;
184 }
185
186 // return an element w/o any check
187 const X* operator[]( size_t i ) const // i < size()
188 {
189 int chunkId = i / _chunkSize;
190 int rank = i - chunkId * _chunkSize;
191 return _chunkList[ chunkId ] + rank;
192 }
193
194 // return only being used element
195 const X* at( size_t i ) const // i < size()
196 {
197 if ( i >= size() || _freeList[ i ] )
198 return 0;
199
200 int chunkId = i / _chunkSize;
201 int rank = i - chunkId * _chunkSize;
202 return _chunkList[ chunkId ] + rank;
203 }
204
205 // void destroy(int toFree)
206 // {
207 // // no control 0<= toFree < _freeList.size()
208 // _freeList[toFree] = true;
209 // if (toFree < _nextFree)
210 // _nextFree = toFree;
211 // }
212
213};
214
215template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
216{
219public:
220
221 ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
222 {
223 if ( more() && _pool._freeList[ _i ] == true )
224 {
225 next();
226 --_nbFound;
227 }
228 }
229
230 virtual bool more()
231 {
232 return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
233 }
234
235 virtual const X* next()
236 {
237 const X* x = 0;
238 if ( more() )
239 {
240 x = _pool[ _i ];
241
242 ++_nbFound;
243
244 for ( ++_i; _i <= _pool._maxOccupied; ++_i )
245 if ( _pool._freeList[ _i ] == false )
246 break;
247 }
248 return x;
249 }
250};
251
252#endif
Definition: ObjectPool.hxx:216
virtual const X * next()
Return the current object and step to the next one.
Definition: ObjectPool.hxx:235
const ObjectPool< X > & _pool
Definition: ObjectPool.hxx:217
int _i
Definition: ObjectPool.hxx:218
ObjectPoolIterator(const ObjectPool< X > &pool)
Definition: ObjectPool.hxx:221
int _nbFound
Definition: ObjectPool.hxx:218
virtual bool more()
Return true if and only if there are other object in this iterator.
Definition: ObjectPool.hxx:230
Definition: ObjectPool.hxx:40
int getNextFree()
Definition: ObjectPool.hxx:54
std::vector< X * > _chunkList
Definition: ObjectPool.hxx:43
void clear()
Definition: ObjectPool.hxx:161
std::vector< bool > _freeList
Definition: ObjectPool.hxx:44
const X * at(size_t i) const
Definition: ObjectPool.hxx:195
size_t size() const
Definition: ObjectPool.hxx:175
const X * operator[](size_t i) const
Definition: ObjectPool.hxx:187
ObjectPool(int nblk=1024)
Definition: ObjectPool.hxx:84
int _nbHoles
Definition: ObjectPool.hxx:49
int _maxAvail
Definition: ObjectPool.hxx:46
int _nextFree
Definition: ObjectPool.hxx:45
int _maxOccupied
Definition: ObjectPool.hxx:48
X * getNew()
Definition: ObjectPool.hxx:102
size_t nbElements() const
Definition: ObjectPool.hxx:181
void destroy(X *obj)
Definition: ObjectPool.hxx:133
int _lastDelChunk
Definition: ObjectPool.hxx:50
void checkDelete(int chunkId)
Definition: ObjectPool.hxx:70
int _chunkSize
Definition: ObjectPool.hxx:47
virtual ~ObjectPool()
Definition: ObjectPool.hxx:96
Abstract class for iterators.
Definition: SMDS_Iterator.hxx:33