diff --git a/src/Build/Evaluation/IntrinsicFunctions.cs b/src/Build/Evaluation/IntrinsicFunctions.cs
index 28e8fe62c93..3fff5c28e65 100644
--- a/src/Build/Evaluation/IntrinsicFunctions.cs
+++ b/src/Build/Evaluation/IntrinsicFunctions.cs
@@ -14,7 +14,6 @@
using Microsoft.Build.Shared;
using Microsoft.Build.Shared.FileSystem;
using Microsoft.Build.Utilities;
-using Microsoft.NET.StringTools;
using Microsoft.Win32;
// Needed for DoesTaskHostExistForParameters
@@ -399,11 +398,11 @@ internal static string ConvertFromBase64(string toDecode)
}
///
- /// Hash the string independent of bitness, target framework and default codepage of the environment.
+ /// Hash the string independent of bitness and target framework.
///
internal static int StableStringHash(string toHash)
{
- return FowlerNollVo1aHash.ComputeHash32(toHash);
+ return CommunicationsUtilities.GetHashCode(toHash);
}
///
diff --git a/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs b/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs
index 701c7b6b5fc..0a21182e83c 100644
--- a/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs
+++ b/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs
@@ -14,8 +14,6 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Framework.Profiler;
using Microsoft.Build.Shared;
-using Microsoft.Build.Utilities;
-using Microsoft.NET.StringTools;
#nullable disable
@@ -1261,9 +1259,9 @@ private void Write(IExtendedBuildEventArgs extendedData)
internal readonly struct HashKey : IEquatable
{
- private readonly long value;
+ private readonly ulong value;
- private HashKey(long i)
+ private HashKey(ulong i)
{
value = i;
}
@@ -1276,13 +1274,13 @@ public HashKey(string text)
}
else
{
- value = FowlerNollVo1aHash.ComputeHash64Fast(text);
+ value = FnvHash64.GetHashCode(text);
}
}
public static HashKey Combine(HashKey left, HashKey right)
{
- return new HashKey(FowlerNollVo1aHash.Combine64(left.value, right.value));
+ return new HashKey(FnvHash64.Combine(left.value, right.value));
}
public HashKey Add(HashKey other) => Combine(this, other);
@@ -1312,5 +1310,35 @@ public override string ToString()
return value.ToString();
}
}
+
+ internal static class FnvHash64
+ {
+ public const ulong Offset = 14695981039346656037;
+ public const ulong Prime = 1099511628211;
+
+ public static ulong GetHashCode(string text)
+ {
+ ulong hash = Offset;
+
+ unchecked
+ {
+ for (int i = 0; i < text.Length; i++)
+ {
+ char ch = text[i];
+ hash = (hash ^ ch) * Prime;
+ }
+ }
+
+ return hash;
+ }
+
+ public static ulong Combine(ulong left, ulong right)
+ {
+ unchecked
+ {
+ return (left ^ right) * Prime;
+ }
+ }
+ }
}
}
diff --git a/src/StringTools/FowlerNollVo1aHash.cs b/src/StringTools/FowlerNollVo1aHash.cs
deleted file mode 100644
index 7532a688669..00000000000
--- a/src/StringTools/FowlerNollVo1aHash.cs
+++ /dev/null
@@ -1,135 +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.Runtime.InteropServices;
-using System;
-
-namespace Microsoft.NET.StringTools
-{
- ///
- /// Fowler/Noll/Vo hashing.
- ///
- public static class FowlerNollVo1aHash
- {
- // Fowler/Noll/Vo hashing.
- // http://www.isthe.com/chongo/tech/comp/fnv/
- // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash
- // http://www.isthe.com/chongo/src/fnv/hash_32a.c
-
- // 32 bit FNV prime and offset basis for FNV-1a.
- private const uint fnvPrimeA32Bit = 16777619;
- private const uint fnvOffsetBasisA32Bit = 2166136261;
-
- // 64 bit FNV prime and offset basis for FNV-1a.
- private const long fnvPrimeA64Bit = 1099511628211;
- private const long fnvOffsetBasisA64Bit = unchecked((long)14695981039346656037);
-
- ///
- /// Computes 32 bit Fowler/Noll/Vo-1a hash of a string (regardless of encoding).
- ///
- /// String to be hashed.
- /// 32 bit signed hash
- public static int ComputeHash32(string text)
- {
- uint hash = fnvOffsetBasisA32Bit;
-
-#if NET35
- unchecked
- {
- for (int i = 0; i < text.Length; i++)
- {
- char ch = text[i];
- byte b = (byte)ch;
- hash ^= b;
- hash *= fnvPrimeA32Bit;
-
- b = (byte)(ch >> 8);
- hash ^= b;
- hash *= fnvPrimeA32Bit;
- }
- }
-#else
- ReadOnlySpan span = MemoryMarshal.Cast(text.AsSpan());
- foreach (byte b in span)
- {
- hash = unchecked((hash ^ b) * fnvPrimeA32Bit);
- }
-#endif
-
- return unchecked((int)hash);
- }
-
- ///
- /// Computes 64 bit Fowler/Noll/Vo-1a hash optimized for ASCII strings.
- /// The hashing algorithm considers only the first 8 bits of each character.
- /// Analysis: https://github.com/KirillOsenkov/MSBuildStructuredLog/wiki/String-Hashing#faster-fnv-1a
- ///
- /// String to be hashed.
- /// 64 bit unsigned hash
- public static long ComputeHash64Fast(string text)
- {
- long hash = fnvOffsetBasisA64Bit;
-
- unchecked
- {
- for (int i = 0; i < text.Length; i++)
- {
- char ch = text[i];
-
- hash = (hash ^ ch) * fnvPrimeA64Bit;
- }
- }
-
- return hash;
- }
-
- ///
- /// Computes 64 bit Fowler/Noll/Vo-1a hash of a string (regardless of encoding).
- ///
- /// String to be hashed.
- /// 64 bit unsigned hash
- public static long ComputeHash64(string text)
- {
- long hash = fnvOffsetBasisA64Bit;
-
-#if NET35
- unchecked
- {
- for (int i = 0; i < text.Length; i++)
- {
- char ch = text[i];
- byte b = (byte)ch;
- hash ^= b;
- hash *= fnvPrimeA64Bit;
-
- b = (byte)(ch >> 8);
- hash ^= b;
- hash *= fnvPrimeA64Bit;
- }
- }
-#else
- ReadOnlySpan span = MemoryMarshal.Cast(text.AsSpan());
- foreach (byte b in span)
- {
- hash = unchecked((hash ^ b) * fnvPrimeA64Bit);
- }
-#endif
-
- return hash;
- }
-
- ///
- /// Combines two 64 bit hashes generated by class into one.
- ///
- /// First hash value to be combined.
- /// Second hash value to be combined.
- ///
- public static long Combine64(long left, long right)
- {
- unchecked
- {
- return (left ^ right) * fnvPrimeA64Bit;
- }
- }
- }
-}