@@ -390,17 +390,20 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
390390 }
391391
392392 if ( _buckets == null ) Initialize ( 0 ) ;
393- int hashCode = _comparer . GetHashCode ( key ) & 0x7FFFFFFF ;
393+ IEqualityComparer < TKey > comparer = _comparer ;
394+ int hashCode = comparer . GetHashCode ( key ) & 0x7FFFFFFF ;
394395 int targetBucket = hashCode % _buckets . Length ;
395396 int collisionCount = 0 ;
396397
397- for ( int i = _buckets [ targetBucket ] ; i >= 0 ; i = _entries [ i ] . next )
398+ int i = _buckets [ targetBucket ] ;
399+ Entry [ ] entries = _entries ;
400+ while ( i >= 0 )
398401 {
399- if ( _entries [ i ] . hashCode == hashCode && _comparer . Equals ( _entries [ i ] . key , key ) )
402+ if ( entries [ i ] . hashCode == hashCode && comparer . Equals ( key , entries [ i ] . key ) )
400403 {
401404 if ( behavior == InsertionBehavior . OverwriteExisting )
402405 {
403- _entries [ i ] . value = value ;
406+ entries [ i ] . value = value ;
404407 _version ++ ;
405408 return true ;
406409 }
@@ -412,41 +415,45 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
412415
413416 return false ;
414417 }
418+
419+ i = entries [ i ] . next ;
415420 collisionCount ++ ;
416421 }
417422
418423 int index ;
419424 if ( _freeCount > 0 )
420425 {
421426 index = _freeList ;
422- _freeList = _entries [ index ] . next ;
427+ _freeList = entries [ index ] . next ;
423428 _freeCount -- ;
424429 }
425430 else
426431 {
427- if ( _count == _entries . Length )
432+ int count = _count ;
433+ if ( count == entries . Length )
428434 {
429435 Resize ( ) ;
430436 targetBucket = hashCode % _buckets . Length ;
431437 }
432- index = _count ;
433- _count ++ ;
438+ index = count ;
439+ _count = count + 1 ;
440+ entries = _entries ;
434441 }
435442
436- _entries [ index ] . hashCode = hashCode ;
437- _entries [ index ] . next = _buckets [ targetBucket ] ;
438- _entries [ index ] . key = key ;
439- _entries [ index ] . value = value ;
443+ entries [ index ] . hashCode = hashCode ;
444+ entries [ index ] . next = _buckets [ targetBucket ] ;
445+ entries [ index ] . key = key ;
446+ entries [ index ] . value = value ;
440447 _buckets [ targetBucket ] = index ;
441448 _version ++ ;
442449
443- // If we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing
444- // i.e. EqualityComparer<string>.Default.
445-
446- if ( collisionCount > HashHelpers . HashCollisionThreshold && _comparer is NonRandomizedStringEqualityComparer )
450+ // Value types never rehash
451+ if ( default ( TKey ) == null && collisionCount > HashHelpers . HashCollisionThreshold && _comparer is NonRandomizedStringEqualityComparer )
447452 {
453+ // If we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing
454+ // i.e. EqualityComparer<string>.Default.
448455 _comparer = ( IEqualityComparer < TKey > ) EqualityComparer < string > . Default ;
449- Resize ( _entries . Length , true ) ;
456+ Resize ( entries . Length , true ) ;
450457 }
451458
452459 return true ;
@@ -508,6 +515,8 @@ private void Resize()
508515
509516 private void Resize ( int newSize , bool forceNewHashCodes )
510517 {
518+ // Value types never rehash
519+ Debug . Assert ( ! forceNewHashCodes || default ( TKey ) == null ) ;
511520 Debug . Assert ( newSize >= _entries . Length ) ;
512521
513522 int [ ] buckets = new int [ newSize ] ;
@@ -520,7 +529,7 @@ private void Resize(int newSize, bool forceNewHashCodes)
520529 int count = _count ;
521530 Array . Copy ( _entries , 0 , entries , 0 , count ) ;
522531
523- if ( forceNewHashCodes )
532+ if ( default ( TKey ) == null && forceNewHashCodes )
524533 {
525534 for ( int i = 0 ; i < count ; i ++ )
526535 {
0 commit comments