From aba96022de1501fee2ff016211f8080599e5f510 Mon Sep 17 00:00:00 2001 From: Konrad Jamrozik Date: Mon, 6 Mar 2023 15:56:36 -0800 Subject: [PATCH] CodeownersEntry.GetHashCode now properly supports enumerables (#5636) --- .../CodeOwnersParser/CodeownersEntry.cs | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/tools/code-owners-parser/CodeOwnersParser/CodeownersEntry.cs b/tools/code-owners-parser/CodeOwnersParser/CodeownersEntry.cs index 5eff1b30514..72f1d9fbf83 100644 --- a/tools/code-owners-parser/CodeOwnersParser/CodeownersEntry.cs +++ b/tools/code-owners-parser/CodeOwnersParser/CodeownersEntry.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; @@ -184,7 +185,43 @@ public override bool Equals(object? obj) // @formatter:on } + /// + /// Implementation of GetHashCode that properly hashes collections. + /// Implementation based on + /// https://stackoverflow.com/a/10567544/986533 + /// + /// This implementation is candidate to be moved to: + /// https://github.com/Azure/azure-sdk-tools/issues/5281 + /// public override int GetHashCode() - => HashCode.Combine(PathExpression, Owners, PRLabels, ServiceLabels); + { + int hashCode = 0; + // ReSharper disable NonReadonlyMemberInGetHashCode + hashCode = AddHashCodeForObject(hashCode, PathExpression); + hashCode = AddHashCodeForEnumerable(hashCode, Owners); + hashCode = AddHashCodeForEnumerable(hashCode, PRLabels); + hashCode = AddHashCodeForEnumerable(hashCode, ServiceLabels); + // ReSharper restore NonReadonlyMemberInGetHashCode + return hashCode; + + // ReSharper disable once VariableHidesOuterVariable + int AddHashCodeForEnumerable(int hashCode, IEnumerable enumerable) + { + foreach (var item in enumerable) + { + hashCode = AddHashCodeForObject(hashCode, item); + } + return hashCode; + } + + int AddHashCodeForObject(int hc, object item) + { + // Based on https://stackoverflow.com/a/10567544/986533 + hc ^= item.GetHashCode(); + hc = (hc << 7) | + (hc >> (32 - 7)); // rotate hashCode to the left to swipe over all bits + return hc; + } + } } }