/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ // hsHashTable.h #ifndef _hsHashTable_Included_ #define _hsHashTable_Included_ #include "hsTemplates.h" template class hsHashTableIterator { public: hsHashTableIterator() : fList(nil), fIndex(-1) { } explicit hsHashTableIterator(hsTArray* list, UInt32 idx) : fList(list), fIndex(idx) { } T* operator->() const { return &((*fList)[fIndex]); } T& operator*() const { return (*fList)[fIndex]; } hsHashTableIterator& operator++() { fIndex--; return *this; } const hsHashTableIterator& operator++(int) { hsHashTableIterator temp(*this); --(*this); return temp; } hsHashTableIterator& operator--() { fIndex++; return *this; } const hsHashTableIterator& operator--(int) { hsHashTableIterator temp(*this); ++(*this); return temp; } hsBool operator==(const hsHashTableIterator& other) const { return fList==other.fList && fIndex==other.fIndex; } hsBool operator!=(const hsHashTableIterator& other) const { return !(*this == other); } private: hsTArray* fList; UInt32 fIndex; }; template class hsHashTable { public: hsHashTable(UInt32 size=150001, UInt32 step=1); ~hsHashTable(); typedef hsHashTableIterator iterator; iterator begin() { return iterator(&fItemList,fItemList.Count()-1); } iterator end() { return iterator(&fItemList,0); } void clear(); UInt32 count() { return fItemList.Count()-1; } UInt32 size() { return fSize; } UInt32 CollisionCount() { return fCollisionCount; } inline void insert(T& item); inline void erase(T& item); inline iterator find(const T& item); iterator GetItem(UInt32 i); private: hsTArray fItemList; hsTArray fClearList; UInt32* fHashTable; UInt32 fSize; UInt32 fCollisionStep; UInt32 fCollisionCount; // No copy or assignment hsHashTable(const hsHashTable&); hsHashTable &operator=(const hsHashTable&); }; template hsHashTable::hsHashTable(UInt32 size, UInt32 step) : fSize(size), fCollisionStep(step), fCollisionCount(0) { fItemList.SetCount(1); fHashTable = TRACKED_NEW UInt32[fSize]; memset(fHashTable,0,fSize*sizeof(UInt32)); } template hsHashTable::~hsHashTable() { delete [] fHashTable; } template void hsHashTable::clear() { fItemList.SetCount(1); for (Int32 i=0; i void hsHashTable::insert(T& item) { hsAssert(fClearList.Count() < fSize,"Hash table overflow! Increase the table size."); UInt32 h = item.GetHash(); h %= fSize; while (UInt32 it = fHashTable[h]) { if ( fItemList[it] == item) { fItemList[it] = item; return; } h += fCollisionStep; h %= fSize; fCollisionCount++; } fHashTable[h] = fItemList.Count(); fItemList.Append(item); fClearList.Append(h); } template void hsHashTable::erase(T& item) { UInt32 h = item.GetHash(); h %= fSize; while (UInt32 it = fHashTable[h]) { if ( fItemList[it] == item ) { fHashTable[h] = 0; return; } } } template hsHashTableIterator hsHashTable::find(const T& item) { UInt32 h = item.GetHash(); h %= fSize; while (UInt32 it = fHashTable[h]) { if ( fItemList[it] == item ) { return iterator(&fItemList,it); } h += fCollisionStep; h %= fSize; fCollisionCount++; } return end(); } template hsHashTableIterator hsHashTable::GetItem(UInt32 i) { return iterator(&fItemList,i+1); } #endif // _hsHashTable_Included_