00001 // Copyright (C) 2010-2011 CEA/DEN, EDF R&D, OPEN CASCADE 00002 // 00003 // This library is free software; you can redistribute it and/or 00004 // modify it under the terms of the GNU Lesser General Public 00005 // License as published by the Free Software Foundation; either 00006 // version 2.1 of the License. 00007 // 00008 // This library is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 // Lesser General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU Lesser General Public 00014 // License along with this library; if not, write to the Free Software 00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00016 // 00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com 00018 // 00019 00020 #ifndef _OBJECTPOOL_HXX_ 00021 #define _OBJECTPOOL_HXX_ 00022 00023 #include <vector> 00024 #include <stack> 00025 #include <iostream> 00026 00027 template<class X> class ObjectPool 00028 { 00029 00030 private: 00031 std::vector<X*> _chunkList; 00032 std::vector<bool> _freeList; 00033 int _nextFree; 00034 int _maxAvail; 00035 int _chunkSize; 00036 00037 int getNextFree() 00038 { 00039 for (int i = _nextFree; i < _maxAvail; i++) 00040 if (_freeList[i] == true) 00041 { 00042 return i; 00043 break; 00044 } 00045 return _maxAvail; 00046 } 00047 00048 void checkDelete(int chunkId) 00049 { 00050 int i0 = _chunkSize * chunkId; 00051 int i1 = _chunkSize * (chunkId + 1); 00052 for (int i = i0; i < i1; i++) 00053 if (_freeList[i] == false) 00054 return; 00055 std::cerr << "a chunk to delete" << std::endl; 00056 // compactage des vecteurs un peu lourd, pas necessaire 00057 //X* chunk = _chunkList[chunkId]; 00058 //delete [] chunk; 00059 } 00060 00061 public: 00062 ObjectPool(int nblk) 00063 { 00064 _chunkSize = nblk; 00065 _nextFree = 0; 00066 _maxAvail = 0; 00067 _chunkList.clear(); 00068 _freeList.clear(); 00069 } 00070 00071 virtual ~ObjectPool() 00072 { 00073 for (int i = 0; i < _chunkList.size(); i++) 00074 delete[] _chunkList[i]; 00075 } 00076 00077 X* getNew() 00078 { 00079 X *obj = 0; 00080 _nextFree = getNextFree(); 00081 if (_nextFree == _maxAvail) 00082 { 00083 X* newChunk = new X[_chunkSize]; 00084 _chunkList.push_back(newChunk); 00085 _freeList.insert(_freeList.end(), _chunkSize, true); 00086 _maxAvail += _chunkSize; 00087 _freeList[_nextFree] = false; 00088 obj = newChunk; // &newChunk[0]; 00089 } 00090 else 00091 { 00092 int chunkId = _nextFree / _chunkSize; 00093 int rank = _nextFree - chunkId * _chunkSize; 00094 _freeList[_nextFree] = false; 00095 obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank]; 00096 } 00097 //obj->init(); 00098 return obj; 00099 } 00100 00101 void destroy(X* obj) 00102 { 00103 long adrobj = (long) (obj); 00104 for (int i = 0; i < _chunkList.size(); i++) 00105 { 00106 X* chunk = _chunkList[i]; 00107 long adrmin = (long) (chunk); 00108 if (adrobj < adrmin) 00109 continue; 00110 long adrmax = (long) (chunk + _chunkSize); 00111 if (adrobj >= adrmax) 00112 continue; 00113 int rank = (adrobj - adrmin) / sizeof(X); 00114 int toFree = i * _chunkSize + rank; 00115 _freeList[toFree] = true; 00116 if (toFree < _nextFree) 00117 _nextFree = toFree; 00118 //obj->clean(); 00119 //checkDelete(i); compactage non fait 00120 break; 00121 } 00122 } 00123 00124 // void destroy(int toFree) 00125 // { 00126 // // no control 0<= toFree < _freeList.size() 00127 // _freeList[toFree] = true; 00128 // if (toFree < _nextFree) 00129 // _nextFree = toFree; 00130 // } 00131 00132 }; 00133 00134 #endif