00001
00021 #ifndef __HASH_PTR_H__
00022 #define __HASH_PTR_H__
00023
00027
00028 #include <stdio.h>
00029 #include "extra.h"
00030
00031 extern int Hash_DefaultHashFunc(int key, int nBins);
00032
00036
00040
00041 typedef struct Hash_Ptr_t_ Hash_Ptr_t;
00042 typedef struct Hash_Ptr_Entry_t_ Hash_Ptr_Entry_t;
00043
00044 struct Hash_Ptr_Entry_t_
00045 {
00046 int key;
00047 void * data;
00048 struct Hash_Ptr_Entry_t_ * pNext;
00049 };
00050
00051 struct Hash_Ptr_t_
00052 {
00053 int nSize;
00054 int nBins;
00055 int (* fHash)(int key, int nBins);
00056 Hash_Ptr_Entry_t ** pArray;
00057 };
00058
00059
00060
00064
00065 #define Hash_PtrForEachEntry( pHash, pEntry, bin ) \
00066 for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \
00067 if (pEntry)
00068
00072
00084 static inline Hash_Ptr_t * Hash_PtrAlloc( int nBins )
00085 {
00086 Hash_Ptr_t * p;
00087 int i;
00088 assert(nBins > 0);
00089 p = ALLOC( Hash_Ptr_t, 1);
00090 p->nBins = nBins;
00091 p->fHash = Hash_DefaultHashFunc;
00092 p->nSize = 0;
00093 p->pArray = ALLOC( Hash_Ptr_Entry_t *, nBins );
00094 for(i=0; i<nBins; i++)
00095 p->pArray[i] = NULL;
00096
00097 return p;
00098 }
00099
00111 static inline int Hash_PtrExists( Hash_Ptr_t *p, int key )
00112 {
00113 int bin;
00114 Hash_Ptr_Entry_t *pEntry, **pLast;
00115
00116
00117 bin = (*(p->fHash))(key, p->nBins);
00118
00119
00120 pLast = &(p->pArray[bin]);
00121 pEntry = p->pArray[bin];
00122 while(pEntry) {
00123 if (pEntry->key == key) {
00124 return 1;
00125 }
00126 pLast = &(pEntry->pNext);
00127 pEntry = pEntry->pNext;
00128 }
00129
00130 return 0;
00131 }
00132
00144 static inline void Hash_PtrWriteEntry( Hash_Ptr_t *p, int key, void * data )
00145 {
00146 int bin;
00147 Hash_Ptr_Entry_t *pEntry, **pLast;
00148
00149
00150 bin = (*(p->fHash))(key, p->nBins);
00151
00152
00153 pLast = &(p->pArray[bin]);
00154 pEntry = p->pArray[bin];
00155 while(pEntry) {
00156 if (pEntry->key == key) {
00157 pEntry->data = data;
00158 return;
00159 }
00160 pLast = &(pEntry->pNext);
00161 pEntry = pEntry->pNext;
00162 }
00163
00164
00165
00166 p->nSize++;
00167 (*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 );
00168 pEntry->pNext = NULL;
00169 pEntry->key = key;
00170 pEntry->data = data;
00171
00172 return;
00173 }
00174
00175
00187 static inline void * Hash_PtrEntry( Hash_Ptr_t *p, int key, int fCreate )
00188 {
00189 int bin;
00190 Hash_Ptr_Entry_t *pEntry, **pLast;
00191
00192
00193 bin = (*(p->fHash))(key, p->nBins);
00194
00195
00196 pLast = &(p->pArray[bin]);
00197 pEntry = p->pArray[bin];
00198 while(pEntry) {
00199 if (pEntry->key == key)
00200 return pEntry->data;
00201 pLast = &(pEntry->pNext);
00202 pEntry = pEntry->pNext;
00203 }
00204
00205
00206 if (fCreate) {
00207
00208 p->nSize++;
00209 (*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 );
00210 pEntry->pNext = NULL;
00211 pEntry->key = key;
00212 pEntry->data = NULL;
00213 return pEntry->data;
00214 }
00215
00216 return NULL;
00217 }
00218
00219
00231 static inline void** Hash_PtrEntryPtr( Hash_Ptr_t *p, int key )
00232 {
00233 int bin;
00234 Hash_Ptr_Entry_t *pEntry, **pLast;
00235
00236
00237 bin = (*(p->fHash))(key, p->nBins);
00238
00239
00240 pLast = &(p->pArray[bin]);
00241 pEntry = p->pArray[bin];
00242 while(pEntry) {
00243 if (pEntry->key == key)
00244 return &(pEntry->data);
00245 pLast = &(pEntry->pNext);
00246 pEntry = pEntry->pNext;
00247 }
00248
00249
00250
00251 p->nSize++;
00252 (*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 );
00253 pEntry->pNext = NULL;
00254 pEntry->key = key;
00255 pEntry->data = NULL;
00256
00257 return &(pEntry->data);
00258 }
00259
00271 static inline void* Hash_PtrRemove( Hash_Ptr_t *p, int key )
00272 {
00273 int bin;
00274 void * data;
00275 Hash_Ptr_Entry_t *pEntry, **pLast;
00276
00277
00278 bin = (*(p->fHash))(key, p->nBins);
00279
00280
00281 pLast = &(p->pArray[bin]);
00282 pEntry = p->pArray[bin];
00283 while(pEntry) {
00284 if (pEntry->key == key) {
00285 p->nSize--;
00286 data = pEntry->data;
00287 *pLast = pEntry->pNext;
00288 return data;
00289 }
00290 pLast = &(pEntry->pNext);
00291 pEntry = pEntry->pNext;
00292 }
00293
00294
00295 return NULL;
00296 }
00297
00309 static inline void Hash_PtrFree( Hash_Ptr_t *p ) {
00310 int bin;
00311 Hash_Ptr_Entry_t *pEntry;
00312
00313
00314 for(bin = 0; bin < p->nBins; bin++) {
00315 pEntry = p->pArray[bin];
00316 while(pEntry) {
00317 pEntry = pEntry->pNext;
00318 FREE( pEntry );
00319 }
00320 }
00321
00322
00323 FREE( p->pArray );
00324 FREE( p );
00325 }
00326
00330
00331 #endif