#include "Col.ph" #ifdef __GNUG__ #pragma implementation #endif #include "RobustHashTable.h" #include "Class.h" #include "Set.h" //---- RobustHashTable --------------------------------------------------------- NewMetaImpl(RobustHashTable,HashTable, (TVP(tab,capacity))); RobustHashTable::RobustHashTable(Set *aClient,int initCapacity, pEqualFunc eq, pHashFunc hsh, int *sz) : HashTable(initCapacity, eq, hsh, sz) { client= aClient; Init(); } RobustHashTable::~RobustHashTable() { SafeDelete(tab); SafeDelete(seq); } void RobustHashTable::Init() { int i; TabEntry entry; tab= new Object *[capacity + 1]; seq= new TabEntry[capacity + 1]; entry.nxt= capacity; entry.prv= capacity; for ( i= 0; i <= capacity; i++ ) { tab[i]= 0; seq[i]= entry; } } void RobustHashTable::Empty(int newCapacity) { SafeDelete(tab); SafeDelete(seq); CalcBounds(newCapacity); *size= 0; Init(); Changed(); } //----- iterator support -------- void *RobustHashTable::AtNextIndex(int &i) { i= seq[i].nxt; return tab[i]; } void *RobustHashTable::AtPrevIndex(int &i) { i= seq[i].prv; return tab[i]; } int RobustHashTable::GetInitialIndex() { return capacity; } //---- table primitives -------- void *RobustHashTable::KeyAt(int i) { return tab[i]; } void RobustHashTable::SetKeyAt(void *obj, int i) { TabEntry *prvp, *nxtp; tab[i]= (Object *) obj; nxtp= &seq[capacity]; prvp= &seq[nxtp->prv]; seq[i].Set(nxtp->prv, prvp->nxt); prvp->nxt= i; nxtp->prv= i; } void RobustHashTable::NullAt(int i) { int prv, nxt; tab[i]= 0; prv= seq[i].prv; nxt= seq[i].nxt; seq[prv].nxt= nxt; seq[nxt].prv= prv; seq[i].prv= capacity; seq[i].nxt= capacity; } void RobustHashTable::Swap(int i, int j) { Object *tmp; int prv, nxt; TabEntry entry; tmp= tab[i]; tab[i]= tab[j]; tab[j]= tmp; entry= seq[i]; seq[i]= seq[j]; seq[j]= entry; prv= seq[i].prv; nxt= seq[i].nxt; seq[prv].nxt= i; seq[nxt].prv= i; } void RobustHashTable::RemoveSlot(int slot) { if ( client->HasIterators() ) { client->SaveItersPosition(slot); HashTable::RemoveSlot(slot); client->ResetItersPosition(); } else HashTable::RemoveSlot(slot); } void RobustHashTable::Rehash(int newCapacity) { if ( newCapacity > capacity && client->HasIterators() ) { client->SaveItersPosition(cInvalidIndex); HashTable::Rehash(newCapacity); client->ResetItersPosition(); } else HashTable::Rehash(newCapacity); // rehash due to removal - iterator's position already saved } HashTable *RobustHashTable::MakeNew(int initCapacity) { return new RobustHashTable(client, initCapacity, equal, hash); } void RobustHashTable::Assign(HashTable *ht) { RobustHashTable *rht= (RobustHashTable *) ht; HashTable::Assign(ht); SafeDelete(tab); SafeDelete(seq); tab= rht->tab; seq= rht->seq; rht->tab= 0; rht->seq= 0; }