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 0000000..3a9c925
Binary files /dev/null and b/AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.snk differ
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);
+ }
}
}