summaryrefslogtreecommitdiff
path: root/src/hash.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/hash.h')
-rw-r--r--src/hash.h65
1 files changed, 59 insertions, 6 deletions
diff --git a/src/hash.h b/src/hash.h
index 10db03a..7f1ac65 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -25,10 +25,12 @@ bool __cmpHashKeys( T a, T b );
25 25
26struct __calcNextTSize_fast 26struct __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
34template<typename key, typename value, typename sizecalc = __calcNextTSize_fast, typename keyalloc = std::allocator<key>, typename valuealloc = std::allocator<value>, typename challoc = std::allocator<uint32_t> > 36template<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 }