00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
00152
00153
00154
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 }
00200 #endif