Skip to content

Commit

Permalink
Fix HashSet.Remove to use provided comparer (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub authored and safern committed Nov 20, 2019
1 parent 714b143 commit cd4631d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public static IEnumerable<object[]> ValidCollectionSizes()
yield return new object[] { 75 };
}

public static IEnumerable<object[]> ValidPositiveCollectionSizes()
{
yield return new object[] { 1 };
yield return new object[] { 75 };
}

public enum EnumerableType
{
HashSet,
Expand Down
18 changes: 18 additions & 0 deletions src/libraries/Common/tests/System/Collections/TestingTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,5 +366,23 @@ public struct ValueDelegateEquatable : IEquatable<ValueDelegateEquatable>
public bool Equals(ValueDelegateEquatable other) => EqualsWorker(other);
}

public sealed class TrackingEqualityComparer<T> : IEqualityComparer<T>
{
public int EqualsCalls;
public int GetHashCodeCalls;

public bool Equals(T x, T y)
{
EqualsCalls++;
return EqualityComparer<T>.Default.Equals(x, y);
}

public int GetHashCode(T obj)
{
GetHashCodeCalls++;
return EqualityComparer<T>.Default.GetHashCode(obj);
}
}

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ public bool Remove(T item)

for (i = _buckets[bucket] - 1; i >= 0; last = i, i = slots[i].next)
{
if (slots[i].hashCode == hashCode && EqualityComparer<T>.Default.Equals(slots[i].value, item))
if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].value, item))
{
goto ReturnFound;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,5 +626,29 @@ public void EnsureCapacity_Generic_GrowCapacityWithFreeList(int setLength)
}

#endregion

#region Remove

[Theory]
[MemberData(nameof(ValidPositiveCollectionSizes))]
public void Remove_NonDefaultComparer_ComparerUsed(int capacity)
{
var c = new TrackingEqualityComparer<T>();
var set = new HashSet<T>(capacity, c);

AddToCollection(set, capacity);
T first = set.First();
c.EqualsCalls = 0;
c.GetHashCodeCalls = 0;

Assert.Equal(capacity, set.Count);
set.Remove(first);
Assert.Equal(capacity - 1, set.Count);

Assert.InRange(c.EqualsCalls, 1, int.MaxValue);
Assert.InRange(c.GetHashCodeCalls, 1, int.MaxValue);
}

#endregion
}
}

0 comments on commit cd4631d

Please sign in to comment.