Salome HOME
Regression of BelongToGeom on Debian-6
[modules/smesh.git] / src / SMDS / ObjectPool.hxx
index 1ee3710556b2804591e9eb086455142911367455..5e5f0d289d275eff3d2c3d10a6b99d80b88d400d 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #define _OBJECTPOOL_HXX_
 
 #include <vector>
-#include <stack>
+//#include <stack>
 #include <iostream>
 
+namespace
+{
+  // assure deallocation of memory of a vector
+  template<class Y> void clearVector(std::vector<Y>& v )
+  {
+    std::vector<Y> emptyVec; v.swap( emptyVec );
+  }
+}
+
 template<class X> class ObjectPool
 {
 
@@ -33,9 +42,17 @@ private:
   int _nextFree;
   int _maxAvail;
   int _chunkSize;
+  int _maxOccupied;
+  int _nbHoles;
+  int _lastDelChunk;
 
   int getNextFree()
   {
+    // Don't iterate on the _freeList if all the "holes"
+    // are filled. Go straight to the last occupied ID + 1
+    if ( _nbHoles == 0 )
+      return std::min(_maxOccupied + 1, _maxAvail);
+    
     for (int i = _nextFree; i < _maxAvail; i++)
       if (_freeList[i] == true)
         {
@@ -64,13 +81,16 @@ public:
     _chunkSize = nblk;
     _nextFree = 0;
     _maxAvail = 0;
+    _maxOccupied = 0;
+    _nbHoles = 0;
     _chunkList.clear();
     _freeList.clear();
+    _lastDelChunk = 0;
   }
 
   virtual ~ObjectPool()
   {
-    for (int i = 0; i < _chunkList.size(); i++)
+    for (size_t i = 0; i < _chunkList.size(); i++)
       delete[] _chunkList[i];
   }
 
@@ -94,31 +114,57 @@ public:
         _freeList[_nextFree] = false;
         obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
       }
+    if (_nextFree < _maxOccupied)
+      {
+        _nbHoles-=1;
+      }
+    else
+      {
+        _maxOccupied = _nextFree;
+      }
     //obj->init();
     return obj;
   }
 
   void destroy(X* obj)
   {
-    long adrobj = (long) (obj);
-    for (int i = 0; i < _chunkList.size(); i++)
+    size_t i = 0;
+    if ( obj >= _chunkList[ _lastDelChunk ] &&
+         obj <  _chunkList[ _lastDelChunk ] + _chunkSize )
+      i = _lastDelChunk;
+    else
+      for ( ; i < _chunkList.size(); i++ )
       {
-        X* chunk = _chunkList[i];
-        long adrmin = (long) (chunk);
-        if (adrobj < adrmin)
-          continue;
-        long adrmax = (long) (chunk + _chunkSize);
-        if (adrobj >= adrmax)
-          continue;
-        int rank = (adrobj - adrmin) / sizeof(X);
-        int toFree = i * _chunkSize + rank;
-        _freeList[toFree] = true;
-        if (toFree < _nextFree)
-          _nextFree = toFree;
-        //obj->clean();
-        //checkDelete(i); compactage non fait
-        break;
+        if ( obj >= _chunkList[ i ] &&
+             obj <  _chunkList[ i ] + _chunkSize )
+          break;
       }
+    X*    chunk = _chunkList[i];
+    long adrobj = (long) (obj);
+    long adrmin = (long) (chunk);
+    int  rank   = (adrobj - adrmin) / sizeof(X);
+    int  toFree = i * _chunkSize + rank;
+    _freeList[toFree] = true;
+    if (toFree < _nextFree)
+      _nextFree = toFree;
+    if (toFree < _maxOccupied)
+      _nbHoles += 1;
+    _lastDelChunk = i;
+    //obj->clean();
+    //checkDelete(i); compactage non fait
+  }
+
+  void clear()
+  {
+    _nextFree = 0;
+    _maxAvail = 0;
+    _maxOccupied = 0;
+    _nbHoles = 0;
+    _lastDelChunk = 0;
+    for (size_t i = 0; i < _chunkList.size(); i++)
+      delete[] _chunkList[i];
+    clearVector( _chunkList );
+    clearVector( _freeList );
   }
 
   //  void destroy(int toFree)