glcontainer.h

00001 /*
00002 Copyright (c) 2000-2007 Lee Thomason (www.grinninglizard.com)
00003 Grinning Lizard Utilities.
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any 
00010 purpose, including commercial applications, and to alter it and 
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must 
00014 not claim that you wrote the original software. If you use this 
00015 software in a product, an acknowledgment in the product documentation 
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and 
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source 
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef GRINLIZ_CONTAINER_INCLUDED
00027 #define GRINLIZ_CONTAINER_INCLUDED
00028 
00029 #include "gldebug.h"
00030 #include "gltypes.h"
00031 
00032 namespace grinliz
00033 {
00034 
00035 template< typename T, typename Equal >
00036 class PtrHashTable
00037 {
00038 public:
00039         PtrHashTable( int _size = 256 ) : size( 0 ), population( 0 ), table( 0 )
00040         {
00041                 Resize( _size );
00042         }
00043 
00044         ~PtrHashTable() { delete [] table; }
00045 
00046         void Clear()
00047         {
00048                 memset( table, 0, size*sizeof(T*) );
00049                 population = 0;
00050         }
00051 
00052         void Put( T* t ) 
00053         {
00054                 if ( population > size / 2 ) {
00055                         GLOUTPUT(( "PtrHashTable resize %d to %d\n", size, size*4 ));
00056                         Resize( size*4 );
00057                 }
00058 
00059                 U32 hash = t->HashCode();
00060                 unsigned index = hash % size;
00061                 GLASSERT( index < size );
00062 
00063                 // Linear probe
00064                 while( table[index] ) {
00065                         ++index;
00066                         if ( index == size )
00067                                 index = 0;
00068                 }
00069                 table[index] = t;
00070                 ++population;
00071         }
00072 
00073         T* Contains( const T& key ) 
00074         {
00075                 U32 hash = key.HashCode();
00076                 unsigned index = hash % size;
00077                 while( table[index] ) 
00078                 {
00079                         Equal equal;
00080                         if ( equal( *(table[index]), key ) )
00081                                 return table[index];
00082 
00083                         ++index;
00084                         if ( index == size )
00085                                 index = 0;
00086                 }
00087                 return 0;
00088         }
00089 
00090         void Resize( unsigned newSize ) 
00091         {
00092                 if ( newSize < population / 4 )
00093                         newSize = population*4;
00094 
00095                 T** oldTable = table;
00096                 unsigned oldSize = size;
00097 
00098                 size = newSize;
00099                 table = glnew T*[size];
00100                 Clear();
00101 
00102                 for( unsigned i=0; i<oldSize; ++i ) 
00103                 {
00104                         if ( oldTable[i] )
00105                                 Put( oldTable[i] );
00106                 }
00107                 delete [] oldTable;
00108         }
00109 
00110 private:
00111         unsigned size;
00112         unsigned population;
00113         T** table;
00114 };
00115 
00116 
00117 class MapIdToVoidPtr
00118 {
00119 public:
00120         MapIdToVoidPtr(  U32 _size = 256 );
00121         ~MapIdToVoidPtr();
00122 
00123         void Clear();
00124         void Insert( U32 i, const void* t );
00125         const void* Get( U32 i );
00126         bool Remove( U32 i );
00127 
00128         U32 NumSlot()                                           { return size; }
00129         bool GetSlot( U32 offset, const void** v, U32* i )      
00130         {       
00131                 GLASSERT( offset < size );
00132                 if ( table[offset].i >= 0 ) {
00133                         *v = table[offset].ptr;
00134                         *i = table[offset].i;
00135                         return true;
00136                 }
00137                 return false;
00138         }
00139 
00140 private:
00141         U32 HashCode( U32 hash )
00142         {
00143                 hash += (hash << 3);
00144                 hash ^= (hash >> 11);
00145                 hash += (hash << 15);
00146                 return (U32) hash;
00147         }
00148 
00149         void Resize( U32 newSize );
00150 
00151         // 'ptr' can have any value.
00152         // 'i'  >= 0, index
00153         //      -1 empty
00154         //              -2 deleted
00155         struct Node {
00156                 int i;
00157                 const void* ptr;
00158         };
00159         enum {
00160                 NODE_EMPTY = -1,
00161                 NODE_DELETED = -2,
00162         };
00163 
00164         U32 size;
00165         U32 population;
00166         Node* table;
00167 };
00168 
00169 template< typename T >
00170 class MapId
00171 {
00172 public:
00173         MapId(  U32 _size = 256 ) : map( _size ) {
00174                 GLASSERT( sizeof( T ) <= sizeof( void* ) );
00175                 idPool = 0;
00176         }
00177         ~MapId()        {}
00178 
00179         void Clear()                                                    { map.Clear(); }
00180         void Insert( U32 i, const T t )                 { map.Insert( i, t ); }
00181         const T Get( U32 i )                                    { return (const T)map.Get( i ); }
00182         bool Remove( U32 i )                                    { return map.Remove( i ); }
00183 
00184         U32 NumSlot()                                                                           { return map.NumSlot(); }
00185         bool GetSlot( U32 offset, T* v, U32* i )                
00186         { 
00187                 const void* vPtr = 0;
00188                 bool result = map.GetSlot( offset, &vPtr, i ); 
00189                 *v = (T)(vPtr);
00190                 return result;
00191         }
00192 
00193         U32 NextID()                                                    { return idPool++; }
00194 private:
00195         MapIdToVoidPtr map;
00196         U32 idPool;
00197 };
00198 
00199 }       // namespace grinliz
00200 #endif

Generated on Fri Mar 23 19:36:21 2007 for Lilith3D by  doxygen 1.5.1-p1