summaryrefslogtreecommitdiff
path: root/hmap.cpp
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2013-04-06 13:14:49 +0200
committerPaul Buetow <paul@buetow.org>2013-04-06 13:14:49 +0200
commit5ecef758a2826bd28dd0676940cd12ef6792126f (patch)
tree94454ed763dfbaf902eef267e1dcef0b30a0db4c /hmap.cpp
parent5a019f435eb0068b524566d9babf172d58d0e96e (diff)
tagging ychat-0.4ychat-0.4
Diffstat (limited to 'hmap.cpp')
-rw-r--r--hmap.cpp159
1 files changed, 78 insertions, 81 deletions
diff --git a/hmap.cpp b/hmap.cpp
index 6531ad0..662a203 100644
--- a/hmap.cpp
+++ b/hmap.cpp
@@ -12,11 +12,11 @@ int nextPrime( int n );
// Construct the hash table.
template <class obj_type, class key_type>
hmap<obj_type, key_type>::hmap( double mop )
- : maxOccupiedPercentage(mop), array( nextPrime( 101 ) )
+ : maxOccupiedPercentage(mop), array( nextPrime( 101 ) )
{
- cout << "hmap Constructor" << endl;
- lookups = 0;
- make_empty( );
+ cout << "hmap Constructor" << endl;
+ lookups = 0;
+ make_empty( );
}
// Insert item x into the hash table. If the item is
@@ -24,48 +24,48 @@ hmap<obj_type, key_type>::hmap( double mop )
template <class obj_type, class key_type>
void hmap<obj_type, key_type>::add_elem( const obj_type &x, const key_type &k )
{
- // Insert x as active
- int currentPos = findPos( k );
- if( isActive( currentPos ) )
- return;
-
- array[ currentPos ] = hash_entry( x, k, ACTIVE );
- // cout << "Inserted=" << x << "= at " << currentPos << endl;
- if( ++occupied > array.size( ) * maxOccupiedPercentage )
- rehash( );
+ // Insert x as active
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ return;
+
+ array[ currentPos ] = hash_entry( x, k, ACTIVE );
+ // cout << "Inserted=" << x << "= at " << currentPos << endl;
+ if( ++occupied > array.size( ) * maxOccupiedPercentage )
+ rehash( );
}
// Expand the hash table.
template <class obj_type, class key_type>
void hmap<obj_type, key_type>::rehash( )
{
- vector<hash_entry> oldArray = array;
-
- // Create new double-sized, empty table
- array.resize( nextPrime( 2 * oldArray.size( ) ) );
- for( int j = 0; j < array.size( ); j++ )
- array[ j ].info = EMPTY;
-
- // Copy table over
- make_empty( );
- for( int i = 0; i < oldArray.size( ); i++ )
- if( oldArray[ i ].info == ACTIVE )
- add_elem( oldArray[ i ].element, oldArray[ i ].key );
+ vector<hash_entry> oldArray = array;
+
+ // Create new double-sized, empty table
+ array.resize( nextPrime( 2 * oldArray.size( ) ) );
+ for( int j = 0; j < array.size( ); j++ )
+ array[ j ].info = EMPTY;
+
+ // Copy table over
+ make_empty( );
+ for( int i = 0; i < oldArray.size( ); i++ )
+ if( oldArray[ i ].info == ACTIVE )
+ add_elem( oldArray[ i ].element, oldArray[ i ].key );
}
// Hash function, can only handle strings.
-// If you want to hash other objects you will have to
+// If you want to hash other objects you will have to
// create a hash table for them
template <class obj_type, class key_type>
unsigned int hmap<obj_type, key_type>::hash( const string & key ) const
{
- unsigned int hashVal = 0;
- // cout << key << "%";
+ unsigned int hashVal = 0;
+ // cout << key << "%";
- for( size_t i = 0; i < key.size(); i++ )
- hashVal = ( hashVal << 5 ) ^ key[ i ] ^ hashVal;
+ for( size_t i = 0; i < key.size(); i++ )
+ hashVal = ( hashVal << 5 ) ^ key[ i ] ^ hashVal;
- return hashVal;
+ return hashVal;
}
// Method that performs quadratic probing resolution.
@@ -73,32 +73,32 @@ unsigned int hmap<obj_type, key_type>::hash( const string & key ) const
template <class obj_type, class key_type>
int hmap<obj_type, key_type>::findPos( const key_type &k )
{
- int collisionNum = 0;
- int currentPos = hash( k ) % array.size( );
+ int collisionNum = 0;
+ int currentPos = hash( k ) % array.size( );
+ lookups++;
+
+ while( array[ currentPos ].info != EMPTY &&
+ array[ currentPos ].key != k )
+ {
+ // cout << array[ currentPos ].element << "!=" << x << endl;
lookups++;
+ currentPos += 2 * ++collisionNum - 1; // Compute ith probe
- while( array[ currentPos ].info != EMPTY &&
- array[ currentPos ].key != k )
- {
- // cout << array[ currentPos ].element << "!=" << x << endl;
- lookups++;
- currentPos += 2 * ++collisionNum - 1; // Compute ith probe
+ if( currentPos >= array.size( ) )
+ currentPos -= array.size( );
+ }
- if( currentPos >= array.size( ) )
- currentPos -= array.size( );
- }
-
- // cout << currentPos << " ";
- return currentPos;
+ // cout << currentPos << " ";
+ return currentPos;
}
// Remove item x from the hash table.
template <class obj_type, class key_type>
void hmap<obj_type, key_type>::del_elem( const key_type & k )
{
- int currentPos = findPos( k );
- if( isActive( currentPos ) )
- array[ currentPos ].info = DELETED;
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ array[ currentPos ].info = DELETED;
}
// Find item x in the hash table.
@@ -106,46 +106,46 @@ void hmap<obj_type, key_type>::del_elem( const key_type & k )
template <class obj_type, class key_type>
obj_type hmap<obj_type, key_type>::get_elem( const key_type &k )
{
- int currentPos = findPos( k );
- if( isActive( currentPos ) )
- return array[ currentPos ].element;
- else
- return 0;
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ return array[ currentPos ].element;
+ else
+ return 0;
}
// Make the hash table logically empty.
template <class obj_type, class key_type>
void hmap<obj_type, key_type>::make_empty( )
{
- occupied = 0;
- for( int i = 0; i < array.size( ); i++ )
- array[ i ].info = EMPTY;
+ occupied = 0;
+ for( int i = 0; i < array.size( ); i++ )
+ array[ i ].info = EMPTY;
}
// Return true if currentPos exists and is active.
template <class obj_type, class key_type>
bool hmap<obj_type, key_type>::isActive( int currentPos ) const
{
- return array[ currentPos ].info == ACTIVE;
+ return array[ currentPos ].info == ACTIVE;
}
// Internal method to test if a positive number is prime.
// Not an efficient algorithm.
template <class obj_type, class key_type>
-bool hmap<obj_type, key_type>::isPrime( int n ) const
+bool hmap<obj_type, key_type>::isPrime( int n ) const
{
- if( n == 2 || n == 3 )
- return true;
+ if( n == 2 || n == 3 )
+ return true;
- else if( n == 1 || n % 2 == 0 )
- return false;
+ else if( n == 1 || n % 2 == 0 )
+ return false;
- for( int i = 3; i * i <= n; i += 2 )
- if( n % i == 0 )
- return false;
+ for( int i = 3; i * i <= n; i += 2 )
+ if( n % i == 0 )
+ return false;
- return true;
+ return true;
}
// Internal method to return a prime number at least as large as n.
@@ -153,30 +153,27 @@ bool hmap<obj_type, key_type>::isPrime( int n ) const
template <class obj_type, class key_type>
int hmap<obj_type, key_type>::nextPrime( int n ) const
{
- if( n % 2 == 0 )
- n++;
+ if( n % 2 == 0 )
+ n++;
- for( ; !isPrime( n ); n += 2 )
- ;
+ for( ; !isPrime( n ); n += 2 );
- return n;
+ return n;
}
-template<class obj_type, class key_type>
-void
+template<class obj_type, class key_type> void
hmap<obj_type, key_type>::run_func( void (*func)(obj_type) )
{
- for( int i = 0; i < array.size( ); i++ )
- if ( array[i].info == ACTIVE )
- ( *func ) ( array[i].element );
+ for( int i = 0; i < array.size( ); i++ )
+ if ( array[i].info == ACTIVE )
+ ( *func ) ( array[i].element );
}
-template<class obj_type, class key_type>
-void
+template<class obj_type, class key_type> void
hmap<obj_type, key_type>::run_func( void (*func)(obj_type, void*), void* v_arg )
{
- for( int i = 0; i < array.size( ); i++ )
- if ( array[i].info == ACTIVE )
- ( *func ) ( array[i].element, v_arg );
+ for( int i = 0; i < array.size( ); i++ )
+ if ( array[i].info == ACTIVE )
+ ( *func ) ( array[i].element, v_arg );
}
#endif