@@ -24,7 +24,7 @@ namespace IronPython.Runtime {
2424 /// Mutations to the dictionary involves a simple locking strategy of
2525 /// locking on the DictionaryStorage object to ensure that only one
2626 /// mutation happens at a time.
27- ///
27+ ///
2828 /// Reads against the dictionary happen lock free. When the dictionary is mutated
2929 /// it is either adding or removing buckets in a thread-safe manner so that the readers
3030 /// will either see a consistent picture as if the read occured before or after the mutation.
@@ -161,11 +161,12 @@ public void AddNoLock(object key, object value) {
161161 }
162162
163163 private void AddOne ( object key , object value ) {
164- GetHash ( key , out var hc , out var eqFunc ) ;
165- if ( AddWorker ( _indices , _buckets , new Bucket ( key , value , hc ) , eqFunc ) ) {
164+ Debug . Assert ( _keyType == HeterogeneousType || key ? . GetType ( ) == _keyType ) ;
165+ var hc = _hashFunc ( key ) & int . MaxValue ;
166+ if ( AddWorker ( _indices , _buckets , new Bucket ( key , value , hc ) , _eqFunc ) ) {
166167 if ( _count >= ( _indices . Length * Load ) ) {
167168 // grow the hash table
168- EnsureSize ( ( int ) ( _indices . Length / Load ) * ResizeMultiplier , eqFunc ) ;
169+ EnsureSize ( ( int ) ( _indices . Length / Load ) * ResizeMultiplier , _eqFunc ) ;
169170 }
170171 }
171172 }
@@ -298,7 +299,9 @@ private static KeyValuePair<int, int> LookupIndex(int[] indices, List<Bucket> bu
298299 }
299300
300301 // keep walking
301- index = ProbeNext ( indices , index ) ;
302+ if ( ++ index == indices . Length ) {
303+ index = 0 ;
304+ }
302305
303306 // if we ended up doing a full scan, then this means the key is not already in use and there are
304307 // only recycled buckets available -- nothing more to probe
@@ -329,15 +332,6 @@ private bool AddWorker(int[] indices, List<Bucket> buckets, Bucket bucket, Func<
329332 return true ;
330333 }
331334
332- private static int ProbeNext ( int [ ] indices , int index ) {
333- // probe to next bucket
334- index ++ ;
335- if ( index == indices . Length ) {
336- index = 0 ;
337- }
338- return index ;
339- }
340-
341335 /// <summary>
342336 /// Removes an entry from the dictionary and returns true if the
343337 /// entry was removed or false.
@@ -389,10 +383,7 @@ private void GetHash(object key, out int hc, out Func<object, object, bool> eqFu
389383
390384 private bool TryRemoveNoLock ( object key , out object value ) {
391385 GetHash ( key , out var hc , out var eqFunc ) ;
392- return TryRemoveNoLock ( key , hc , eqFunc , out value ) ;
393- }
394386
395- private bool TryRemoveNoLock ( object key , int hc , Func < object , object , bool > eqFunc , out object value ) {
396387 if ( _indices == null ) {
397388 value = null ;
398389 return false ;
@@ -445,22 +436,19 @@ public override bool TryGetValue(object key, out object value)
445436 private bool TryGetValue ( int [ ] indices , List < Bucket > buckets , object key , out object value ) {
446437 if ( _count > 0 && indices != null ) {
447438 GetHash ( key , out var hc , out var eqFunc ) ;
448- return TryGetValue ( indices , buckets , key , hc , eqFunc , out value ) ;
449- }
450439
451- value = null ;
452- return false ;
453- }
440+ var pair = LookupIndex ( indices , buckets , key , hc , eqFunc ) ;
441+ if ( pair . Value < 0 ) {
442+ value = null ;
443+ return false ;
444+ }
454445
455- private static bool TryGetValue ( int [ ] indices , List < Bucket > buckets , object key , int hc , Func < object , object , bool > eqFunc , out object value ) {
456- var pair = LookupIndex ( indices , buckets , key , hc , eqFunc ) ;
457- if ( pair . Value < 0 ) {
458- value = null ;
459- return false ;
446+ value = buckets [ pair . Value ] . Value ;
447+ return true ;
460448 }
461449
462- value = buckets [ pair . Value ] . Value ;
463- return true ;
450+ value = null ;
451+ return false ;
464452 }
465453
466454 /// <summary>
0 commit comments