// // ptrmap.h // #ifndef PTRMAP_H #define PTRMAP_H #ifdef __cplusplus #include "private.h" #define PM_HASHSIZE 31 template class CPMEntry { public: TKey key; TPtr *ptr; CPMEntry *next; }; template class CPtrMap { public: CPtrMap() { memset(_HashTbl, 0, sizeof(_HashTbl)); } ~CPtrMap(); BOOL _Set(TKey key, TPtr *ptr); TPtr *_Find(TKey key); TPtr *_Remove(TKey key); BOOL _Remove(TPtr *ptr); BOOL _FindKey(TPtr *ptr, TKey *pkeyOut); private: UINT _HashFunc(TKey key) { return (UINT)((UINT_PTR)key % PM_HASHSIZE); } CPMEntry **_FindEntry(TKey key); CPMEntry *_HashTbl[PM_HASHSIZE]; }; //+--------------------------------------------------------------------------- // // dtor // //---------------------------------------------------------------------------- template CPtrMap::~CPtrMap() { CPMEntry *pe; CPMEntry *peTmp; int i; // free anything left in the hashtbl for (i=0; inext; cicMemFree(pe); pe = peTmp; } } } //+--------------------------------------------------------------------------- // // _Set // //---------------------------------------------------------------------------- template BOOL CPtrMap::_Set(TKey key, TPtr *ptr) { UINT uIndex; CPMEntry *pe; CPMEntry **ppe; BOOL fRet; fRet = TRUE; if (ppe = _FindEntry(key)) { // already in hash tbl (*ppe)->ptr = ptr; } else if (pe = (CPMEntry *)cicMemAlloc(sizeof(CPMEntry))) { // new entry uIndex = _HashFunc(key); pe->key = key; pe->ptr = ptr; pe->next = _HashTbl[uIndex]; _HashTbl[uIndex] = pe; } else { // out of memory fRet = FALSE; } return fRet; } //+--------------------------------------------------------------------------- // // _Find // //---------------------------------------------------------------------------- template TPtr *CPtrMap::_Find(TKey key) { CPMEntry **ppe; if (ppe = _FindEntry(key)) { return (*ppe)->ptr; } return NULL; } //+--------------------------------------------------------------------------- // // _Remove // //---------------------------------------------------------------------------- template TPtr *CPtrMap::_Remove(TKey key) { CPMEntry *pe; CPMEntry **ppe; TPtr *ptr; if (ppe = _FindEntry(key)) { pe = *ppe; ptr = pe->ptr; *ppe = pe->next; cicMemFree(pe); return ptr; } return NULL; } //+--------------------------------------------------------------------------- // // _Remove // //---------------------------------------------------------------------------- template BOOL CPtrMap::_Remove(TPtr *ptr) { int i; CPMEntry *pe; CPMEntry **ppe; for (i = 0; i < PM_HASHSIZE; i++) { ppe = &_HashTbl[i]; while (*ppe) { if ((*ppe)->ptr == ptr) { pe = *ppe; *ppe = pe->next; cicMemFree(pe); } else { ppe = &(*ppe)->next; } } } return TRUE; } //+--------------------------------------------------------------------------- // // _FindKey // //---------------------------------------------------------------------------- template BOOL CPtrMap::_FindKey(TPtr *ptr, TKey *ptkeyOut) { int i; CPMEntry **ppe; *ptkeyOut = NULL; for (i = 0; i < PM_HASHSIZE; i++) { ppe = &_HashTbl[i]; while (*ppe) { if ((*ppe)->ptr == ptr) { *ptkeyOut = (*ppe)->key; return TRUE; } else { ppe = &(*ppe)->next; } } } return FALSE; } //+--------------------------------------------------------------------------- // // _FindEntry // //---------------------------------------------------------------------------- template CPMEntry **CPtrMap::_FindEntry(TKey key) { CPMEntry **ppe; ppe = &_HashTbl[_HashFunc(key)]; while (*ppe) { if ((*ppe)->key == key) { return ppe; } ppe = &(*ppe)->next; } return NULL; } #endif // __cplusplus #endif // PTRMAP_H