Version: 8.3.0
ObjectPool.hxx
Go to the documentation of this file.
1 // Copyright (C) 2010-2016 CEA/DEN, EDF R&D, 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 <stack>
25 #include <iostream>
26 
27 namespace
28 {
29  // assure deallocation of memory of a vector
30  template<class Y> void clearVector(std::vector<Y>& v )
31  {
32  std::vector<Y> emptyVec; v.swap( emptyVec );
33  }
34 }
35 
36 template<class X> class ObjectPool
37 {
38 
39 private:
40  std::vector<X*> _chunkList;
41  std::vector<bool> _freeList;
42  int _nextFree;
43  int _maxAvail;
46  int _nbHoles;
48 
50  {
51  // Don't iterate on the _freeList if all the "holes"
52  // are filled. Go straight to the last occupied ID + 1
53  if ( _nbHoles == 0 )
54  return std::min(_maxOccupied + 1, _maxAvail);
55 
56  for (int i = _nextFree; i < _maxAvail; i++)
57  if (_freeList[i] == true)
58  {
59  return i;
60  break;
61  }
62  return _maxAvail;
63  }
64 
65  void checkDelete(int chunkId)
66  {
67  int i0 = _chunkSize * chunkId;
68  int i1 = _chunkSize * (chunkId + 1);
69  for (int i = i0; i < i1; i++)
70  if (_freeList[i] == false)
71  return;
72  std::cerr << "a chunk to delete" << std::endl;
73  // compactage des vecteurs un peu lourd, pas necessaire
74  //X* chunk = _chunkList[chunkId];
75  //delete [] chunk;
76  }
77 
78 public:
79  ObjectPool(int nblk)
80  {
81  _chunkSize = nblk;
82  _nextFree = 0;
83  _maxAvail = 0;
84  _maxOccupied = 0;
85  _nbHoles = 0;
86  _chunkList.clear();
87  _freeList.clear();
88  _lastDelChunk = 0;
89  }
90 
91  virtual ~ObjectPool()
92  {
93  for (size_t i = 0; i < _chunkList.size(); i++)
94  delete[] _chunkList[i];
95  }
96 
97  X* getNew()
98  {
99  X *obj = 0;
101  if (_nextFree == _maxAvail)
102  {
103  X* newChunk = new X[_chunkSize];
104  _chunkList.push_back(newChunk);
105  _freeList.insert(_freeList.end(), _chunkSize, true);
107  _freeList[_nextFree] = false;
108  obj = newChunk; // &newChunk[0];
109  }
110  else
111  {
112  int chunkId = _nextFree / _chunkSize;
113  int rank = _nextFree - chunkId * _chunkSize;
114  _freeList[_nextFree] = false;
115  obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
116  }
117  if (_nextFree < _maxOccupied)
118  {
119  _nbHoles-=1;
120  }
121  else
122  {
124  }
125  //obj->init();
126  return obj;
127  }
128 
129  void destroy(X* obj)
130  {
131  size_t i = 0;
132  if ( obj >= _chunkList[ _lastDelChunk ] &&
133  obj < _chunkList[ _lastDelChunk ] + _chunkSize )
134  i = _lastDelChunk;
135  else
136  for ( ; i < _chunkList.size(); i++ )
137  {
138  if ( obj >= _chunkList[ i ] &&
139  obj < _chunkList[ i ] + _chunkSize )
140  break;
141  }
142  X* chunk = _chunkList[i];
143  long adrobj = (long) (obj);
144  long adrmin = (long) (chunk);
145  int rank = (adrobj - adrmin) / sizeof(X);
146  int toFree = i * _chunkSize + rank;
147  _freeList[toFree] = true;
148  if (toFree < _nextFree)
149  _nextFree = toFree;
150  if (toFree < _maxOccupied)
151  _nbHoles += 1;
152  _lastDelChunk = i;
153  //obj->clean();
154  //checkDelete(i); compactage non fait
155  }
156 
157  void clear()
158  {
159  _nextFree = 0;
160  _maxAvail = 0;
161  _maxOccupied = 0;
162  _nbHoles = 0;
163  _lastDelChunk = 0;
164  for (size_t i = 0; i < _chunkList.size(); i++)
165  delete[] _chunkList[i];
166  clearVector( _chunkList );
167  clearVector( _freeList );
168  }
169 
170  // void destroy(int toFree)
171  // {
172  // // no control 0<= toFree < _freeList.size()
173  // _freeList[toFree] = true;
174  // if (toFree < _nextFree)
175  // _nextFree = toFree;
176  // }
177 
178 };
179 
180 #endif