From f044a3fdca981e10b77334680ae2aa7a95d530bd Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Fri, 29 Dec 2023 18:10:45 +0100 Subject: [PATCH] Additional coverage --- .../AsyncKeyedLock.Tests.csproj | 4 ++ AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.snk | Bin 0 -> 596 bytes .../StripedAsyncKeyedLocker/OriginalTests.cs | 57 ++++++++++++++++++ AsyncKeyedLock/HashHelpers.cs | 43 +------------ AsyncKeyedLock/StripedAsyncKeyedLocker.cs | 9 +++ 5 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.snk diff --git a/AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.csproj b/AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.csproj index 4515249..eb5397e 100644 --- a/AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.csproj +++ b/AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.csproj @@ -6,6 +6,10 @@ enable false + + True + + AsyncKeyedLock.Tests.snk diff --git a/AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.snk b/AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.snk new file mode 100644 index 0000000000000000000000000000000000000000..3a9c92537598e280006edd1041beb3b5bedf19e9 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097{&->*W0lG*zw!i6&O>X3J6z+B>Oh_#6c3; z-#CwTrK+@P^%_I8pDr)XHB(n98v#ca2C%?!{a@i^9~^rDWzlaoS4gH4XBL5zjP}8s zE!{;>Oo{H-BQp7E9~#VJ?ozQ}XAn=par+);>0p{@?HvT_yzo@xn={T9n?w^6Ri~pv=@<&7m;mvsnTWj-bhFSiJQ#;sa_{ zb%Sq9+iExCgIa@~?P2o zi6L4Ruiy~T*^+Hz4$YmDsMeBDHT(FYY!+ypU^LAEG0+8jybfm*&&Go-$AGEN9oGg0 z1x%_d6<2$m@#X)JiTItMuvj4t;P_bGhK#7UT;R1_D6%=p^rl%8xM8TQ9F|QINZ$rB zMt(9}p8f^tl3}D4EzFylfKo|tSpVg@95s_wfVIO^rKOx#9UAG0?YuzvZr6ZC+X4?# z?}iAP0y*4g`T!i*k#5yH2VlnKQ!~oVuf6+ZT8SD`k}e6F5#tuUWyv9qjD_WH*An&| il+pa6yccwnW%Dt-^|tEiYA;BN9<&@KweJJf*~o$eKO$QI literal 0 HcmV?d00001 diff --git a/AsyncKeyedLock.Tests/StripedAsyncKeyedLocker/OriginalTests.cs b/AsyncKeyedLock.Tests/StripedAsyncKeyedLocker/OriginalTests.cs index 3a7353d..c4c6cac 100644 --- a/AsyncKeyedLock.Tests/StripedAsyncKeyedLocker/OriginalTests.cs +++ b/AsyncKeyedLock.Tests/StripedAsyncKeyedLocker/OriginalTests.cs @@ -1,6 +1,7 @@ using AsyncKeyedLock.Tests.Helpers; using FluentAssertions; using ListShuffle; +using System.Collections; using System.Collections.Concurrent; using Xunit; @@ -8,6 +9,62 @@ namespace AsyncKeyedLock.Tests.StripedAsyncKeyedLocker { public class OriginalTests { + [Fact] + public void TestHashHelpersIsPrime0DoesNotThrow() + { + Action action = () => + { + var asyncKeyedLocker = new StripedAsyncKeyedLocker(0); + }; + action.Should().NotThrow(); + } + + [Fact] + public void TestHashHelpersIsPrime1DoesNotThrow() + { + Action action = () => + { + var asyncKeyedLocker = new StripedAsyncKeyedLocker(1); + }; + action.Should().NotThrow(); + } + + [Fact] + public void TestHashHelpersIsPrime7199370DoesNotThrow() + { + Action action = () => + { + var asyncKeyedLocker = new StripedAsyncKeyedLocker(7199370); + }; + action.Should().NotThrow(); + } + + [Fact] + public void TestHashHelpersIsPrime7199371DoesNotThrow() + { + Action action = () => + { + var asyncKeyedLocker = new StripedAsyncKeyedLocker(7199372); + }; + action.Should().NotThrow(); + } + + [Fact] + public void TestHashHelpersIsPrimeNegative1ThrowsArgumentException() + { + Action action = () => + { + var asyncKeyedLocker = new StripedAsyncKeyedLocker(-1); + }; + action.Should().Throw(); + } + + [Fact] + public void TestHashHelpersIsPrime2() + { + HashHelpers.IsPrime(2).Should().Be(true); + } + [Fact] public async Task TestTimeout() { diff --git a/AsyncKeyedLock/HashHelpers.cs b/AsyncKeyedLock/HashHelpers.cs index c360bb5..d1d965c 100644 --- a/AsyncKeyedLock/HashHelpers.cs +++ b/AsyncKeyedLock/HashHelpers.cs @@ -1,11 +1,8 @@ -// This code is taken directly from Microsoft's source code with minor alterations. Credit belongs to Microsoft. +// This code is taken directly from Microsoft's source code with some alterations. Credit belongs to Microsoft. // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Runtime.CompilerServices; - namespace System.Collections { internal static partial class HashHelpers @@ -84,43 +81,5 @@ public static int GetPrime(int min) } return min; } - - // Returns size of hashtable to grow to. - public static int ExpandPrime(int oldSize) - { - int newSize = 2 * oldSize; - - // Allow the hashtables to grow to maximum possible size (~2G elements) before encountering capacity overflow. - // Note that this check works even when _items.Length overflowed thanks to the (uint) cast - if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) - { - Debug.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength"); - return MaxPrimeArrayLength; - } - - return GetPrime(newSize); - } - - /// Returns approximate reciprocal of the divisor: ceil(2**64 / divisor). - /// This should only be used on 64-bit. - public static ulong GetFastModMultiplier(uint divisor) => - ulong.MaxValue / divisor + 1; - - /// Performs a mod operation using the multiplier pre-computed with . - /// This should only be used on 64-bit. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint FastMod(uint value, uint divisor, ulong multiplier) - { - // We use modified Daniel Lemire's fastmod algorithm (https://github.com/dotnet/runtime/pull/406), - // which allows to avoid the long multiplication if the divisor is less than 2**31. - Debug.Assert(divisor <= int.MaxValue); - - // This is equivalent of (uint)Math.BigMul(multiplier * value, divisor, out _). This version - // is faster than BigMul currently because we only need the high bits. - uint highbits = (uint)(((((multiplier * value) >> 32) + 1) * divisor) >> 32); - - Debug.Assert(highbits == value % divisor); - return highbits; - } } } \ No newline at end of file diff --git a/AsyncKeyedLock/StripedAsyncKeyedLocker.cs b/AsyncKeyedLock/StripedAsyncKeyedLocker.cs index 6af137e..ae273f2 100644 --- a/AsyncKeyedLock/StripedAsyncKeyedLocker.cs +++ b/AsyncKeyedLock/StripedAsyncKeyedLocker.cs @@ -5,6 +5,10 @@ using System.Threading; using System.Threading.Tasks; +[assembly: InternalsVisibleTo("AsyncKeyedLock.Tests, PublicKey=002400000480000094000000060200000024000052534131000" + + "4000001000100a5cffbe51901ba498a225214c7eee4ff5f0341aad9f7605a596e72dbffdf234bcf2c157f7e3a4e2a3900cbc0d3919a6b" + + "938cdf09e2aa5949fdd8f1dbda151853a00a08578724fb36f8c44112dadf388f75a5aab469f51a43b49f2e2fce355357291b01471606b" + + "0c071fd5fe1641f1c7b0165d16f365748a613671681938cf6c1")] namespace AsyncKeyedLock { /// @@ -923,5 +927,10 @@ public bool IsInUse(TKey key) { return Get(key).SemaphoreSlim.CurrentCount < MaxCount; } + + internal bool IsPrime(int candidate) + { + return HashHelpers.IsPrime(candidate); + } } }