From 6f6bb9f9309a6d5e471579ec565d56e4d083dafb Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 21 Nov 2006 16:01:57 +0000 Subject: Added erase functionality, and specializations for using ints as hash keys, so really it does everything the old one did, does it better, easier, and possibly faster. --- src/hash.cpp | 20 +++++ src/hash.h | 247 +++++++++++++++++++++++++++++++---------------------- src/tests/hash.cpp | 26 ++++-- 3 files changed, 184 insertions(+), 109 deletions(-) diff --git a/src/hash.cpp b/src/hash.cpp index 14be208..0241753 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,5 +1,25 @@ #include "hash.h" +template<> uint32_t __calcHashCode( const int k ) +{ + return k; +} + +template<> bool __cmpHashKeys( const int a, const int b ) +{ + return a == b; +} + +template<> uint32_t __calcHashCode( int k ) +{ + return k; +} + +template<> bool __cmpHashKeys( int a, int b ) +{ + return a == b; +} + template<> uint32_t __calcHashCode( const char * k ) { diff --git a/src/hash.h b/src/hash.h index c4f4b43..ff3bafd 100644 --- a/src/hash.h +++ b/src/hash.h @@ -40,8 +40,9 @@ private: { } - HashProxy( Hash &h, _value *pValue ) : + HashProxy( Hash &h, uint32_t nPos, _value *pValue ) : hsh( h ), + nPos( nPos ), pValue( pValue ), bFilled( true ) { @@ -74,6 +75,12 @@ public: return bFilled; } + void erase() + { + if( bFilled ) + hsh._erase( nPos ); + } + _value operator=( _value nval ) { if( bFilled ) @@ -119,10 +126,11 @@ public: for( uint32_t j = 0; j < nCapacity; j++ ) { if( isFilled( j ) ) - { - va.destroy( &aValues[j] ); - ka.destroy( &aKeys[j] ); - } + if( !isDeleted( j ) ) + { + va.destroy( &aValues[j] ); + ka.destroy( &aKeys[j] ); + } } va.deallocate( aValues, nCapacity ); ka.deallocate( aKeys, nCapacity ); @@ -167,7 +175,7 @@ public: if( bFill ) { - return HashProxy( *this, &aValues[nPos] ); + return HashProxy( *this, nPos, &aValues[nPos] ); } else { @@ -192,7 +200,7 @@ public: } } - value get( key k ) + void erase( key k ) { uint32_t hash = __calcHashCode( k ); bool bFill; @@ -200,110 +208,24 @@ public: if( bFill ) { - return aValues[nPos]; - } - else - { - throw "Hey, no such thing..."; - } - } - - uint32_t probe( uint32_t hash, key k, bool &bFill, bool rehash=true ) - { - uint32_t nCur = hash%nCapacity; - - // First we scan to see if the key is already there, abort if we - // run out of probing room, or we find a non-filled entry - for( int8_t j = 0; - isFilled( nCur ) && j < 32; - nCur = (nCur + (1< getAtPos( uint32_t nPos ) { return std::pair(aKeys[nPos],aValues[nPos]); @@ -404,7 +333,8 @@ private: for( uint32_t j = 0; j < nCapacity; j++ ) { if( isFilled( j ) ) - return j; + if( !isDeleted( j ) ) + return j; } bFinished = true; @@ -415,12 +345,115 @@ private: for( uint32_t j = nPos+1; j < nCapacity; j++ ) { if( isFilled( j ) ) - return j; + if( !isDeleted( j ) ) + return j; } bFinished = true; } + uint32_t probe( uint32_t hash, key k, bool &bFill, bool rehash=true ) + { + uint32_t nCur = hash%nCapacity; + + // First we scan to see if the key is already there, abort if we + // run out of probing room, or we find a non-filled entry + for( int8_t j = 0; + isFilled( nCur ) && j < 32; + nCur = (nCur + (1< uint32_t __calcHashCode( const int k ); +template<> bool __cmpHashKeys( const int a, const int b ); + +template<> uint32_t __calcHashCode( int k ); +template<> bool __cmpHashKeys( int a, int b ); + template<> uint32_t __calcHashCode( const char *k ); template<> bool __cmpHashKeys( const char *a, const char *b ); diff --git a/src/tests/hash.cpp b/src/tests/hash.cpp index 8406439..f9a8f12 100644 --- a/src/tests/hash.cpp +++ b/src/tests/hash.cpp @@ -67,11 +67,9 @@ int main() } printf("Getting\n-------------------\n\n"); - printf("%d\n", sTest.get( names[10] ) ); - printf("%d\n", (int)sTest[names[10]] ); - sTest[names[10]] = 22; - sTest["That one guy"] = 135; - printf("%d\n", (int)sTest[names[10]] ); + + sTest.erase("Homer the Great"); + sTest["Bart's Comet"].erase(); for( Hash::iterator i = sTest.begin(); i != sTest.end(); i++ ) @@ -79,5 +77,23 @@ int main() Hash::iterator j = i; printf("%d: %s\n", (*j).second, (*j).first.c_str() ); } + + for( int j = 0; j < 33; j++ ) + { + if( sTest[names[j]].isFilled() ) + { + if( sTest[names[j]] != j ) + { + printf("'%s' should be %d, is %d\n", + names[j], j, + sTest[names[j]].value() + ); + } + } + else + { + printf("Missing element %d, '%s'\n", j, names[j] ); + } + } } -- cgit v1.2.3