smallobject.hh

00001 #ifndef DUNE_SMALLOBJECT_HH
00002 #define DUNE_SMALLOBJECT_HH
00003 
00004 #include <cassert>
00005 #include <new>
00006 
00007 namespace Dune
00008 {
00009 
00010   // SmallObjectPool
00011   // ---------------
00012 
00013   class SmallObjectPool
00014   {
00015     union Block
00016     {
00017       Block *next;
00018       unsigned int blocks;
00019     };
00020 
00021   public:
00022     enum { blockSize = sizeof( Block ) };
00023     enum { maxBlocks = (1 << 10) - 1 };
00024     enum { maxSize = maxBlocks * blockSize };
00025 
00026   private:
00027     Block *list_[ maxBlocks ];
00028 
00029     SmallObjectPool ()
00030     {
00031       for( unsigned int i = 0; i < maxBlocks; ++i )
00032         list_[ i ] = 0;
00033     }
00034 
00035     ~SmallObjectPool ()
00036     {
00037       for( unsigned int i = 0; i < maxBlocks; ++i )
00038       {
00039         for( Block *next = list_[ i ]; next != 0; )
00040         {
00041           Block *current = next;
00042           next = current->next;
00043           delete[] current;
00044         }
00045       }
00046     }
00047 
00048     static SmallObjectPool &instance ()
00049     {
00050       static SmallObjectPool inst;
00051       return inst;
00052     }
00053 
00054     static Block *&list ( unsigned int blocks )
00055     {
00056       assert( blocks < maxBlocks );
00057       return instance().list_[ blocks ];
00058     }
00059 
00060   public:
00061     static void *allocate ( unsigned int size )
00062     {
00063       const unsigned int blocks = (size + (blockSize-1)) / blockSize;
00064       if( blocks >= maxBlocks )
00065         return 0;
00066       Block *&next = list( blocks );
00067       Block *current = next;
00068       if( current != 0 )
00069         next = current->next;
00070       else
00071         current = new Block[ blocks+1 ];
00072       current->blocks = blocks;
00073       return current + 1;
00074     }
00075 
00076     static void free ( void *ptr )
00077     {
00078       if( ptr != 0 )
00079       {
00080         Block *current = reinterpret_cast< Block * >( ptr ) - 1;
00081         const unsigned int blocks = current->blocks;
00082         Block *&next = list( blocks );
00083         current->next = next;
00084         next = current;
00085       }
00086     }
00087   };
00088 
00089 
00090 
00091   // SmallObject
00092   // -----------
00093 
00094   struct SmallObject
00095   {
00096     void *operator new ( size_t size )
00097     {
00098       return SmallObjectPool :: allocate( size );
00099     }
00100 
00101     void operator delete ( void *ptr )
00102     {
00103       SmallObjectPool :: free( ptr );
00104     }
00105   };
00106 
00107 }
00108 
00109 #endif

Generated on Sun Nov 15 22:28:13 2009 for dune-common by  doxygen 1.5.6