diff options
Diffstat (limited to '')
-rw-r--r-- | src/hash.h | 65 |
1 files changed, 59 insertions, 6 deletions
@@ -25,10 +25,12 @@ bool __cmpHashKeys( T a, T b ); | |||
25 | 25 | ||
26 | struct __calcNextTSize_fast | 26 | struct __calcNextTSize_fast |
27 | { | 27 | { |
28 | uint32_t operator()( uint32_t nCapacity, uint32_t nFill, uint32_t nDeleted ) const | 28 | uint32_t operator()( uint32_t nCapacity, uint32_t nFill, uint32_t nDeleted ) const |
29 | { | 29 | { |
30 | return nCapacity*2+1; | 30 | if( nDeleted >= nCapacity/2 ) |
31 | } | 31 | return nCapacity; |
32 | return nCapacity*2+1; | ||
33 | } | ||
32 | }; | 34 | }; |
33 | 35 | ||
34 | template<typename key, typename value, typename sizecalc = __calcNextTSize_fast, typename keyalloc = std::allocator<key>, typename valuealloc = std::allocator<value>, typename challoc = std::allocator<uint32_t> > | 36 | template<typename key, typename value, typename sizecalc = __calcNextTSize_fast, typename keyalloc = std::allocator<key>, typename valuealloc = std::allocator<value>, typename challoc = std::allocator<uint32_t> > |
@@ -295,6 +297,18 @@ public: | |||
295 | } | 297 | } |
296 | } | 298 | } |
297 | 299 | ||
300 | struct iterator; | ||
301 | virtual void erase( struct iterator &i ) | ||
302 | { | ||
303 | if( this != &i.hsh ) | ||
304 | throw HashException("This iterator didn't come from this Hash."); | ||
305 | if( isFilled( i.nPos ) && !isDeleted( i.nPos ) ) | ||
306 | { | ||
307 | _erase( i.nPos ); | ||
308 | onDelete(); | ||
309 | } | ||
310 | } | ||
311 | |||
298 | virtual void clear() | 312 | virtual void clear() |
299 | { | 313 | { |
300 | for( uint32_t j = 0; j < nCapacity; j++ ) | 314 | for( uint32_t j = 0; j < nCapacity; j++ ) |
@@ -399,10 +413,29 @@ public: | |||
399 | return !(*this == oth ); | 413 | return !(*this == oth ); |
400 | } | 414 | } |
401 | 415 | ||
416 | iterator operator=( const iterator &oth ) | ||
417 | { | ||
418 | if( &hsh != &oth.hsh ) | ||
419 | throw HashException( | ||
420 | "Cannot mix iterators from different hash objects."); | ||
421 | nPos = oth.nPos; | ||
422 | bFinished = oth.bFinished; | ||
423 | } | ||
424 | |||
402 | std::pair<key,value> operator *() | 425 | std::pair<key,value> operator *() |
403 | { | 426 | { |
404 | return hsh.getAtPos( nPos ); | 427 | return hsh.getAtPos( nPos ); |
405 | } | 428 | } |
429 | |||
430 | key &getKey() | ||
431 | { | ||
432 | return hsh.getKeyAtPos( nPos ); | ||
433 | } | ||
434 | |||
435 | value &getValue() | ||
436 | { | ||
437 | return hsh.getValueAtPos( nPos ); | ||
438 | } | ||
406 | }; | 439 | }; |
407 | 440 | ||
408 | iterator begin() | 441 | iterator begin() |
@@ -436,6 +469,8 @@ protected: | |||
436 | ka.construct( &aKeys[loc], k ); | 469 | ka.construct( &aKeys[loc], k ); |
437 | aHashCodes[loc] = hash; | 470 | aHashCodes[loc] = hash; |
438 | nFilled++; | 471 | nFilled++; |
472 | //printf("Filled: %d, Deleted: %d, Capacity: %d\n", | ||
473 | // nFilled, nDeleted, nCapacity ); | ||
439 | } | 474 | } |
440 | 475 | ||
441 | virtual void _erase( uint32_t loc ) | 476 | virtual void _erase( uint32_t loc ) |
@@ -443,12 +478,25 @@ protected: | |||
443 | bDeleted[loc/32] |= (1<<(loc%32)); | 478 | bDeleted[loc/32] |= (1<<(loc%32)); |
444 | va.destroy( &aValues[loc] ); | 479 | va.destroy( &aValues[loc] ); |
445 | ka.destroy( &aKeys[loc] ); | 480 | ka.destroy( &aKeys[loc] ); |
481 | nDeleted++; | ||
482 | //printf("Filled: %d, Deleted: %d, Capacity: %d\n", | ||
483 | // nFilled, nDeleted, nCapacity ); | ||
446 | } | 484 | } |
447 | 485 | ||
448 | virtual std::pair<key,value> getAtPos( uint32_t nPos ) | 486 | virtual std::pair<key,value> getAtPos( uint32_t nPos ) |
449 | { | 487 | { |
450 | return std::pair<key,value>(aKeys[nPos],aValues[nPos]); | 488 | return std::pair<key,value>(aKeys[nPos],aValues[nPos]); |
451 | } | 489 | } |
490 | |||
491 | virtual key &getKeyAtPos( uint32_t nPos ) | ||
492 | { | ||
493 | return aKeys[nPos]; | ||
494 | } | ||
495 | |||
496 | virtual value &getValueAtPos( uint32_t nPos ) | ||
497 | { | ||
498 | return aValues[nPos]; | ||
499 | } | ||
452 | 500 | ||
453 | virtual uint32_t getFirstPos( bool &bFinished ) | 501 | virtual uint32_t getFirstPos( bool &bFinished ) |
454 | { | 502 | { |
@@ -521,6 +569,10 @@ protected: | |||
521 | 569 | ||
522 | void reHash( uint32_t nNewSize ) | 570 | void reHash( uint32_t nNewSize ) |
523 | { | 571 | { |
572 | //printf("---REHASH---"); | ||
573 | //printf("Filled: %d, Deleted: %d, Capacity: %d\n", | ||
574 | // nFilled, nDeleted, nCapacity ); | ||
575 | |||
524 | // Save all the old data | 576 | // Save all the old data |
525 | uint32_t nOldCapacity = nCapacity; | 577 | uint32_t nOldCapacity = nCapacity; |
526 | uint32_t *bOldFilled = bFilled; | 578 | uint32_t *bOldFilled = bFilled; |
@@ -543,12 +595,13 @@ protected: | |||
543 | aKeys = ka.allocate( nCapacity ); | 595 | aKeys = ka.allocate( nCapacity ); |
544 | aValues = va.allocate( nCapacity ); | 596 | aValues = va.allocate( nCapacity ); |
545 | 597 | ||
546 | nFilled = 0; | 598 | nDeleted = nFilled = 0; |
547 | 599 | ||
548 | // Re-insert all of the old data (except deleted items) | 600 | // Re-insert all of the old data (except deleted items) |
549 | for( uint32_t j = 0; j < nOldCapacity; j++ ) | 601 | for( uint32_t j = 0; j < nOldCapacity; j++ ) |
550 | { | 602 | { |
551 | if( (bOldFilled[j/32]&(1<<(j%32)))!=0 ) | 603 | if( (bOldFilled[j/32]&(1<<(j%32)))!=0 && |
604 | (bOldDeleted[j/32]&(1<<(j%32)))==0 ) | ||
552 | { | 605 | { |
553 | insert( aOldKeys[j], aOldValues[j] ); | 606 | insert( aOldKeys[j], aOldValues[j] ); |
554 | } | 607 | } |