/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts 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 . */ /* $Header: /VSS_Sync/wwlib/hash.cpp 3 10/17/00 4:48p Vss_sync $ */ /*********************************************************************************************** *** Confidential - Westwood Studios *** *********************************************************************************************** * * * Project Name : Commando / G 3D Library * * * * $Archive:: /VSS_Sync/wwlib/hash.cpp $* * * * Author:: Greg_h * * * * $Modtime:: 10/16/00 11:42a $* * * * $Revision:: 3 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "hash.h" #include "wwdebug.h" #include "realcrc.h" #ifdef _UNIX #include "osdep.h" #endif #include /* ** HashTableClass */ HashTableClass::HashTableClass( int size ) : HashTableSize( size ) { // Assert HashTableSize is a power of 2 WWASSERT( (HashTableSize & (HashTableSize-1)) == 0 ); // Allocate and clear the table HashTable = new HashableClass * [ HashTableSize ]; Reset(); } HashTableClass::~HashTableClass( void ) { // If we need to, free the hash table if ( HashTable != NULL) { delete [] HashTable; HashTable = NULL; } } void HashTableClass::Reset( void ) { for ( int i = 0; i < HashTableSize; i++ ) { HashTable[i] = NULL; } } void HashTableClass::Add( HashableClass * entry ) { WWASSERT( entry != NULL); int index = Hash( entry->Get_Key() ); WWASSERT( entry->NextHash == NULL ); entry->NextHash = HashTable[ index ]; HashTable[ index ] = entry; } bool HashTableClass::Remove( HashableClass * entry ) { WWASSERT(entry != NULL); // Find in the hash table. const char *key = entry->Get_Key(); int index = Hash( key ); if ( HashTable[ index ] != NULL ) { // Special check for first entry if ( HashTable[ index ] == entry ) { HashTable[ index ] = entry->NextHash; return true; } // Search the list for the entry, and remove it HashableClass * node = HashTable[ index ]; while ( node->NextHash != NULL ) { if ( node->NextHash == entry ) { node->NextHash = entry->NextHash; return true; } node = node->NextHash; } } return false; } HashableClass * HashTableClass::Find( const char * key ) { // Find in the hash table. int index = Hash( key ); for ( HashableClass * node = HashTable[ index ]; node != NULL; node = node->NextHash ) { if ( ::stricmp( node->Get_Key(), key ) == 0 ) { return node; } } return NULL; } int HashTableClass::Hash( const char * key ) { return CRC_Stringi( key ) & (HashTableSize-1); } /* ** */ void HashTableIteratorClass::First(void) { Index = 0; NextEntry = Table.HashTable[ Index ]; Advance_Next(); Next(); // Accept the next we found, and go to the next next } void HashTableIteratorClass::Next(void) { CurrentEntry = NextEntry; if ( NextEntry != NULL ) { NextEntry = NextEntry->NextHash; Advance_Next(); } } void HashTableIteratorClass::Advance_Next(void) { while ( NextEntry == NULL ) { Index++; if ( Index >= Table.HashTableSize ) { return; // Done! } NextEntry = Table.HashTable[ Index ]; } }