mud++0.35/etc/
mud++0.35/etc/guilds/
mud++0.35/help/propert/
mud++0.35/mudC/
mud++0.35/player/
mud++0.35/src/interface/
mud++0.35/src/os/cygwin32/
mud++0.35/src/os/win32/
mud++0.35/src/os/win32/bcppbuilder/
mud++0.35/src/osaddon/
mud++0.35/src/util/
/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@hom.net 
MUD++ development mailing list    mudpp@van.ml.org
------------------------------------------------------------------------------
hash.cc
*/

// TEMPLATE FILE

template< class T >
void HashTable< T >::reset() const
{
	for( int i = 0; i < HASH_KEY; i++ )
	{
		table[ i ].reset();
		if( table[ i ].peek() )
		{
			// Override const member
			//const_cast< HashTable< T > * >(this)->ihash = i;
			((HashTable< T > *)this)->ihash = i;
			return;
		}
	}
}


template< class T >
const HashTable< T > & HashTable< T >::next() const
{
	int i;

	table[ ihash ].next();
	if( !table[ ihash ].peek() && ihash < HASH_KEY -1 )
	{
		for( i = ihash + 1; i < HASH_KEY; i++ )
		{
			table[ i ].reset();
			if( table[ i ].peek() )
			{
				//const_cast< HashTable< T > * >(this)->ihash = i;
				((HashTable< T > * )this)->ihash = i;
				return *this;
			}
		}
	}

	return *this;
}


template < class T >
void HashTable< T >::clr()
{
	HashNode * ptr;

	for( ihash = 0; ihash < HASH_KEY; ihash++ )
	{
		table[ ihash ].reset();
		while( ( ptr = table[ ihash ].remove() ) )
		{
//			delete (T*)ptr->getObj();
			delete ptr;
		}
	}
}


// Dont want to change the internal state of container so create
// tlist to do iterating. 
template < class T >
T * HashTable< T >::lookup( const char * x )
{
	HashNode * ptr;
	LList< HashNode > tlist = table[ getHashKey( x ) ];
	tlist.reset();
	while( ( ptr = tlist.peek() ) )
	{
		tlist.next();
		if( ptr->getKey() == x )
			return (T*)ptr->getObj(); 
	}

	return 0;
}


template < class T >
void HashTable< T >::remove( const char * x )
{
	HashNode * ptr;
	int ihash = getHashKey( x );
	LList< HashNode > tlist = table[ ihash ];
	tlist.reset();
	while( ( ptr = tlist.peek() ) )
	{
		tlist.next();
		if( ptr->getKey() == x )
		{
			table[ ihash ].remove( ptr ); 
			return;
		}
	}
}


template < class T >
void HashTable< T >::removeAllInstancesOf(T * what)
{
	HashNode * ptr;

	for( ihash = 0; ihash < HASH_KEY; ihash++ )
	{
		for_each( table[ ihash ], ptr )
		{
			if ( (T*)ptr->getObj() == what )
			{
				// Maybe just remove() will do ?
				table[ ihash ].remove( ptr );
				delete ptr;
			}
		}
	}
}



// Need to work on the hasher, this will not hash effectively
// over large table sizes. For now its good enough.
template< class T >
 int HashTable< T >::getHashKey( const char * str )
{
	int key = (int)str[0];
	key <<= 2;
	if( str[0] )
		key |= (int)str[1]; // be it null or not
	return key % HASH_KEY;
}


template < class T >
 T * HashTable< T >::peek() const
{
	HashNode *x = table[ ihash ].peek();
	if( x )
		return (T*)x->getObj();
	return 0;
}

template < class T >
T * HashTable< T >::remove()
{

	int i;
	HashNode *x;

	x = table[ ihash ].remove();
	if( !x && ihash < HASH_KEY -1 )
	{
		for( i = ihash + 1; i < HASH_KEY; i++ )
		{
			table[ i ].reset();
			if( (x = table[ i ].remove()) )
			{
				((HashTable< T > * )this)->ihash = i;
				return (T*)x->getObj();
			}
		}
	}
	else if ( x )
	{
		return (T*)x->getObj();
	}
	
	return 0;

}


template < class T >
 const String & HashTable< T >::getKey() const
{
	static String empty;

	HashNode *x = table[ ihash ].peek();
	if( x )
		return x->getKey();

	return empty;
}


template < class T >
 T * HashTable< T >::lookup( const String & x )
{
	return lookup( x.chars() );
}


template < class T >
 void HashTable< T >::add( const String & x, T * y )
{
	HashNode *ptr = new HashNode( x, (void*)y );
	int i = getHashKey( ptr->getKey() );
	table[ i ].addTop( ptr );
}


template < class T >
 void HashTable< T >::remove( const String & x )
{
	remove( x.chars() );
}