From 1772571dbee4bad6805fbe90ed558a1b09d98e5b Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Thu, 2 Nov 2023 09:34:13 +0100 Subject: [PATCH 1/7] Shorten UTD marker file --- src/Tasks/Microsoft.Common.CurrentVersion.targets | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/Tasks/Microsoft.Common.CurrentVersion.targets index bcf0e99af18..2b6ed93fe5c 100644 --- a/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -385,11 +385,16 @@ Copyright (C) Microsoft Corporation. All rights reserved. <_GenerateBindingRedirectsIntermediateAppConfig>$(IntermediateOutputPath)$(TargetFileName).config + + + $(MSBuildProjectFile) + $(MSBuildCopyMarkerName.Substring(0,8)).$(ProjectGuid.Substring(1,8)) + - + From 4a4544cb4d4971772086f0f55f51385e6ea3e59a Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Fri, 3 Nov 2023 16:29:09 +0100 Subject: [PATCH 2/7] Improve the StableStringHash intrinsic function and use it in the copy mareker filename --- src/Build/Evaluation/FowlerNollVo1aHash.cs | 41 +++++++++++++++++++ src/Build/Evaluation/IntrinsicFunctions.cs | 4 +- src/Build/Microsoft.Build.csproj | 1 + .../Microsoft.Common.CurrentVersion.targets | 5 ++- 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 src/Build/Evaluation/FowlerNollVo1aHash.cs diff --git a/src/Build/Evaluation/FowlerNollVo1aHash.cs b/src/Build/Evaluation/FowlerNollVo1aHash.cs new file mode 100644 index 00000000000..4ae34818799 --- /dev/null +++ b/src/Build/Evaluation/FowlerNollVo1aHash.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 System.Text; + +namespace Microsoft.Build.Evaluation +{ + internal 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 fnvPrimeA = 16777619; + private const uint fnvOffsetBasisA = 2166136261; + + /// + /// Computes 32 bit Fowler/Noll/Vo-1a hash of a UTF8 decoded string. + /// + /// String to be hashed. + /// 32 bit signed hash + internal static int ComputeHash(string text) + { + uint hash = fnvOffsetBasisA; + + // We want this to be stable across platforms, so we need to use UTF8 encoding. + foreach (byte b in Encoding.UTF8.GetBytes(text)) + { + unchecked + { + hash ^= b; + hash *= fnvPrimeA; + } + } + + return unchecked((int)hash); + } + } +} diff --git a/src/Build/Evaluation/IntrinsicFunctions.cs b/src/Build/Evaluation/IntrinsicFunctions.cs index 3fff5c28e65..a74ebc1310c 100644 --- a/src/Build/Evaluation/IntrinsicFunctions.cs +++ b/src/Build/Evaluation/IntrinsicFunctions.cs @@ -398,11 +398,11 @@ internal static string ConvertFromBase64(string toDecode) } /// - /// Hash the string independent of bitness and target framework. + /// Hash the string independent of bitness, target framework and default codepage of the environment. /// internal static int StableStringHash(string toHash) { - return CommunicationsUtilities.GetHashCode(toHash); + return FowlerNollVo1aHash.ComputeHash(toHash); } /// diff --git a/src/Build/Microsoft.Build.csproj b/src/Build/Microsoft.Build.csproj index a42e76cc270..8465a1d66cd 100644 --- a/src/Build/Microsoft.Build.csproj +++ b/src/Build/Microsoft.Build.csproj @@ -153,6 +153,7 @@ + diff --git a/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/Tasks/Microsoft.Common.CurrentVersion.targets index 2b6ed93fe5c..142040bc605 100644 --- a/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -388,7 +388,10 @@ Copyright (C) Microsoft Corporation. All rights reserved. $(MSBuildProjectFile) - $(MSBuildCopyMarkerName.Substring(0,8)).$(ProjectGuid.Substring(1,8)) + + $(MSBuildProjectFile.Substring(0,8)).$(ProjectGuid.Substring(1,8)) + + $(MSBuildProjectFile.Substring(0,8)).$([MSBuild]::StableStringHash($(MSBuildProjectFile)).ToString("X8")) From 8fe5c17fcf65a88c81b25d4885ef130b8da1790b Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Mon, 6 Nov 2023 15:16:00 +0100 Subject: [PATCH 3/7] Unify FNV implementations --- src/Build/Evaluation/FowlerNollVo1aHash.cs | 41 ------- src/Build/Evaluation/IntrinsicFunctions.cs | 2 +- .../BinaryLogger/BuildEventArgsWriter.cs | 35 +----- src/Build/Microsoft.Build.csproj | 2 +- src/Build/Utilities/FowlerNollVo1aHash.cs | 107 ++++++++++++++++++ 5 files changed, 112 insertions(+), 75 deletions(-) delete mode 100644 src/Build/Evaluation/FowlerNollVo1aHash.cs create mode 100644 src/Build/Utilities/FowlerNollVo1aHash.cs diff --git a/src/Build/Evaluation/FowlerNollVo1aHash.cs b/src/Build/Evaluation/FowlerNollVo1aHash.cs deleted file mode 100644 index 4ae34818799..00000000000 --- a/src/Build/Evaluation/FowlerNollVo1aHash.cs +++ /dev/null @@ -1,41 +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.Text; - -namespace Microsoft.Build.Evaluation -{ - internal 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 fnvPrimeA = 16777619; - private const uint fnvOffsetBasisA = 2166136261; - - /// - /// Computes 32 bit Fowler/Noll/Vo-1a hash of a UTF8 decoded string. - /// - /// String to be hashed. - /// 32 bit signed hash - internal static int ComputeHash(string text) - { - uint hash = fnvOffsetBasisA; - - // We want this to be stable across platforms, so we need to use UTF8 encoding. - foreach (byte b in Encoding.UTF8.GetBytes(text)) - { - unchecked - { - hash ^= b; - hash *= fnvPrimeA; - } - } - - return unchecked((int)hash); - } - } -} diff --git a/src/Build/Evaluation/IntrinsicFunctions.cs b/src/Build/Evaluation/IntrinsicFunctions.cs index a74ebc1310c..3b60f4f1a4c 100644 --- a/src/Build/Evaluation/IntrinsicFunctions.cs +++ b/src/Build/Evaluation/IntrinsicFunctions.cs @@ -402,7 +402,7 @@ internal static string ConvertFromBase64(string toDecode) /// internal static int StableStringHash(string toHash) { - return FowlerNollVo1aHash.ComputeHash(toHash); + return FowlerNollVo1aHash.ComputeHash32(toHash); } /// diff --git a/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs b/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs index 0a21182e83c..ffc7d17dbc0 100644 --- a/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs +++ b/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs @@ -14,6 +14,7 @@ using Microsoft.Build.Framework; using Microsoft.Build.Framework.Profiler; using Microsoft.Build.Shared; +using Microsoft.Build.Utilities; #nullable disable @@ -1274,13 +1275,13 @@ public HashKey(string text) } else { - value = FnvHash64.GetHashCode(text); + value = FowlerNollVo1aHash.ComputeHash64Fast(text); } } public static HashKey Combine(HashKey left, HashKey right) { - return new HashKey(FnvHash64.Combine(left.value, right.value)); + return new HashKey(FowlerNollVo1aHash.Combine64(left.value, right.value)); } public HashKey Add(HashKey other) => Combine(this, other); @@ -1310,35 +1311,5 @@ 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/Build/Microsoft.Build.csproj b/src/Build/Microsoft.Build.csproj index 8465a1d66cd..67490385761 100644 --- a/src/Build/Microsoft.Build.csproj +++ b/src/Build/Microsoft.Build.csproj @@ -153,7 +153,7 @@ - + diff --git a/src/Build/Utilities/FowlerNollVo1aHash.cs b/src/Build/Utilities/FowlerNollVo1aHash.cs new file mode 100644 index 00000000000..a9b319e7cc0 --- /dev/null +++ b/src/Build/Utilities/FowlerNollVo1aHash.cs @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Build.Utilities +{ + internal 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 ulong fnvPrimeA64Bit = 1099511628211; + private const ulong fnvOffsetBasisA64Bit = 14695981039346656037; + + /// + /// Computes 32 bit Fowler/Noll/Vo-1a hash of a string (regardless of encoding). + /// + /// String to be hashed. + /// 32 bit signed hash + internal static int ComputeHash32(string text) + { + uint hash = fnvOffsetBasisA32Bit; + + 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; + } + } + + 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 + internal static ulong ComputeHash64Fast(string text) + { + ulong 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 + internal static ulong ComputeHash64(string text) + { + ulong hash = fnvOffsetBasisA64Bit; + + 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; + } + } + + return hash; + } + + internal static ulong Combine64(ulong left, ulong right) + { + unchecked + { + return (left ^ right) * fnvPrimeA64Bit; + } + } + } +} From e02ba1c3aaaa3a33a7e704a7b173602588f67916 Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Thu, 23 Nov 2023 12:20:36 +0100 Subject: [PATCH 4/7] Apply PR suggestions --- src/Build/Utilities/FowlerNollVo1aHash.cs | 33 +++++-------------- .../Microsoft.Common.CurrentVersion.targets | 13 ++++---- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/Build/Utilities/FowlerNollVo1aHash.cs b/src/Build/Utilities/FowlerNollVo1aHash.cs index a9b319e7cc0..f55ff6393af 100644 --- a/src/Build/Utilities/FowlerNollVo1aHash.cs +++ b/src/Build/Utilities/FowlerNollVo1aHash.cs @@ -1,6 +1,9 @@ // 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.Build.Utilities { internal static class FowlerNollVo1aHash @@ -27,19 +30,10 @@ internal static int ComputeHash32(string text) { uint hash = fnvOffsetBasisA32Bit; - unchecked + ReadOnlySpan span = MemoryMarshal.Cast(text.AsSpan()); + foreach (byte b in span) { - 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; - } + hash = unchecked((hash ^ b) * fnvPrimeA32Bit); } return unchecked((int)hash); @@ -78,19 +72,10 @@ internal static ulong ComputeHash64(string text) { ulong hash = fnvOffsetBasisA64Bit; - unchecked + ReadOnlySpan span = MemoryMarshal.Cast(text.AsSpan()); + foreach (byte b in span) { - 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; - } + hash = unchecked((hash ^ b) * fnvPrimeA64Bit); } return hash; diff --git a/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/Tasks/Microsoft.Common.CurrentVersion.targets index 4c1a4b8f53b..fcd663f17aa 100644 --- a/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -386,18 +386,19 @@ Copyright (C) Microsoft Corporation. All rights reserved. <_GenerateBindingRedirectsIntermediateAppConfig>$(IntermediateOutputPath)$(TargetFileName).config - - $(MSBuildProjectFile) - + + $(MSBuildProjectFile) + $(MSBuildProjectFile.Substring(0,8)).$(ProjectGuid.Substring(1,8)) - - $(MSBuildProjectFile.Substring(0,8)).$([MSBuild]::StableStringHash($(MSBuildProjectFile)).ToString("X8")) + + $(MSBuildProjectFile.Substring(0,8)).$([MSBuild]::StableStringHash($(MSBuildProjectFile)).ToString("X8")) + $(MSBuildCopyMarkerName).Up2Date - + From dee22d1f17518454a2eb5232474b661cb69a773a Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Thu, 23 Nov 2023 14:06:35 +0100 Subject: [PATCH 5/7] Move FNV hashing to stringtools --- src/Build/Evaluation/IntrinsicFunctions.cs | 1 + .../BinaryLogger/BuildEventArgsWriter.cs | 5 +- src/Build/Microsoft.Build.csproj | 1 - .../FowlerNollVo1aHash.cs | 64 ++++++++++++++++--- 4 files changed, 58 insertions(+), 13 deletions(-) rename src/{Build/Utilities => StringTools}/FowlerNollVo1aHash.cs (60%) diff --git a/src/Build/Evaluation/IntrinsicFunctions.cs b/src/Build/Evaluation/IntrinsicFunctions.cs index 3b60f4f1a4c..28e8fe62c93 100644 --- a/src/Build/Evaluation/IntrinsicFunctions.cs +++ b/src/Build/Evaluation/IntrinsicFunctions.cs @@ -14,6 +14,7 @@ using Microsoft.Build.Shared; using Microsoft.Build.Shared.FileSystem; using Microsoft.Build.Utilities; +using Microsoft.NET.StringTools; using Microsoft.Win32; // Needed for DoesTaskHostExistForParameters diff --git a/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs b/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs index ffc7d17dbc0..701c7b6b5fc 100644 --- a/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs +++ b/src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs @@ -15,6 +15,7 @@ using Microsoft.Build.Framework.Profiler; using Microsoft.Build.Shared; using Microsoft.Build.Utilities; +using Microsoft.NET.StringTools; #nullable disable @@ -1260,9 +1261,9 @@ private void Write(IExtendedBuildEventArgs extendedData) internal readonly struct HashKey : IEquatable { - private readonly ulong value; + private readonly long value; - private HashKey(ulong i) + private HashKey(long i) { value = i; } diff --git a/src/Build/Microsoft.Build.csproj b/src/Build/Microsoft.Build.csproj index 67490385761..a42e76cc270 100644 --- a/src/Build/Microsoft.Build.csproj +++ b/src/Build/Microsoft.Build.csproj @@ -153,7 +153,6 @@ - diff --git a/src/Build/Utilities/FowlerNollVo1aHash.cs b/src/StringTools/FowlerNollVo1aHash.cs similarity index 60% rename from src/Build/Utilities/FowlerNollVo1aHash.cs rename to src/StringTools/FowlerNollVo1aHash.cs index f55ff6393af..61574db2094 100644 --- a/src/Build/Utilities/FowlerNollVo1aHash.cs +++ b/src/StringTools/FowlerNollVo1aHash.cs @@ -4,9 +4,12 @@ using System.Runtime.InteropServices; using System; -namespace Microsoft.Build.Utilities +namespace Microsoft.NET.StringTools { - internal static class FowlerNollVo1aHash + /// + /// Fowler/Noll/Vo hashing. + /// + public static class FowlerNollVo1aHash { // Fowler/Noll/Vo hashing. // http://www.isthe.com/chongo/tech/comp/fnv/ @@ -18,23 +21,40 @@ internal static class FowlerNollVo1aHash private const uint fnvOffsetBasisA32Bit = 2166136261; // 64 bit FNV prime and offset basis for FNV-1a. - private const ulong fnvPrimeA64Bit = 1099511628211; - private const ulong fnvOffsetBasisA64Bit = 14695981039346656037; + 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 - internal static int ComputeHash32(string text) + 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); } @@ -46,9 +66,9 @@ internal static int ComputeHash32(string text) /// /// String to be hashed. /// 64 bit unsigned hash - internal static ulong ComputeHash64Fast(string text) + public static long ComputeHash64Fast(string text) { - ulong hash = fnvOffsetBasisA64Bit; + long hash = fnvOffsetBasisA64Bit; unchecked { @@ -68,20 +88,44 @@ internal static ulong ComputeHash64Fast(string text) /// /// String to be hashed. /// 64 bit unsigned hash - internal static ulong ComputeHash64(string text) + public static long ComputeHash64(string text) { - ulong hash = fnvOffsetBasisA64Bit; + 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; } - internal static ulong Combine64(ulong left, ulong right) + /// + /// Combines two 64 bit hashes into one. + /// + /// + /// + /// + [CLSCompliant(false)] + public static long Combine64(long left, long right) { unchecked { From 0add56177437e6b07ef7e5a1f9d4f44a60b4ba74 Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Thu, 23 Nov 2023 14:28:47 +0100 Subject: [PATCH 6/7] Fix leftovers --- src/StringTools/FowlerNollVo1aHash.cs | 1 - src/Tasks/Microsoft.Common.CurrentVersion.targets | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/StringTools/FowlerNollVo1aHash.cs b/src/StringTools/FowlerNollVo1aHash.cs index 61574db2094..e6d9e14136d 100644 --- a/src/StringTools/FowlerNollVo1aHash.cs +++ b/src/StringTools/FowlerNollVo1aHash.cs @@ -124,7 +124,6 @@ public static long ComputeHash64(string text) /// /// /// - [CLSCompliant(false)] public static long Combine64(long left, long right) { unchecked diff --git a/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/Tasks/Microsoft.Common.CurrentVersion.targets index fcd663f17aa..e4da0a86001 100644 --- a/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -386,12 +386,12 @@ Copyright (C) Microsoft Corporation. All rights reserved. <_GenerateBindingRedirectsIntermediateAppConfig>$(IntermediateOutputPath)$(TargetFileName).config - + $(MSBuildProjectFile) - $(MSBuildProjectFile.Substring(0,8)).$(ProjectGuid.Substring(1,8)) + $(MSBuildProjectFile.Substring(0,8)).$(ProjectGuid.Substring(1,8)) - $(MSBuildProjectFile.Substring(0,8)).$([MSBuild]::StableStringHash($(MSBuildProjectFile)).ToString("X8")) + $(MSBuildProjectFile.Substring(0,8)).$([MSBuild]::StableStringHash($(MSBuildProjectFile)).ToString("X8")) $(MSBuildCopyMarkerName).Up2Date From c58eb9015d8bf0e16d53e1d0a30509a7bb32ab42 Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Thu, 23 Nov 2023 14:30:24 +0100 Subject: [PATCH 7/7] Add comments --- src/StringTools/FowlerNollVo1aHash.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/StringTools/FowlerNollVo1aHash.cs b/src/StringTools/FowlerNollVo1aHash.cs index e6d9e14136d..7532a688669 100644 --- a/src/StringTools/FowlerNollVo1aHash.cs +++ b/src/StringTools/FowlerNollVo1aHash.cs @@ -119,10 +119,10 @@ public static long ComputeHash64(string text) } /// - /// Combines two 64 bit hashes into one. + /// 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) {