Salome HOME
Update copyright
[modules/smesh.git] / src / SMDS / ObjectPool.hxx
1 // Copyright (C) 2010-2011  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 template<class X> class ObjectPool
28 {
29
30 private:
31   std::vector<X*> _chunkList;
32   std::vector<bool> _freeList;
33   int _nextFree;
34   int _maxAvail;
35   int _chunkSize;
36
37   int getNextFree()
38   {
39     for (int i = _nextFree; i < _maxAvail; i++)
40       if (_freeList[i] == true)
41         {
42           return i;
43           break;
44         }
45     return _maxAvail;
46   }
47
48   void checkDelete(int chunkId)
49   {
50     int i0 = _chunkSize * chunkId;
51     int i1 = _chunkSize * (chunkId + 1);
52     for (int i = i0; i < i1; i++)
53       if (_freeList[i] == false)
54         return;
55     std::cerr << "a chunk to delete" << std::endl;
56     // compactage des vecteurs un peu lourd, pas necessaire
57     //X* chunk = _chunkList[chunkId];
58     //delete [] chunk;
59   }
60
61 public:
62   ObjectPool(int nblk)
63   {
64     _chunkSize = nblk;
65     _nextFree = 0;
66     _maxAvail = 0;
67     _chunkList.clear();
68     _freeList.clear();
69   }
70
71   virtual ~ObjectPool()
72   {
73     for (int i = 0; i < _chunkList.size(); i++)
74       delete[] _chunkList[i];
75   }
76
77   X* getNew()
78   {
79     X *obj = 0;
80     _nextFree = getNextFree();
81     if (_nextFree == _maxAvail)
82       {
83         X* newChunk = new X[_chunkSize];
84         _chunkList.push_back(newChunk);
85         _freeList.insert(_freeList.end(), _chunkSize, true);
86         _maxAvail += _chunkSize;
87         _freeList[_nextFree] = false;
88         obj = newChunk; // &newChunk[0];
89       }
90     else
91       {
92         int chunkId = _nextFree / _chunkSize;
93         int rank = _nextFree - chunkId * _chunkSize;
94         _freeList[_nextFree] = false;
95         obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
96       }
97     //obj->init();
98     return obj;
99   }
100
101   void destroy(X* obj)
102   {
103     long adrobj = (long) (obj);
104     for (int i = 0; i < _chunkList.size(); i++)
105       {
106         X* chunk = _chunkList[i];
107         long adrmin = (long) (chunk);
108         if (adrobj < adrmin)
109           continue;
110         long adrmax = (long) (chunk + _chunkSize);
111         if (adrobj >= adrmax)
112           continue;
113         int rank = (adrobj - adrmin) / sizeof(X);
114         int toFree = i * _chunkSize + rank;
115         _freeList[toFree] = true;
116         if (toFree < _nextFree)
117           _nextFree = toFree;
118         //obj->clean();
119         //checkDelete(i); compactage non fait
120         break;
121       }
122   }
123
124   //  void destroy(int toFree)
125   //  {
126   //    // no control 0<= toFree < _freeList.size()
127   //    _freeList[toFree] = true;
128   //    if (toFree < _nextFree)
129   //      _nextFree = toFree;
130   //  }
131
132 };
133
134 #endif