Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 018d676

Browse files
committed
Dictionary TryInsert CQ
1 parent c8db268 commit 018d676

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

src/mscorlib/shared/System/Collections/Generic/Dictionary.cs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)