Files
firestorm/Gameleap/code/mw4/Libraries/stuff/Hash.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

625 lines
14 KiB
C++

//===========================================================================//
// File: hash.cc //
// Project: MUNGA Brick: Connection Library //
// Contents: Implementation details of Hash class //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 12/15/94 ECH Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hash ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//###########################################################################
// Hash
//###########################################################################
//
Hash::Hash(
unsigned size,
void *node,
bool has_unique_entries
):
SortedSocket(NULL, has_unique_entries)
{
//
// If the size is not prime, warn and select new size
//
#if defined(_ARMOR)
if (!CheckForPrimeSize(size))
{
while (!CheckForPrimeSize(size))
size++;
PAUSE(("Non-prime hash table, correct size is %d", size));
}
#endif
//
//---------------------
// Initialize the table
//---------------------
//
m_hashTable.SetLength(size);
for (unsigned i=0; i<size; i++)
{
m_hashTable[i] = NULL;
}
}
//
//###########################################################################
// ~Hash
//###########################################################################
//
Hash::~Hash()
{
Check_Object(this);
int i;
for (i=0; i<m_hashTable.GetLength(); i++)
{
if (m_hashTable[i] != NULL)
{
Check_Object(m_hashTable[i]);
delete m_hashTable[i];
}
}
m_hashTable.SetLength(0);
}
//
//###########################################################################
// TestInstance
//###########################################################################
//
void
Hash::TestInstance()
{
SortedSocket::TestInstance();
Verify(m_hashTable.GetLength() > 0);
}
//
//###########################################################################
// DeletePlugs
//###########################################################################
//
void
Hash::DeletePlugs()
{
Check_Object(this);
int i;
for (i=0; i<m_hashTable.GetLength(); i++)
{
if (m_hashTable[i] != NULL)
{
Check_Object(m_hashTable[i]);
m_hashTable[i]->DeletePlugs();
delete m_hashTable[i];
m_hashTable[i] = NULL;
}
}
}
//
//###########################################################################
// GetNthItem
//###########################################################################
//
void*
Hash::GetNthItem(unsigned index)
{
STOP(("Not implemented"));
return NULL;
}
//
//###########################################################################
// GetSize
//###########################################################################
//
unsigned
Hash::GetSize()
{
Check_Object(this);
HashIterator iterator(this);
unsigned i = 0;
while (iterator.ReadAndNextItem() != NULL)
i++;
return i;
}
//
//#############################################################################
// IsEmpty
//#############################################################################
//
bool
Hash::IsEmpty()
{
Check_Object(this);
for (int i = 0; i < m_hashTable.GetLength(); i++)
{
if (m_hashTable[i] != NULL)
{
if (!m_hashTable[i]->IsEmpty())
return false;
}
}
return true;
}
//
//###########################################################################
// AddValueImplementation
//###########################################################################
//
void
Hash::AddValuePlug(
Plug *plug,
const void *value
)
{
Check_Object(this);
Check_Object(plug);
Check_Pointer(value);
//
//-------------------------------------------------------------
// Verify that value has not been added
//-------------------------------------------------------------
//
Verify(HasUniqueEntries() ? (FindPlug(value) == NULL) : true);
//
//-------------------------------------------------------------
// Find hash entry
//-------------------------------------------------------------
//
unsigned index = GetHashIndex(value);
//
//-------------------------------------------------------------
// Get vchain for this index
//-------------------------------------------------------------
//
SortedChain *vchain;
if ((vchain = m_hashTable[index]) == NULL)
{
vchain = MakeSortedChain();
Check_Object(vchain);
m_hashTable[index] = vchain;
}
//
//-------------------------------------------------------------
// Add to the vchain
//-------------------------------------------------------------
//
Check_Object(vchain);
vchain->AddValuePlug(plug, value);
}
//
//###########################################################################
// FindPlug
//###########################################################################
//
Plug*
Hash::FindPlug(
const void *value
)
{
Check_Object(this);
Check_Pointer(value);
//
//-------------------------------------------------------------
// Find hash entry
//-------------------------------------------------------------
//
unsigned index;
index = GetHashIndex(value);
//
//-------------------------------------------------------------
// Get vchain for this index
//-------------------------------------------------------------
//
SortedChain *vchain;
if ((vchain = m_hashTable[index]) == NULL)
return NULL;
//
//-------------------------------------------------------------
// Find in vchain
//-------------------------------------------------------------
//
Check_Object(vchain);
return vchain->FindPlug(value);
}
//
//###########################################################################
// CheckForPrimeSize
//###########################################################################
//
bool
Hash::CheckForPrimeSize(unsigned size)
{
Check_Signature(this);
Verify(size > 2);
unsigned upper_bound =
static_cast<unsigned>(Sqrt(static_cast<Scalar>(size)));
for (unsigned i = 2; i < upper_bound; i++)
{
if ((size % i) == 0)
return false;
}
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ HashIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~
const unsigned HashIteratorNullPosition = -1;
//
//###########################################################################
// HashIterator
//###########################################################################
//
HashIterator::HashIterator(Hash *hash):
SortedIterator(hash)
{
m_currentPosition = HashIteratorNullPosition;
m_vchainIterator = NULL;
First();
}
Iterator*
HashIterator::MakeClone()
{
Check_Object(this);
return new(g_Heap) HashIterator(*this);
}
HashIterator::~HashIterator()
{
Check_Object(this);
m_currentPosition = HashIteratorNullPosition;
DeleteSortedChainIterator();
}
//
//###########################################################################
// TestInstance
//###########################################################################
//
void
HashIterator::TestInstance()
{
SortedIterator::TestInstance();
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
}
}
//
//###########################################################################
// First
//###########################################################################
//
Iterator&
HashIterator::First()
{
Check_Object(this);
NextSortedChainIterator(0);
return *this;
}
//
//###########################################################################
// Last
//###########################################################################
//
Iterator&
HashIterator::Last()
{
Check_Object(this);
STOP(("Shouldn't reach here"));
return *this;
}
//
//###########################################################################
// Next
//###########################################################################
//
Iterator&
HashIterator::Next()
{
Check_Object(this);
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
if (m_vchainIterator->GetCurrentPlug() != NULL)
{
//
// Try to step to the next item in this list
//
m_vchainIterator->Next();
}
if (m_vchainIterator->GetCurrentPlug() == NULL)
{
//
// At end of list, step to the next list
//
NextSortedChainIterator(m_currentPosition+1);
}
}
return *this;
}
//
//###########################################################################
// Previous
//###########################################################################
//
Iterator&
HashIterator::Previous()
{
Check_Object(this);
STOP(("Not implemented"));
return *this;
}
//
//###########################################################################
// ReadAndNextItem
//###########################################################################
//
void*
HashIterator::ReadAndNextItem()
{
Check_Object(this);
void *result = NULL;
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
if (m_vchainIterator->GetCurrentPlug() != NULL)
{
result = m_vchainIterator->GetCurrentPlug();
m_vchainIterator->Next();
}
//
// List was emptied, step to next list
//
else
{
NextSortedChainIterator(m_currentPosition+1);
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
Verify(m_vchainIterator->GetCurrentPlug() != NULL);
result = m_vchainIterator->GetCurrentPlug();
m_vchainIterator->Next();
}
}
}
return result;
}
//
//###########################################################################
// Previous
//###########################################################################
//
void*
HashIterator::ReadAndPreviousItem()
{
Check_Object(this);
void *result = GetCurrentItem();
HashIterator::Previous();
return result;
}
//
//###########################################################################
// GetCurrentImplementation
//###########################################################################
//
void
*HashIterator::GetCurrentItem()
{
Check_Object(this);
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
if (m_vchainIterator->GetCurrentPlug() != NULL)
{
return m_vchainIterator->GetCurrentPlug();
}
//
// List was emptied, step to next list
//
NextSortedChainIterator(m_currentPosition+1);
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
Verify(m_vchainIterator->GetCurrentPlug() != NULL);
return m_vchainIterator->GetCurrentPlug();
}
}
return NULL;
}
//
//###########################################################################
// GetNthItem
//###########################################################################
//
void*
HashIterator::GetNthItem(unsigned index)
{
unsigned i = 0;
NextSortedChainIterator(0);
while (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
while (m_vchainIterator->GetCurrentPlug() != NULL)
{
if (i == index)
return m_vchainIterator->GetCurrentPlug();
m_vchainIterator->Next();
i++;
}
//
// List was emptied, step to next list
//
NextSortedChainIterator(m_currentPosition+1);
}
return NULL;
}
//
//###########################################################################
// Remove
//###########################################################################
//
void
HashIterator::Remove()
{
Check_Object(this);
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
if (m_vchainIterator->GetCurrentPlug() != NULL)
{
m_vchainIterator->Remove();
return;
}
//
// List was emptied, step to next list
//
NextSortedChainIterator(m_currentPosition+1);
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
m_vchainIterator->Remove();
return;
}
}
}
//
//###########################################################################
// FindPlug
//###########################################################################
//
Plug
*HashIterator::FindPlug(
const void*
)
{
Check_Object(this);
STOP(("Not implemented"));
return NULL;
}
//
//###########################################################################
// GetPlugValue
//###########################################################################
//
void*
HashIterator::GetPlugValue()
{
Check_Object(this);
STOP(("Not implemented"));
return NULL;
}
//
//###########################################################################
//###########################################################################
//
void
HashIterator::DeleteSortedChainIterator()
{
if (m_vchainIterator != NULL)
{
Check_Object(m_vchainIterator);
delete m_vchainIterator;
m_vchainIterator = NULL;
}
}
//
//###########################################################################
//###########################################################################
//
void
HashIterator::NextSortedChainIterator(unsigned index)
{
Check_Object(this);
int i;
DeleteSortedChainIterator();
m_currentPosition = HashIteratorNullPosition;
DynamicArrayOf<SortedChain*> &hash_table =
Cast_Object(Hash*, m_socket)->m_hashTable;
for (i = index; i < hash_table.GetLength(); i++)
{
if (hash_table[i] != NULL)
{
//
// This index contains a vchain
//
Check_Object(hash_table[i]);
//
// Create a vchain iterator
//
m_vchainIterator = new(g_Heap) SortedChainIterator(hash_table[i]);
Check_Object(m_vchainIterator);
if (m_vchainIterator->GetCurrentPlug() != NULL)
{
//
// The vchain contains items
//
m_currentPosition = i;
return;
}
//
// Destroy the vchain iterator
//
DeleteSortedChainIterator();
}
}
}