Salome HOME
0022107: EDF 2502 SMESH: Publish the result of show bad mesh in a group
[modules/smesh.git] / src / SMDS / ObjectPool.hxx
1 // Copyright (C) 2010-2013  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.
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;
44   int _chunkSize;
45
46   int getNextFree()
47   {
48     for (int i = _nextFree; i < _maxAvail; i++)
49       if (_freeList[i] == true)
50         {
51           return i;
52           break;
53         }
54     return _maxAvail;
55   }
56
57   void checkDelete(int chunkId)
58   {
59     int i0 = _chunkSize * chunkId;
60     int i1 = _chunkSize * (chunkId + 1);
61     for (int i = i0; i < i1; i++)
62       if (_freeList[i] == false)
63         return;
64     std::cerr << "a chunk to delete" << std::endl;
65     // compactage des vecteurs un peu lourd, pas necessaire
66     //X* chunk = _chunkList[chunkId];
67     //delete [] chunk;
68   }
69
70 public:
71   ObjectPool(int nblk)
72   {
73     _chunkSize = nblk;
74     _nextFree = 0;
75     _maxAvail = 0;
76     _chunkList.clear();
77     _freeList.clear();
78   }
79
80   virtual ~ObjectPool()
81   {
82     for (size_t i = 0; i < _chunkList.size(); i++)
83       delete[] _chunkList[i];
84   }
85
86   X* getNew()
87   {
88     X *obj = 0;
89     _nextFree = getNextFree();
90     if (_nextFree == _maxAvail)
91       {
92         X* newChunk = new X[_chunkSize];
93         _chunkList.push_back(newChunk);
94         _freeList.insert(_freeList.end(), _chunkSize, true);
95         _maxAvail += _chunkSize;
96         _freeList[_nextFree] = false;
97         obj = newChunk; // &newChunk[0];
98       }
99     else
100       {
101         int chunkId = _nextFree / _chunkSize;
102         int rank = _nextFree - chunkId * _chunkSize;
103         _freeList[_nextFree] = false;
104         obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
105       }
106     //obj->init();
107     return obj;
108   }
109
110   void destroy(X* obj)
111   {
112     long adrobj = (long) (obj);
113     for (size_t i = 0; i < _chunkList.size(); i++)
114       {
115         X* chunk = _chunkList[i];
116         long adrmin = (long) (chunk);
117         if (adrobj < adrmin)
118           continue;
119         long adrmax = (long) (chunk + _chunkSize);
120         if (adrobj >= adrmax)
121           continue;
122         int rank = (adrobj - adrmin) / sizeof(X);
123         int toFree = i * _chunkSize + rank;
124         _freeList[toFree] = true;
125         if (toFree < _nextFree)
126           _nextFree = toFree;
127         //obj->clean();
128         //checkDelete(i); compactage non fait
129         break;
130       }
131   }
132
133   void clear()
134   {
135     _nextFree = 0;
136     _maxAvail = 0;
137     for (size_t i = 0; i < _chunkList.size(); i++)
138       delete[] _chunkList[i];
139     clearVector( _chunkList );
140     clearVector( _freeList );
141   }
142
143   //  void destroy(int toFree)
144   //  {
145   //    // no control 0<= toFree < _freeList.size()
146   //    _freeList[toFree] = true;
147   //    if (toFree < _nextFree)
148   //      _nextFree = toFree;
149   //  }
150
151 };
152
153 #endif