#ifndef _VAR_STRING_HASH_H_ #define _VAR_STRING_HASH_H_ 1 #include #include #include class VarStrHashNode { friend class VarStrHash; friend class VarStrHashIterator; private: int copyKeyFlag; char * hashString; void * hashData; VarStrHashNode * next; VarStrHashNode ( char * HashString, void * HashData, int copyKey=1); ~VarStrHashNode ( void ); }; class VarStrHash { friend class VarStrHashIterator; private: int tableSize; int copyKeyFlag; VarStrHashNode ** nodes; public: VarStrHash (int copyKey = 1, int TableSize = 255 ); ~VarStrHash ( void ); inline unsigned char stringHash ( char * hashString ); inline void insert ( char * hashString, void * hashData ); inline void remove ( char * hashString ); inline void * find ( char * hashString ); }; class VarStrHashIterator { private: VarStrHash * hashTbl; VarStrHashNode * node; int idx; public: VarStrHashIterator( VarStrHash * HashTbl ); ~VarStrHashIterator( void ); inline void * first ( void ); inline void * operator ++ ( void ); inline void * operator ++ ( int x ); inline char * key ( void ); inline void * data ( void ); }; inline VarStrHashNode::VarStrHashNode ( char * HashString, void * HashData, int copyKey ) : next(NULL), copyKeyFlag(copyKey) { if(copyKeyFlag) hashString = strdup(HashString); else hashString = HashString; hashData = HashData; } inline VarStrHashNode::~VarStrHashNode ( void ) { if(copyKeyFlag) delete hashString; } inline VarStrHash::VarStrHash ( int copyKey, int TableSize ) : copyKeyFlag(copyKey), tableSize (TableSize) { nodes = new VarStrHashNode * [tableSize]; memset(nodes, 0, sizeof(VarStrHashNode *) * tableSize ); } inline VarStrHash::~VarStrHash ( void ) { for(int i=0; inext; delete node; } } } inline unsigned char VarStrHash::stringHash ( char * hashString ) { unsigned char idx=0; unsigned int hash = 0, g; for (int i = 0; hashString[i] != '\0'; i++) { hash = (hash << 4) + hashString[i]; if (g = hash & 0xf0000000) { hash ^= g >> 24; hash ^= g; } } return (hash % tableSize); } inline void VarStrHash::insert (char * hashString, void * hashData ) { unsigned char idx = stringHash(hashString); VarStrHashNode * prev = NULL, * node = nodes[idx]; VarStrHashNode * newNode = new VarStrHashNode(hashString, hashData, copyKeyFlag); while(node!=NULL && strcmp(node->hashString, hashString)) { prev = node; node = prev->next; } if(node!=NULL) { newNode->next = node->next; delete node; } if(prev!=NULL) prev->next = newNode; else nodes[idx] = newNode; } inline void VarStrHash::remove ( char * hashString ) { unsigned char idx = stringHash(hashString); VarStrHashNode * prev = NULL, * node = nodes[idx]; while(node!=NULL && strcmp(node->hashString, hashString)) { prev = node; node = prev->next; } if(node!=NULL) { if(prev!=NULL) prev->next = node->next; else nodes[idx] = node->next; delete node; } } inline void * VarStrHash::find ( char * hashString ) { unsigned char idx = stringHash(hashString); VarStrHashNode * prev = NULL, * node = nodes[idx]; while(node!=NULL && strcmp(node->hashString, hashString)) { prev = node; node = prev->next; } return node!=NULL?node->hashData:NULL; } inline VarStrHashIterator::VarStrHashIterator(VarStrHash * HashTbl) : hashTbl(HashTbl), idx(0), node(NULL) { } inline VarStrHashIterator::~VarStrHashIterator( void ) { } inline void * VarStrHashIterator::first ( void ) { if(hashTbl!=NULL) { for(idx = 0; idxtableSize && (node = hashTbl->nodes[idx])==NULL; idx++); } else node = NULL; return (node!=NULL)?node->hashData:NULL; } inline void * VarStrHashIterator::operator ++ ( void ) { if(hashTbl!=NULL) { if(node==NULL) first(); else if(node->next!=NULL) node = node->next; else { node = NULL; do { idx++; } while(idxtableSize && (node = hashTbl->nodes[idx])==NULL); } } else node = NULL; return (node!=NULL)?node->hashData:NULL; } inline void * VarStrHashIterator::operator ++ ( int x ) { if(hashTbl!=NULL && x==0) { if(node==NULL) first(); else if(node->next!=NULL) node = node->next; else { node = NULL; do { idx++; } while(idxtableSize && (node = hashTbl->nodes[idx])==NULL); } } else node = NULL; return (node!=NULL)?node->hashData:NULL; } inline char * VarStrHashIterator::key ( void ) { return (node!=NULL)?node->hashString:NULL; } inline void * VarStrHashIterator::data ( void ) { return (node!=NULL)?node->hashData:NULL; } #endif /* _VAR_STRING_HASH_H_ */