@@ -37,21 +37,21 @@ internal enum InsertionBehavior : byte
3737 [ System . Runtime . CompilerServices . TypeForwardedFrom ( "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ) ]
3838 public class Dictionary < TKey , TValue > : IDictionary < TKey , TValue > , IDictionary , IReadOnlyDictionary < TKey , TValue > , ISerializable , IDeserializationCallback
3939 {
40- private struct Entry
40+ internal struct Entry
4141 {
4242 public int hashCode ; // Lower 31 bits of hash code, -1 if unused
4343 public int next ; // Index of next entry, -1 if last
4444 public TKey key ; // Key of entry
4545 public TValue value ; // Value of entry
4646 }
4747
48- private int [ ] _buckets ;
49- private Entry [ ] _entries ;
50- private int _count ;
48+ internal int [ ] _buckets ;
49+ internal Entry [ ] _entries ;
50+ internal int _count ;
5151 private int _version ;
5252 private int _freeList ;
5353 private int _freeCount ;
54- private IEqualityComparer < TKey > _comparer ;
54+ internal IEqualityComparer < TKey > _comparer ;
5555 private KeyCollection _keys ;
5656 private ValueCollection _values ;
5757 private object _syncRoot ;
@@ -440,13 +440,13 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
440440 _buckets [ targetBucket ] = index ;
441441 _version ++ ;
442442
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.
445443
446444 if ( default ( TKey ) == null && collisionCount > HashHelpers . HashCollisionThreshold && _comparer is NonRandomizedStringEqualityComparer )
447445 {
446+ // If we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing
447+ // i.e. EqualityComparer<string>.Default.
448448 _comparer = ( IEqualityComparer < TKey > ) EqualityComparer < string > . Default ;
449- Rehash ( ) ;
449+ DictionaryHelper . Rehash ( ( Dictionary < string , TValue > ) ( object ) this ) ;
450450 }
451451
452452 return true ;
@@ -498,35 +498,6 @@ public virtual void OnDeserialization(object sender)
498498 HashHelpers . SerializationInfoTable . Remove ( this ) ;
499499 }
500500
501- private void Rehash ( )
502- {
503- int [ ] buckets = _buckets ;
504- for ( int i = 0 ; i < buckets . Length ; i ++ )
505- {
506- buckets [ i ] = - 1 ;
507- }
508-
509- int count = _count ;
510- int length = buckets . Length ;
511- Entry [ ] entries = _entries ;
512-
513- IEqualityComparer < TKey > comparer = _comparer ;
514-
515- for ( int i = 0 ; i < count ; i ++ )
516- {
517- ref Entry entry = ref entries [ i ] ;
518- int hashCode = entry . hashCode ;
519- if ( hashCode >= 0 )
520- {
521- hashCode = ( comparer . GetHashCode ( entry . key ) & 0x7FFFFFFF ) ;
522- int bucket = hashCode % length ;
523- entry . hashCode = hashCode ;
524- entry . next = buckets [ bucket ] ;
525- buckets [ bucket ] = i ;
526- }
527- }
528- }
529-
530501 private void Expand ( int prime )
531502 {
532503 Debug . Assert ( HashHelpers . IsPrime ( prime ) ) ;
@@ -1485,4 +1456,39 @@ void System.Collections.IEnumerator.Reset()
14851456 }
14861457 }
14871458 }
1459+
1460+ internal class DictionaryHelper
1461+ {
1462+ internal static void Rehash < TValue > ( Dictionary < string , TValue > dict )
1463+ {
1464+ // Rehash is externalised for string keys only; rather than an instance method
1465+ // so it isn't compiled into every generic instance type for AOT compiles
1466+
1467+ int [ ] buckets = dict . _buckets ;
1468+ for ( int i = 0 ; i < buckets . Length ; i ++ )
1469+ {
1470+ buckets [ i ] = - 1 ;
1471+ }
1472+
1473+ int count = dict . _count ;
1474+ int length = buckets . Length ;
1475+ Dictionary < string , TValue > . Entry [ ] entries = dict . _entries ;
1476+
1477+ IEqualityComparer < string > comparer = dict . _comparer ;
1478+
1479+ for ( int i = 0 ; i < count ; i ++ )
1480+ {
1481+ ref Dictionary < string , TValue > . Entry entry = ref entries [ i ] ;
1482+ int hashCode = entry . hashCode ;
1483+ if ( hashCode >= 0 )
1484+ {
1485+ hashCode = ( comparer . GetHashCode ( entry . key ) & 0x7FFFFFFF ) ;
1486+ int bucket = hashCode % length ;
1487+ entry . hashCode = hashCode ;
1488+ entry . next = buckets [ bucket ] ;
1489+ buckets [ bucket ] = i ;
1490+ }
1491+ }
1492+ }
1493+ }
14881494}
0 commit comments