diff --git a/src/libraries/Common/src/Extensions/HashCodeCombiner/HashCodeCombiner.cs b/src/libraries/Common/src/Extensions/HashCodeCombiner/HashCodeCombiner.cs deleted file mode 100644 index a23c699025311e..00000000000000 --- a/src/libraries/Common/src/Extensions/HashCodeCombiner/HashCodeCombiner.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace Microsoft.Extensions.Internal -{ - internal struct HashCodeCombiner - { - private long _combinedHash64; - - public int CombinedHash - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _combinedHash64.GetHashCode(); } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private HashCodeCombiner(long seed) - { - _combinedHash64 = seed; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(IEnumerable e) - { - if (e == null) - { - Add(0); - } - else - { - int count = 0; - foreach (object o in e) - { - Add(o); - count++; - } - Add(count); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator int(HashCodeCombiner self) - { - return self.CombinedHash; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(int i) - { - _combinedHash64 = ((_combinedHash64 << 5) + _combinedHash64) ^ i; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(string s) - { - int hashCode = (s != null) ? s.GetHashCode() : 0; - Add(hashCode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(object o) - { - int hashCode = (o != null) ? o.GetHashCode() : 0; - Add(hashCode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(TValue value, IEqualityComparer comparer) - { - int hashCode = value != null ? comparer.GetHashCode(value) : 0; - Add(hashCode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HashCodeCombiner Start() - { - return new HashCodeCombiner(0x1505L); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/HashCodeCombinerTest.cs b/src/libraries/Common/tests/Extensions/HashCodeCombinerTest.cs deleted file mode 100644 index 68ec1c5108d345..00000000000000 --- a/src/libraries/Common/tests/Extensions/HashCodeCombinerTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -namespace Microsoft.Extensions.Internal -{ - public class HashCodeCombinerTest - { - [Fact] - public void GivenTheSameInputs_ItProducesTheSameOutput() - { - var hashCode1 = new HashCodeCombiner(); - var hashCode2 = new HashCodeCombiner(); - - hashCode1.Add(42); - hashCode1.Add("foo"); - hashCode2.Add(42); - hashCode2.Add("foo"); - - Assert.Equal(hashCode1.CombinedHash, hashCode2.CombinedHash); - } - - [Fact] - public void HashCode_Is_OrderSensitive() - { - var hashCode1 = HashCodeCombiner.Start(); - var hashCode2 = HashCodeCombiner.Start(); - - hashCode1.Add(42); - hashCode1.Add("foo"); - - hashCode2.Add("foo"); - hashCode2.Add(42); - - Assert.NotEqual(hashCode1.CombinedHash, hashCode2.CombinedHash); - } - } -} diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs index cf424bed27be8e..aa554523477f31 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using Microsoft.Extensions.Internal; +using System.Numerics.Hashing; namespace Microsoft.Extensions.FileSystemGlobbing { @@ -66,13 +66,10 @@ public override bool Equals(object obj) /// Gets a hash for the file pattern match. /// /// Some number - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(Path, StringComparer.OrdinalIgnoreCase); - hashCodeCombiner.Add(Stem, StringComparer.OrdinalIgnoreCase); + public override int GetHashCode() => + HashHelpers.Combine(GetHashCode(Path), GetHashCode(Stem)); - return hashCodeCombiner; - } + private static int GetHashCode(string value) => + value != null ? StringComparer.OrdinalIgnoreCase.GetHashCode(value) : 0; } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj index cf923440da6e9e..5e064234c68bc5 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj @@ -6,8 +6,8 @@ - + diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs new file mode 100644 index 00000000000000..25296f838f1481 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace Microsoft.Extensions.FileSystemGlobbing.Tests +{ + public class FilePatternMatchTests + { + [Fact] + public void TestGetHashCode() + { + FilePatternMatch match1 = new FilePatternMatch("sub/sub2/bar/baz/three.txt", "sub2/bar/baz/three.txt"); + FilePatternMatch match2 = new FilePatternMatch("sub/sub2/bar/baz/three.txt", "sub2/bar/baz/three.txt"); + FilePatternMatch match3 = new FilePatternMatch("sub/sub2/bar/baz/one.txt", "sub2/bar/baz/three.txt"); + FilePatternMatch match4 = new FilePatternMatch("sub/sub2/bar/baz/three.txt", "sub2/bar/baz/one.txt"); + + Assert.Equal(match1.GetHashCode(), match2.GetHashCode()); + Assert.NotEqual(match1.GetHashCode(), match3.GetHashCode()); + Assert.NotEqual(match1.GetHashCode(), match4.GetHashCode()); + + // FilePatternMatch is case insensitive + FilePatternMatch matchCase1 = new FilePatternMatch("Sub/Sub2/bar/baz/three.txt", "sub2/bar/baz/three.txt"); + FilePatternMatch matchCase2 = new FilePatternMatch("sub/sub2/bar/baz/three.txt", "Sub2/bar/baz/thrEE.txt"); + Assert.Equal(matchCase1.GetHashCode(), matchCase2.GetHashCode()); + } + + [Fact] + public void TestGetHashCodeWithNull() + { + FilePatternMatch match = new FilePatternMatch(null, null); + Assert.Equal(0, match.GetHashCode()); + + int hash1 = new FilePatternMatch("non null", null).GetHashCode(); + int hash2 = new FilePatternMatch(null, "non null").GetHashCode(); + Assert.NotEqual(0, hash1); + Assert.NotEqual(0, hash2); + Assert.NotEqual(hash1, hash2); + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj b/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj index 192e8f377e1c70..716edd80e42827 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj +++ b/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj @@ -9,8 +9,8 @@ - + (this[0])?.GetHashCode() ?? Count.GetHashCode(); } - var hcc = default(HashCodeCombiner); + int hashCode = 0; for (int i = 0; i < values.Length; i++) { - hcc.Add(values[i]); + hashCode = HashHelpers.Combine(hashCode, values[i]?.GetHashCode() ?? 0); } - return hcc.CombinedHash; + return hashCode; } else {