diff --git a/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj b/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj index 9d290f1f..4526bb7e 100644 --- a/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj +++ b/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj @@ -3,7 +3,7 @@ Exe latest - net6.0;net8.0 + net8.0;net9.0 True true diff --git a/BitFaster.Caching.Benchmarks/DataStructureBenchmarks.cs b/BitFaster.Caching.Benchmarks/DataStructureBenchmarks.cs index b8b0d0fd..c938870f 100644 --- a/BitFaster.Caching.Benchmarks/DataStructureBenchmarks.cs +++ b/BitFaster.Caching.Benchmarks/DataStructureBenchmarks.cs @@ -10,7 +10,7 @@ namespace BitFaster.Caching.Benchmarks #if Windows [SimpleJob(RuntimeMoniker.Net48)] #endif - [SimpleJob(RuntimeMoniker.Net60)] + [SimpleJob(RuntimeMoniker.Net90)] [MemoryDiagnoser(displayGenColumns: false)] public class DataStructureBenchmarks { diff --git a/BitFaster.Caching.Benchmarks/DisposerBench.cs b/BitFaster.Caching.Benchmarks/DisposerBench.cs index b17fd36d..3c45e4b9 100644 --- a/BitFaster.Caching.Benchmarks/DisposerBench.cs +++ b/BitFaster.Caching.Benchmarks/DisposerBench.cs @@ -11,7 +11,7 @@ namespace BitFaster.Caching.Benchmarks [DisassemblyDiagnoser(printSource: true, maxDepth: 3)] [SimpleJob(RuntimeMoniker.Net48)] #endif - [SimpleJob(RuntimeMoniker.Net60)] + [SimpleJob(RuntimeMoniker.Net90)] [MemoryDiagnoser(displayGenColumns: false)] [HideColumns("Job", "Median", "RatioSD", "Alloc Ratio")] public class DisposerBench diff --git a/BitFaster.Caching.Benchmarks/DrainBenchmarks.cs b/BitFaster.Caching.Benchmarks/DrainBenchmarks.cs index 51306c91..807bf500 100644 --- a/BitFaster.Caching.Benchmarks/DrainBenchmarks.cs +++ b/BitFaster.Caching.Benchmarks/DrainBenchmarks.cs @@ -10,7 +10,7 @@ namespace BitFaster.Caching.Benchmarks [DisassemblyDiagnoser(printSource: true, maxDepth: 3)] [SimpleJob(RuntimeMoniker.Net48)] #endif - [SimpleJob(RuntimeMoniker.Net60)] + [SimpleJob(RuntimeMoniker.Net90)] [HideColumns("Job", "Median", "RatioSD", "Alloc Ratio")] public class DrainBenchmarks { @@ -187,7 +187,7 @@ public void Add() public void DrainArray() { Add(); -#if NETCOREAPP3_1_OR_GREATER +#if NET buffer.DrainTo(output.AsSpan()); #else buffer.DrainTo(new ArraySegment(output)); diff --git a/BitFaster.Caching.Benchmarks/Lfu/CmSketchFlat.cs b/BitFaster.Caching.Benchmarks/Lfu/CmSketchFlat.cs index f0523066..b70ec3af 100644 --- a/BitFaster.Caching.Benchmarks/Lfu/CmSketchFlat.cs +++ b/BitFaster.Caching.Benchmarks/Lfu/CmSketchFlat.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -#if NETCOREAPP3_1_OR_GREATER +#if NET using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; #endif @@ -53,7 +53,7 @@ public CmSketchFlat(long maximumSize, IEqualityComparer comparer) /// The estimated frequency of the value. public int EstimateFrequency(T value) { -#if !NETCOREAPP3_1_OR_GREATER +#if !NET return EstimateFrequencyStd(value); #else @@ -76,7 +76,7 @@ public int EstimateFrequency(T value) /// The value. public void Increment(T value) { -#if !NETCOREAPP3_1_OR_GREATER +#if !NET IncrementStd(value); #else @@ -207,7 +207,7 @@ private int Spread(int x) return (int)((y >> 16) ^ y); } -#if NETCOREAPP3_1_OR_GREATER +#if NET private unsafe int EstimateFrequencyAvx(T value) { int hash = Spread(comparer.GetHashCode(value)); diff --git a/BitFaster.Caching.Benchmarks/Lfu/CmSketchNoPin.cs b/BitFaster.Caching.Benchmarks/Lfu/CmSketchNoPin.cs index fdc8629a..423dfb96 100644 --- a/BitFaster.Caching.Benchmarks/Lfu/CmSketchNoPin.cs +++ b/BitFaster.Caching.Benchmarks/Lfu/CmSketchNoPin.cs @@ -1,10 +1,9 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; -#if NET6_0_OR_GREATER +#if NET using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; @@ -57,7 +56,7 @@ public CmSketchNoPin(long maximumSize, IEqualityComparer comparer) /// The estimated frequency of the value. public int EstimateFrequency(T value) { -#if NET48 +#if NETFRAMEWORK return EstimateFrequencyStd(value); #else @@ -67,7 +66,7 @@ public int EstimateFrequency(T value) { return EstimateFrequencyAvx(value); } -#if NET6_0_OR_GREATER +#if NET else if (isa.IsArm64Supported) { return EstimateFrequencyArm(value); @@ -86,7 +85,7 @@ public int EstimateFrequency(T value) /// The value. public void Increment(T value) { -#if NET48 +#if NETFRAMEWORK IncrementStd(value); #else @@ -96,7 +95,7 @@ public void Increment(T value) { IncrementAvx(value); } -#if NET6_0_OR_GREATER +#if NET else if (isa.IsArm64Supported) { IncrementArm(value); @@ -233,7 +232,7 @@ private void Reset() size = (size - (count0 >> 2)) >> 1; } -#if NET6_0_OR_GREATER +#if NET private unsafe int EstimateFrequencyAvx(T value) { int blockHash = Spread(comparer.GetHashCode(value)); @@ -267,11 +266,7 @@ private unsafe int EstimateFrequencyAvx(T value) .AsUInt16(); // set the zeroed high parts of the long value to ushort.Max -#if NET6_0 count = Avx2.Blend(count, Vector128.AllBitsSet, 0b10101010); -#else - count = Avx2.Blend(count, Vector128.Create(ushort.MaxValue), 0b10101010); -#endif return Avx2.MinHorizontal(count).GetElement(0); } @@ -333,7 +328,7 @@ private unsafe void IncrementAvx(T value) } #endif -#if NET6_0_OR_GREATER +#if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void IncrementArm(T value) { diff --git a/BitFaster.Caching.Benchmarks/TimeBenchmarks.cs b/BitFaster.Caching.Benchmarks/TimeBenchmarks.cs index e4514582..f15bde49 100644 --- a/BitFaster.Caching.Benchmarks/TimeBenchmarks.cs +++ b/BitFaster.Caching.Benchmarks/TimeBenchmarks.cs @@ -41,7 +41,7 @@ public int EnvironmentTickCount() [Benchmark()] public long EnvironmentTickCount64() { -#if NETCOREAPP3_0_OR_GREATER +#if NET return Environment.TickCount64; #else return 0; diff --git a/BitFaster.Caching.HitRateAnalysis/BitFaster.Caching.HitRateAnalysis.csproj b/BitFaster.Caching.HitRateAnalysis/BitFaster.Caching.HitRateAnalysis.csproj index 5968e280..de9625eb 100644 --- a/BitFaster.Caching.HitRateAnalysis/BitFaster.Caching.HitRateAnalysis.csproj +++ b/BitFaster.Caching.HitRateAnalysis/BitFaster.Caching.HitRateAnalysis.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 true true true diff --git a/BitFaster.Caching.ThroughputAnalysis/BitFaster.Caching.ThroughputAnalysis.csproj b/BitFaster.Caching.ThroughputAnalysis/BitFaster.Caching.ThroughputAnalysis.csproj index bdbef714..0aeab23b 100644 --- a/BitFaster.Caching.ThroughputAnalysis/BitFaster.Caching.ThroughputAnalysis.csproj +++ b/BitFaster.Caching.ThroughputAnalysis/BitFaster.Caching.ThroughputAnalysis.csproj @@ -2,7 +2,7 @@ Exe - net6.0;net8.0 + net8.0;net9.0 False 2.0.0 true diff --git a/BitFaster.Caching.UnitTests.Std/BitFaster.Caching.UnitTests.Std.csproj b/BitFaster.Caching.UnitTests.Std/BitFaster.Caching.UnitTests.Std.csproj index 1f91474b..ffb9e912 100644 --- a/BitFaster.Caching.UnitTests.Std/BitFaster.Caching.UnitTests.Std.csproj +++ b/BitFaster.Caching.UnitTests.Std/BitFaster.Caching.UnitTests.Std.csproj @@ -1,8 +1,8 @@  - net6.0 - 9.0 + net9.0 + latest diff --git a/BitFaster.Caching.UnitTests.Std/DurationTests.cs b/BitFaster.Caching.UnitTests.Std/DurationTests.cs index 7a58df9f..0456ee38 100644 --- a/BitFaster.Caching.UnitTests.Std/DurationTests.cs +++ b/BitFaster.Caching.UnitTests.Std/DurationTests.cs @@ -25,7 +25,7 @@ public void SinceEpoch() // On .NET Standard, only windows uses TickCount64 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Duration.SinceEpoch().raw.Should().BeCloseTo(Duration.GetTickCount64(), 15); + Duration.SinceEpoch().raw.Should().BeCloseTo(Environment.TickCount64, 15); } else { diff --git a/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryAsyncCacheTests.cs b/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryAsyncCacheTests.cs index 7459de31..e8dbacfa 100644 --- a/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryAsyncCacheTests.cs +++ b/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryAsyncCacheTests.cs @@ -91,8 +91,8 @@ public void WhenRemovedEventHandlerIsRegisteredItIsFired() this.removedItems.First().Key.Should().Be(1); } - // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +// backcompat: remove conditional compile +#if NET [Fact] public void WhenUpdatedEventHandlerIsRegisteredItIsFired() { @@ -258,8 +258,8 @@ public async Task WhenFactoryThrowsEmptyKeyIsNotEnumerable() cache.Keys.Count().Should().Be(0); } - // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +// backcompat: remove conditional compile +#if NET [Fact] public void WhenRemovedValueIsReturned() { diff --git a/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryCacheTests.cs b/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryCacheTests.cs index 0c8bd66c..d2434418 100644 --- a/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryCacheTests.cs +++ b/BitFaster.Caching.UnitTests/Atomic/AtomicFactoryCacheTests.cs @@ -79,8 +79,8 @@ public void WhenRemovedEventHandlerIsRegisteredItIsFired() this.removedItems.First().Key.Should().Be(1); } - // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +// backcompat: remove conditional compile +#if NET [Fact] public void WhenRemovedValueIsReturned() { diff --git a/BitFaster.Caching.UnitTests/BitFaster.Caching.UnitTests.csproj b/BitFaster.Caching.UnitTests/BitFaster.Caching.UnitTests.csproj index 93a5a179..03f9fb9a 100644 --- a/BitFaster.Caching.UnitTests/BitFaster.Caching.UnitTests.csproj +++ b/BitFaster.Caching.UnitTests/BitFaster.Caching.UnitTests.csproj @@ -1,8 +1,8 @@ - net48;netcoreapp3.1;net6.0 - 9.0 + net48;net8.0;net9.0 + latest diff --git a/BitFaster.Caching.UnitTests/Buffers/MpscBoundedBufferTests.cs b/BitFaster.Caching.UnitTests/Buffers/MpscBoundedBufferTests.cs index a4a65242..ad0adc8d 100644 --- a/BitFaster.Caching.UnitTests/Buffers/MpscBoundedBufferTests.cs +++ b/BitFaster.Caching.UnitTests/Buffers/MpscBoundedBufferTests.cs @@ -100,7 +100,7 @@ public void WhenBufferEmptyDrainReturnsZero() buffer.DrainTo(output).Should().Be(0); } -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenBufferContainsItemsDrainArrayTakesItems() { diff --git a/BitFaster.Caching.UnitTests/CacheEventProxyBaseTests.cs b/BitFaster.Caching.UnitTests/CacheEventProxyBaseTests.cs index 6cbd4908..f82fdc1c 100644 --- a/BitFaster.Caching.UnitTests/CacheEventProxyBaseTests.cs +++ b/BitFaster.Caching.UnitTests/CacheEventProxyBaseTests.cs @@ -55,7 +55,7 @@ public void WhenTwoRemovedEventHandlersAddedThenOneRemovedEventIsFired() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WheUpdatedEventHandlerIsRegisteredItIsFired() { @@ -155,7 +155,7 @@ public void WhenUpdatedEventHandlerIsRegisteredAndProxyUsesDefaultUpdateTranslat this.testCacheEvents.FireUpdated(1, new AtomicFactory(2), new AtomicFactory(3)); -#if NETCOREAPP3_0_OR_GREATER +#if NET this.updatedItems.First().Key.Should().Be(1); #else this.updatedItems.Should().BeEmpty(); diff --git a/BitFaster.Caching.UnitTests/CacheEventsTests.cs b/BitFaster.Caching.UnitTests/CacheEventsTests.cs index e51002d2..bf7e6b6a 100644 --- a/BitFaster.Caching.UnitTests/CacheEventsTests.cs +++ b/BitFaster.Caching.UnitTests/CacheEventsTests.cs @@ -5,7 +5,7 @@ namespace BitFaster.Caching.UnitTests { // backcompat: remove -#if NETCOREAPP3_1_OR_GREATER +#if NET public class CacheEventsTests { [Fact] diff --git a/BitFaster.Caching.UnitTests/CacheMetricsTests.cs b/BitFaster.Caching.UnitTests/CacheMetricsTests.cs index 62bf3368..7094d007 100644 --- a/BitFaster.Caching.UnitTests/CacheMetricsTests.cs +++ b/BitFaster.Caching.UnitTests/CacheMetricsTests.cs @@ -6,7 +6,7 @@ namespace BitFaster.Caching.UnitTests { // backcompat: remove -#if NETCOREAPP3_1_OR_GREATER +#if NET public class CacheMetricsTests { [Fact] diff --git a/BitFaster.Caching.UnitTests/CacheTests.cs b/BitFaster.Caching.UnitTests/CacheTests.cs index 5cdeafa0..166a17a5 100644 --- a/BitFaster.Caching.UnitTests/CacheTests.cs +++ b/BitFaster.Caching.UnitTests/CacheTests.cs @@ -12,7 +12,7 @@ namespace BitFaster.Caching.UnitTests public class CacheTests { // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenCacheInterfaceDefaultGetOrAddFallback() { diff --git a/BitFaster.Caching.UnitTests/DurationTests.cs b/BitFaster.Caching.UnitTests/DurationTests.cs index 38fbce72..dd4f3bd5 100644 --- a/BitFaster.Caching.UnitTests/DurationTests.cs +++ b/BitFaster.Caching.UnitTests/DurationTests.cs @@ -22,7 +22,7 @@ public DurationTests(ITestOutputHelper testOutputHelper) [Fact] public void SinceEpoch() { -#if NETCOREAPP3_0_OR_GREATER +#if NET if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { // eps is 1/200 of a second @@ -36,7 +36,7 @@ public void SinceEpoch() #else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Duration.SinceEpoch().raw.Should().BeCloseTo(Duration.GetTickCount64(), 15); + Duration.SinceEpoch().raw.Should().BeCloseTo(Environment.TickCount, 15); } else { @@ -50,7 +50,7 @@ public void SinceEpoch() [Fact] public void ToTimeSpan() { -#if NETCOREAPP3_0_OR_GREATER +#if NET if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { new Duration(100).ToTimeSpan().Should().BeCloseTo(new TimeSpan(100), TimeSpan.FromMilliseconds(50)); @@ -75,7 +75,7 @@ public void ToTimeSpan() [Fact] public void FromTimeSpan() { -#if NETCOREAPP3_0_OR_GREATER +#if NET if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { Duration.FromTimeSpan(TimeSpan.FromSeconds(1)).raw diff --git a/BitFaster.Caching.UnitTests/Intrinsics.cs b/BitFaster.Caching.UnitTests/Intrinsics.cs index ebbe194a..38ee9c30 100644 --- a/BitFaster.Caching.UnitTests/Intrinsics.cs +++ b/BitFaster.Caching.UnitTests/Intrinsics.cs @@ -1,7 +1,5 @@ -#if NETCOREAPP3_1_OR_GREATER +#if NET using System.Runtime.Intrinsics.X86; -#endif -#if NET6_0_OR_GREATER using System.Runtime.Intrinsics.Arm; #endif @@ -13,15 +11,9 @@ public static class Intrinsics { public static void SkipAvxIfNotSupported() { -#if NETCOREAPP3_1_OR_GREATER - #if NET6_0_OR_GREATER +#if NET // when we are trying to test Avx2/Arm64, skip the test if it's not supported Skip.If(typeof(I) == typeof(DetectIsa) && !(Avx2.IsSupported || AdvSimd.Arm64.IsSupported)); - #else - // when we are trying to test Avx2, skip the test if it's not supported - Skip.If(typeof(I) == typeof(DetectIsa) && !Avx2.IsSupported); - #endif - #else Skip.If(true); #endif diff --git a/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuCoreTests.cs b/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuCoreTests.cs index f3318658..efb2f96e 100644 --- a/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuCoreTests.cs +++ b/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuCoreTests.cs @@ -41,7 +41,7 @@ public void WhenKeyIsRequestedItIsCreatedAndCached() valueFactory.timesCalled.Should().Be(1); result1.Should().Be(result2); } -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenKeyIsRequestedWithArgItIsCreatedAndCached() { @@ -63,7 +63,7 @@ public async Task WhenKeyIsRequesteItIsCreatedAndCachedAsync() result1.Should().Be(result2); } -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public async Task WhenKeyIsRequestedWithArgItIsCreatedAndCachedAsync() { @@ -105,7 +105,7 @@ public void WhenKeyExistsTryRemoveRemovesItem() lfu.TryGet(1, out _).Should().BeFalse(); } -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenKeyExistsTryRemoveReturnsValue() { diff --git a/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuTests.cs b/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuTests.cs index 0f3756bc..c43da509 100644 --- a/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuTests.cs +++ b/BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuTests.cs @@ -477,7 +477,7 @@ public void WhenWriteBufferIsFullAddDoesMaintenance() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenWriteBufferIsFullUpdatesAreDropped() { diff --git a/BitFaster.Caching.UnitTests/Lfu/TimerWheelTests.cs b/BitFaster.Caching.UnitTests/Lfu/TimerWheelTests.cs index 25bac835..5b7334ff 100644 --- a/BitFaster.Caching.UnitTests/Lfu/TimerWheelTests.cs +++ b/BitFaster.Caching.UnitTests/Lfu/TimerWheelTests.cs @@ -122,7 +122,7 @@ public void WhenAdvanceOverflowsAndItemIsExpiredItemIsEvicted() this.lfuNodeList.Count.Should().Be(0); } -#if NET6_0_OR_GREATER +#if NET [Theory] [MemberData(nameof(ClockData))] public void WhenAdvanceBackwardsNothingIsEvicted(long clock) diff --git a/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs b/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs index 4b0b790f..28160594 100644 --- a/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs @@ -429,7 +429,7 @@ public void WhenKeyDoesNotExistTryUpdateReturnsFalse() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenKeyExistsTryUpdateIncrementsUpdateCount() { diff --git a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs index dc8fd785..f3466227 100644 --- a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs @@ -863,7 +863,7 @@ public void WhenKeyDoesNotExistTryUpdateReturnsFalse() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenKeyExistsTryUpdateIncrementsUpdateCount() { @@ -942,7 +942,7 @@ public void WhenKeyDoesNotExistAddOrUpdateMaintainsLruOrder() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenItemExistsAddOrUpdateFiresUpdateEvent() { diff --git a/BitFaster.Caching.UnitTests/Lru/TLruTickCount64PolicyTests .cs b/BitFaster.Caching.UnitTests/Lru/TLruTickCount64PolicyTests .cs index 5803d8e7..bd14d764 100644 --- a/BitFaster.Caching.UnitTests/Lru/TLruTickCount64PolicyTests .cs +++ b/BitFaster.Caching.UnitTests/Lru/TLruTickCount64PolicyTests .cs @@ -1,4 +1,4 @@ -#if NETCOREAPP3_1_OR_GREATER +#if NET using FluentAssertions; using BitFaster.Caching.Lru; diff --git a/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs index f9e0d9f8..200322a7 100644 --- a/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs @@ -148,7 +148,7 @@ public void WhenEventSourceIsSetItemUpdatedEventUsesSource() } // backcompat: remove -#if NETCOREAPP3_1_OR_GREATER +#if NET [Fact] public void WhenInterfaceDefaultItemUpdatedRegisteredNoOp() { diff --git a/BitFaster.Caching.UnitTests/Lru/TlruStopwatchPolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/TlruStopwatchPolicyTests.cs index 842d0843..e2545f59 100644 --- a/BitFaster.Caching.UnitTests/Lru/TlruStopwatchPolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/TlruStopwatchPolicyTests.cs @@ -9,7 +9,7 @@ namespace BitFaster.Caching.UnitTests.Lru { // backcompat: remove conditional compile -#if !NETCOREAPP3_1_OR_GREATER +#if !NET public class TlruStopwatchPolicyTests { private readonly TLruLongTicksPolicy policy = new TLruLongTicksPolicy(TimeSpan.FromSeconds(10)); diff --git a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs index 6bd50a76..b8b4ae8a 100644 --- a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs +++ b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs @@ -59,7 +59,7 @@ public void WhenRemovedEventHandlerIsRegisteredItIsFired() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenUpdatedEventHandlerIsRegisteredItIsFired() { @@ -83,7 +83,7 @@ public void WhenKeyDoesNotExistAddOrUpdateAddsNewItem() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public async Task WhenKeyDoesNotExistGetOrAddArgAddsValueWithArg() { diff --git a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTests.cs b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTests.cs index 864287c6..0aec2836 100644 --- a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTests.cs +++ b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTests.cs @@ -53,7 +53,7 @@ public async Task GetOrAddAsyncDisposedScopeThrows() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public async Task GetOrAddAsyncArgDisposedScopeThrows() { diff --git a/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs b/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs index dd41bda2..863c124b 100644 --- a/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs +++ b/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs @@ -58,7 +58,7 @@ public void WhenRemovedEventHandlerIsRegisteredItIsFired() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenUpdatedEventHandlerIsRegisteredItIsFired() { @@ -82,7 +82,7 @@ public void WhenKeyDoesNotExistAddOrUpdateAddsNewItem() } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET [Fact] public void WhenKeyDoesNotExistGetOrAddArgAddsValueWithArg() { diff --git a/BitFaster.Caching/AssemblyInfo.cs b/BitFaster.Caching/AssemblyInfo.cs index fe942190..a33d04a5 100644 --- a/BitFaster.Caching/AssemblyInfo.cs +++ b/BitFaster.Caching/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Runtime.CompilerServices; -#if NET6_0_OR_GREATER +#if NET [module: System.Runtime.CompilerServices.SkipLocalsInit] #endif diff --git a/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs b/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs index 7e3c0ce6..4fdefa75 100644 --- a/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs +++ b/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs @@ -113,7 +113,7 @@ public bool TryRemove(K key) } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET /// /// ///If the value factory is still executing, returns false. diff --git a/BitFaster.Caching/Atomic/AtomicFactoryCache.cs b/BitFaster.Caching/Atomic/AtomicFactoryCache.cs index 0c75390d..36c38968 100644 --- a/BitFaster.Caching/Atomic/AtomicFactoryCache.cs +++ b/BitFaster.Caching/Atomic/AtomicFactoryCache.cs @@ -107,7 +107,7 @@ public bool TryGet(K key, [MaybeNullWhen(false)] out V value) } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET /// /// ///If the value factory is still executing, returns false. diff --git a/BitFaster.Caching/Atomic/ConcurrentDictionaryExtensions.cs b/BitFaster.Caching/Atomic/ConcurrentDictionaryExtensions.cs index f332435f..0479b720 100644 --- a/BitFaster.Caching/Atomic/ConcurrentDictionaryExtensions.cs +++ b/BitFaster.Caching/Atomic/ConcurrentDictionaryExtensions.cs @@ -124,7 +124,7 @@ public static bool TryRemove(this ConcurrentDictionary>(item.Key, new AtomicFactory(item.Value)); -#if NET6_0_OR_GREATER +#if NET return dictionary.TryRemove(kvp); #else // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/ @@ -142,7 +142,7 @@ public static bool TryRemove(this ConcurrentDictionary>(item.Key, new AsyncAtomicFactory(item.Value)); -#if NET6_0_OR_GREATER +#if NET return dictionary.TryRemove(kvp); #else // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/ diff --git a/BitFaster.Caching/BitFaster.Caching.csproj b/BitFaster.Caching/BitFaster.Caching.csproj index 55f0e8dc..f55470b7 100644 --- a/BitFaster.Caching/BitFaster.Caching.csproj +++ b/BitFaster.Caching/BitFaster.Caching.csproj @@ -1,8 +1,8 @@ - netstandard2.0;netcoreapp3.1;net6.0 - 11.0 + netstandard2.0;net8.0;net9.0 + latest Alex Peck BitFaster.Caching diff --git a/BitFaster.Caching/BitOps.cs b/BitFaster.Caching/BitOps.cs index 9c35873e..8ca3ebbc 100644 --- a/BitFaster.Caching/BitOps.cs +++ b/BitFaster.Caching/BitOps.cs @@ -34,7 +34,7 @@ internal static long CeilingPowerOfTwo(long x) /// Smallest power of two greater than or equal to x. public static uint CeilingPowerOfTwo(uint x) { -#if NETSTANDARD2_0 +#if NETSTANDARD // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 --x; x |= x >> 1; @@ -55,7 +55,7 @@ public static uint CeilingPowerOfTwo(uint x) /// Smallest power of two greater than or equal to x. internal static ulong CeilingPowerOfTwo(ulong x) { -#if NETSTANDARD2_0 +#if NETSTANDARD // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 --x; x |= x >> 1; @@ -87,7 +87,7 @@ internal static int TrailingZeroCount(long x) /// The number of trailing zero bits. internal static int TrailingZeroCount(ulong x) { -#if NETSTANDARD2_0 +#if NETSTANDARD // https://codereview.stackexchange.com/questions/288007/c-bit-utility-functions-popcount-trailing-zeros-count-reverse-all-bits return BitCount(~x & (x - 1)); #else @@ -112,7 +112,7 @@ public static int BitCount(int x) /// The number of 1 bits. public static int BitCount(uint x) { -#if NETSTANDARD2_0 +#if NETSTANDARD var count = 0; while (x != 0) { @@ -143,7 +143,7 @@ public static int BitCount(long x) /// The number of 1 bits. public static int BitCount(ulong x) { -#if NETSTANDARD2_0 +#if NETSTANDARD var count = 0; while (x != 0) { diff --git a/BitFaster.Caching/Buffers/ArrayExtensions.cs b/BitFaster.Caching/Buffers/ArrayExtensions.cs index 9325247b..ab608af2 100644 --- a/BitFaster.Caching/Buffers/ArrayExtensions.cs +++ b/BitFaster.Caching/Buffers/ArrayExtensions.cs @@ -6,7 +6,7 @@ namespace BitFaster.Caching.Buffers // Used to avoid conditional compilation to work with Span and ArraySegment. internal static class ArrayExtensions { -#if NETSTANDARD2_0 +#if NETSTANDARD [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static T[] AsSpanOrArray(this T[] array) { diff --git a/BitFaster.Caching/CacheEventProxyBase.cs b/BitFaster.Caching/CacheEventProxyBase.cs index bdfdb170..0e9f8938 100644 --- a/BitFaster.Caching/CacheEventProxyBase.cs +++ b/BitFaster.Caching/CacheEventProxyBase.cs @@ -62,7 +62,7 @@ private void RegisterUpdated(EventHandler> value itemUpdatedProxy += value; // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET events.ItemUpdated += OnItemUpdated; #endif } @@ -72,7 +72,7 @@ private void UnRegisterUpdated(EventHandler> val this.itemUpdatedProxy -= value; // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET if (this.itemUpdatedProxy == null) { this.events.ItemUpdated -= OnItemUpdated; diff --git a/BitFaster.Caching/Duration.cs b/BitFaster.Caching/Duration.cs index 8cc76832..4be15c57 100644 --- a/BitFaster.Caching/Duration.cs +++ b/BitFaster.Caching/Duration.cs @@ -24,15 +24,15 @@ public readonly struct Duration // this also avoids overflow when multipling long.MaxValue by 1.0 internal static readonly TimeSpan MaxRepresentable = TimeSpan.FromTicks((long)(long.MaxValue / 100.0d)); - internal static readonly Duration Zero = new Duration(0); + internal static readonly Duration Zero = new(0); -#if NETCOREAPP3_0_OR_GREATER +#if NET private static readonly bool IsMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); #else private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); [DllImport("kernel32")] - internal static extern long GetTickCount64(); + private static extern long GetTickCount64(); #endif internal Duration(long raw) @@ -43,56 +43,48 @@ internal Duration(long raw) /// /// Gets the time since the system epoch. /// - /// A duration + /// A duration. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Duration SinceEpoch() { -#if NETCOREAPP3_0_OR_GREATER +#if NET if (IsMacOS) { return new Duration(Stopwatch.GetTimestamp()); } - else - { - return new Duration(Environment.TickCount64); - } + + return new Duration(Environment.TickCount64); #else if (IsWindows) { return new Duration(GetTickCount64()); } - else - { - return new Duration(Stopwatch.GetTimestamp()); - } + + return new Duration(Stopwatch.GetTimestamp()); #endif } /// /// Converts the duration to a TimeSpan. /// - /// + /// A TimeSpan. [MethodImpl(MethodImplOptions.AggressiveInlining)] public TimeSpan ToTimeSpan() { -#if NETCOREAPP3_0_OR_GREATER +#if NET if (IsMacOS) { return StopwatchTickConverter.FromTicks(raw); } - else - { - return TimeSpan.FromMilliseconds(raw); - } + + return TimeSpan.FromMilliseconds(raw); #else if (IsWindows) { return TimeSpan.FromMilliseconds(raw); } - else - { - return StopwatchTickConverter.FromTicks(raw); - } + + return StopwatchTickConverter.FromTicks(raw); #endif } @@ -104,24 +96,20 @@ public TimeSpan ToTimeSpan() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Duration FromTimeSpan(TimeSpan timeSpan) { -#if NETCOREAPP3_0_OR_GREATER +#if NET if (IsMacOS) { return new Duration(StopwatchTickConverter.ToTicks(timeSpan)); } - else - { - return new Duration((long)timeSpan.TotalMilliseconds); - } + + return new Duration((long)timeSpan.TotalMilliseconds); #else if (IsWindows) { return new Duration((long)timeSpan.TotalMilliseconds); } - else - { - return new Duration(StopwatchTickConverter.ToTicks(timeSpan)); - } + + return new Duration(StopwatchTickConverter.ToTicks(timeSpan)); #endif } diff --git a/BitFaster.Caching/IAsyncCache.cs b/BitFaster.Caching/IAsyncCache.cs index 56a55e5f..2016c63a 100644 --- a/BitFaster.Caching/IAsyncCache.cs +++ b/BitFaster.Caching/IAsyncCache.cs @@ -54,8 +54,8 @@ public interface IAsyncCache : IEnumerable> /// A task that represents the asynchronous GetOrAdd operation. ValueTask GetOrAddAsync(K key, Func> valueFactory); - // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +// backcompat: remove conditional compile +#if !NETSTANDARD /// /// Adds a key/value pair to the cache if the key does not already exist. Returns the new value, or the /// existing value if the key already exists. diff --git a/BitFaster.Caching/IAsyncCacheExt.cs b/BitFaster.Caching/IAsyncCacheExt.cs index 2187be54..32b95c27 100644 --- a/BitFaster.Caching/IAsyncCacheExt.cs +++ b/BitFaster.Caching/IAsyncCacheExt.cs @@ -17,7 +17,7 @@ public interface IAsyncCacheExt : IAsyncCache // certain build targets, for other build targets we will define them within this new interface to avoid breaking // existing clients. // backcompat: remove conditional compile -#if !NETCOREAPP3_0_OR_GREATER +#if NETSTANDARD /// /// Adds a key/value pair to the cache if the key does not already exist. Returns the new value, or the /// existing value if the key already exists. diff --git a/BitFaster.Caching/ICache.cs b/BitFaster.Caching/ICache.cs index 6bd8523a..2702a7cc 100644 --- a/BitFaster.Caching/ICache.cs +++ b/BitFaster.Caching/ICache.cs @@ -54,8 +54,8 @@ public interface ICache : IEnumerable> /// in the cache, or the new value if the key was not in the cache. V GetOrAdd(K key, Func valueFactory); - // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +// backcompat: remove conditional compile +#if NET /// /// Adds a key/value pair to the cache if the key does not already exist. Returns the new value, or the /// existing value if the key already exists. diff --git a/BitFaster.Caching/ICacheEvents.cs b/BitFaster.Caching/ICacheEvents.cs index 80099d06..60a4a9a1 100644 --- a/BitFaster.Caching/ICacheEvents.cs +++ b/BitFaster.Caching/ICacheEvents.cs @@ -13,7 +13,7 @@ public interface ICacheEvents event EventHandler> ItemRemoved; // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET /// /// Occurs when an item is updated. /// diff --git a/BitFaster.Caching/ICacheExt.cs b/BitFaster.Caching/ICacheExt.cs index 612a5b89..5cae0db1 100644 --- a/BitFaster.Caching/ICacheExt.cs +++ b/BitFaster.Caching/ICacheExt.cs @@ -16,7 +16,7 @@ public interface ICacheExt : ICache // certain build targets, for other build targets we will define them within this new interface to avoid breaking // existing clients. // backcompat: remove conditional compile -#if !NETCOREAPP3_0_OR_GREATER +#if !NET /// /// Adds a key/value pair to the cache if the key does not already exist. Returns the new value, or the /// existing value if the key already exists. diff --git a/BitFaster.Caching/ICacheMetrics.cs b/BitFaster.Caching/ICacheMetrics.cs index feb79589..1d1af203 100644 --- a/BitFaster.Caching/ICacheMetrics.cs +++ b/BitFaster.Caching/ICacheMetrics.cs @@ -33,7 +33,7 @@ public interface ICacheMetrics long Evicted { get; } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET /// /// Gets the total number of updated items. /// diff --git a/BitFaster.Caching/IScoped.cs b/BitFaster.Caching/IScoped.cs index 5a760055..d28db0e6 100644 --- a/BitFaster.Caching/IScoped.cs +++ b/BitFaster.Caching/IScoped.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BitFaster.Caching { diff --git a/BitFaster.Caching/IScopedAsyncCache.cs b/BitFaster.Caching/IScopedAsyncCache.cs index 47de4532..9661536f 100644 --- a/BitFaster.Caching/IScopedAsyncCache.cs +++ b/BitFaster.Caching/IScopedAsyncCache.cs @@ -59,8 +59,8 @@ public interface IScopedAsyncCache : IEnumerable /// A task that represents the asynchronous ScopedGetOrAdd operation. ValueTask> ScopedGetOrAddAsync(K key, Func>> valueFactory); - // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +// backcompat: remove conditional compile +#if !NETSTANDARD /// /// Adds a key/scoped value pair to the cache if the key does not already exist. Returns a lifetime for either /// the new value, or the existing value if the key already exists. diff --git a/BitFaster.Caching/IScopedCache.cs b/BitFaster.Caching/IScopedCache.cs index 45a0f5c2..0673a17f 100644 --- a/BitFaster.Caching/IScopedCache.cs +++ b/BitFaster.Caching/IScopedCache.cs @@ -60,8 +60,8 @@ public interface IScopedCache : IEnumerable>> wh /// the cache. Lifetime ScopedGetOrAdd(K key, Func> valueFactory); - // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +// backcompat: remove conditional compile +#if NET /// /// Adds a key/scoped value pair to the cache if the key does not already exist. Returns a lifetime for either /// the new value, or the existing value if the key already exists. diff --git a/BitFaster.Caching/Intrinsics.cs b/BitFaster.Caching/Intrinsics.cs index a9104823..17007c6c 100644 --- a/BitFaster.Caching/Intrinsics.cs +++ b/BitFaster.Caching/Intrinsics.cs @@ -1,62 +1,59 @@ -#if !NETSTANDARD2_0 -using System.Runtime.Intrinsics.X86; -#endif - -#if NET6_0_OR_GREATER +#if NET +using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics.Arm; -#endif - -namespace BitFaster.Caching -{ - /// - /// Represents a marker interface to enable instruction set hardware intrinsics. - /// - public interface IsaProbe - { - /// - /// Gets a value indicating whether AVX2 is supported. - /// +#endif + +namespace BitFaster.Caching +{ + /// + /// Represents a marker interface to enable instruction set hardware intrinsics. + /// + public interface IsaProbe + { + /// + /// Gets a value indicating whether AVX2 is supported. + /// bool IsAvx2Supported { get; } -#if NET6_0_OR_GREATER - /// - /// Gets a value indicating whether Arm64 is supported. - /// - bool IsArm64Supported { get => false; } -#endif - } - - /// - /// Detect support for hardware instructions via intrinsics. - /// - public readonly struct DetectIsa : IsaProbe - { -#if NETSTANDARD2_0 - /// - public bool IsAvx2Supported => false; -#else - /// +#if NET + /// + /// Gets a value indicating whether Arm64 is supported. + /// + bool IsArm64Supported { get => false; } +#endif + } + + /// + /// Detect support for hardware instructions via intrinsics. + /// + public readonly struct DetectIsa : IsaProbe + { +#if NET + /// public bool IsAvx2Supported => Avx2.IsSupported; -#endif - -#if NET6_0_OR_GREATER +#else + /// + public bool IsAvx2Supported => false; +#endif + +#if NET /// public bool IsArm64Supported => AdvSimd.Arm64.IsSupported; #else /// public bool IsArm64Supported => false; -#endif - } - - /// - /// Force disable hardware instructions via intrinsics. - /// - public readonly struct DisableHardwareIntrinsics : IsaProbe - { - /// +#endif + } + + /// + /// Force disable hardware instructions via intrinsics. + /// + public readonly struct DisableHardwareIntrinsics : IsaProbe + { + /// public bool IsAvx2Supported => false; /// - public bool IsArm64Supported => false; - } -} + public bool IsArm64Supported => false; + } +} diff --git a/BitFaster.Caching/Lfu/CmSketchCore.cs b/BitFaster.Caching/Lfu/CmSketchCore.cs index 9764c51b..94936052 100644 --- a/BitFaster.Caching/Lfu/CmSketchCore.cs +++ b/BitFaster.Caching/Lfu/CmSketchCore.cs @@ -4,14 +4,9 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if !NETSTANDARD2_0 +#if NET using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; - -#endif - -#if NET6_0_OR_GREATER using System.Runtime.Intrinsics.Arm; #endif @@ -39,7 +34,7 @@ public unsafe class CmSketchCore private const long OneMask = 0x1111111111111111L; private long[] table; -#if NET6_0_OR_GREATER +#if NET private long* tableAddr; #endif private int sampleSize; @@ -76,7 +71,7 @@ public CmSketchCore(long maximumSize, IEqualityComparer comparer) /// The estimated frequency of the value. public int EstimateFrequency(T value) { -#if NETSTANDARD2_0 +#if NETSTANDARD return EstimateFrequencyStd(value); #else @@ -86,7 +81,7 @@ public int EstimateFrequency(T value) { return EstimateFrequencyAvx(value); } -#if NET6_0_OR_GREATER +#if NET else if (isa.IsArm64Supported) { return EstimateFrequencyArm(value); @@ -105,7 +100,7 @@ public int EstimateFrequency(T value) /// The value. public void Increment(T value) { -#if NETSTANDARD2_0 +#if NETSTANDARD IncrementStd(value); #else @@ -115,7 +110,7 @@ public void Increment(T value) { IncrementAvx(value); } -#if NET6_0_OR_GREATER +#if NET else if (isa.IsArm64Supported) { IncrementArm(value); @@ -142,7 +137,7 @@ private void EnsureCapacity(long maximumSize) { int maximum = (int)Math.Min(maximumSize, int.MaxValue >> 1); -#if NET6_0_OR_GREATER +#if NET I isa = default; if (isa.IsAvx2Supported || isa.IsArm64Supported) { @@ -291,7 +286,7 @@ private void Reset() size = (size - (count0 >> 2)) >> 1; } -#if !NETSTANDARD2_0 +#if !NETSTANDARD [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe int EstimateFrequencyAvx(T value) { @@ -305,25 +300,16 @@ private unsafe int EstimateFrequencyAvx(T value) Vector256 indexLong = Avx2.PermuteVar8x32(Vector256.Create(index, Vector128.Zero), Vector256.Create(0, 4, 1, 5, 2, 5, 3, 7)).AsUInt64(); -#if NET6_0_OR_GREATER long* tablePtr = tableAddr; -#else - fixed (long* tablePtr = table) -#endif - { - Vector128 count = Avx2.PermuteVar8x32(Avx2.And(Avx2.ShiftRightLogicalVariable(Avx2.GatherVector256(tablePtr, blockOffset, 8), indexLong), Vector256.Create(0xfL)).AsInt32(), Vector256.Create(0, 2, 4, 6, 1, 3, 5, 7)) - .GetLower() - .AsUInt16(); - // set the zeroed high parts of the long value to ushort.Max -#if NET6_0_OR_GREATER - count = Avx2.Blend(count, Vector128.AllBitsSet, 0b10101010); -#else - count = Avx2.Blend(count, Vector128.Create(ushort.MaxValue), 0b10101010); -#endif + Vector128 count = Avx2.PermuteVar8x32(Avx2.And(Avx2.ShiftRightLogicalVariable(Avx2.GatherVector256(tablePtr, blockOffset, 8), indexLong), Vector256.Create(0xfL)).AsInt32(), Vector256.Create(0, 2, 4, 6, 1, 3, 5, 7)) + .GetLower() + .AsUInt16(); - return Avx2.MinHorizontal(count).GetElement(0); - } + // set the zeroed high parts of the long value to ushort.Max + count = Avx2.Blend(count, Vector128.AllBitsSet, 0b10101010); + + return Avx2.MinHorizontal(count).GetElement(0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -340,34 +326,29 @@ private unsafe void IncrementAvx(T value) Vector256 offsetLong = Avx2.PermuteVar8x32(Vector256.Create(index, Vector128.Zero), Vector256.Create(0, 4, 1, 5, 2, 5, 3, 7)).AsUInt64(); Vector256 mask = Avx2.ShiftLeftLogicalVariable(Vector256.Create(0xfL), offsetLong); -#if NET6_0_OR_GREATER long* tablePtr = tableAddr; -#else - fixed (long* tablePtr = table) -#endif - { - // Note masked is 'equal' - therefore use AndNot below - Vector256 masked = Avx2.CompareEqual(Avx2.And(Avx2.GatherVector256(tablePtr, blockOffset, 8), mask), mask); - // Mask to zero out non matches (add zero below) - first operand is NOT then AND result (order matters) - Vector256 inc = Avx2.AndNot(masked, Avx2.ShiftLeftLogicalVariable(Vector256.Create(1L), offsetLong)); + // Note masked is 'equal' - therefore use AndNot below + Vector256 masked = Avx2.CompareEqual(Avx2.And(Avx2.GatherVector256(tablePtr, blockOffset, 8), mask), mask); - bool wasInc = Avx2.MoveMask(Avx2.CompareEqual(masked.AsByte(), Vector256.Zero).AsByte()) == unchecked((int)(0b1111_1111_1111_1111_1111_1111_1111_1111)); + // Mask to zero out non matches (add zero below) - first operand is NOT then AND result (order matters) + Vector256 inc = Avx2.AndNot(masked, Avx2.ShiftLeftLogicalVariable(Vector256.Create(1L), offsetLong)); - tablePtr[blockOffset.GetElement(0)] += inc.GetElement(0); - tablePtr[blockOffset.GetElement(1)] += inc.GetElement(1); - tablePtr[blockOffset.GetElement(2)] += inc.GetElement(2); - tablePtr[blockOffset.GetElement(3)] += inc.GetElement(3); + bool wasInc = Avx2.MoveMask(Avx2.CompareEqual(masked.AsByte(), Vector256.Zero).AsByte()) == unchecked((int)0b1111_1111_1111_1111_1111_1111_1111_1111); - if (wasInc && (++size == sampleSize)) - { - Reset(); - } + tablePtr[blockOffset.GetElement(0)] += inc.GetElement(0); + tablePtr[blockOffset.GetElement(1)] += inc.GetElement(1); + tablePtr[blockOffset.GetElement(2)] += inc.GetElement(2); + tablePtr[blockOffset.GetElement(3)] += inc.GetElement(3); + + if (wasInc && (++size == sampleSize)) + { + Reset(); } } #endif -#if NET6_0_OR_GREATER +#if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void IncrementArm(T value) { diff --git a/BitFaster.Caching/Lfu/ConcurrentLfuCore.cs b/BitFaster.Caching/Lfu/ConcurrentLfuCore.cs index 67f6dbc1..1ca5eac1 100644 --- a/BitFaster.Caching/Lfu/ConcurrentLfuCore.cs +++ b/BitFaster.Caching/Lfu/ConcurrentLfuCore.cs @@ -166,7 +166,7 @@ public void Trim(int itemCount) TakeCandidatesInLruOrder(this.windowLru, candidates, itemCount); } -#if NET6_0_OR_GREATER +#if NET foreach (var candidate in CollectionsMarshal.AsSpan(candidates)) #else foreach (var candidate in candidates) @@ -301,7 +301,7 @@ internal bool TryGetNode(K key, [MaybeNullWhen(false)] out N node) [MethodImpl(MethodImplOptions.NoInlining)] void TryRemove(N node) { -#if NET6_0_OR_GREATER +#if NET if (this.dictionary.TryRemove(new KeyValuePair(node.Key, node))) #else // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/ @@ -323,7 +323,7 @@ public bool TryRemove(KeyValuePair item) { var kvp = new KeyValuePair(item.Key, node); -#if NET6_0_OR_GREATER +#if NET if (this.dictionary.TryRemove(kvp)) #else // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/ @@ -821,7 +821,7 @@ internal void Evict(LfuNode evictee) // This handles the case where the same key exists in the write buffer both // as added and removed. Remove via KVP ensures we don't remove added nodes. var kvp = new KeyValuePair(evictee.Key, (N)evictee); -#if NET6_0_OR_GREATER +#if NET this.dictionary.TryRemove(kvp); #else ((ICollection>)this.dictionary).Remove(kvp); diff --git a/BitFaster.Caching/Lru/ClassicLru.cs b/BitFaster.Caching/Lru/ClassicLru.cs index b277c9ea..8037f903 100644 --- a/BitFaster.Caching/Lru/ClassicLru.cs +++ b/BitFaster.Caching/Lru/ClassicLru.cs @@ -254,7 +254,7 @@ public bool TryRemove(KeyValuePair item) { var kvp = new KeyValuePair>(item.Key, node); -#if NET6_0_OR_GREATER +#if NET if (this.dictionary.TryRemove(kvp)) #else // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/ diff --git a/BitFaster.Caching/Lru/ConcurrentLruCore.cs b/BitFaster.Caching/Lru/ConcurrentLruCore.cs index 6e66987c..a883e662 100644 --- a/BitFaster.Caching/Lru/ConcurrentLruCore.cs +++ b/BitFaster.Caching/Lru/ConcurrentLruCore.cs @@ -313,8 +313,8 @@ public bool TryRemove(KeyValuePair item) if (EqualityComparer.Default.Equals(existing.Value, item.Value)) { var kvp = new KeyValuePair(item.Key, existing); -#if NET6_0_OR_GREATER - if (this.dictionary.TryRemove(kvp)) +#if NET + if (this.dictionary.TryRemove(kvp)) #else // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/ if (((ICollection>)this.dictionary).Remove(kvp)) @@ -391,7 +391,7 @@ public bool TryUpdate(K key, V value) this.itemPolicy.Update(existing); // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET this.telemetryPolicy.OnItemUpdated(existing.Key, oldValue, existing.Value); #endif Disposer.Dispose(oldValue); @@ -805,7 +805,7 @@ private int Move(I item, ItemDestination where, ItemRemovedReason removedReason) var kvp = new KeyValuePair(item.Key, item); -#if NET6_0_OR_GREATER +#if NET if (this.dictionary.TryRemove(kvp)) #else // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/ @@ -900,7 +900,7 @@ private static Optional> CreateEvents(ConcurrentLruCore lru) public long Evicted => lru.telemetryPolicy.Evicted; // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET public long Updated => lru.telemetryPolicy.Updated; #endif public int Capacity => lru.Capacity; @@ -939,7 +939,7 @@ public event EventHandler> ItemRemoved } // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET public event EventHandler> ItemUpdated { add { this.lru.telemetryPolicy.ItemUpdated += value; } diff --git a/BitFaster.Caching/Lru/ITelemetryPolicy.cs b/BitFaster.Caching/Lru/ITelemetryPolicy.cs index 27d991cf..eaba7470 100644 --- a/BitFaster.Caching/Lru/ITelemetryPolicy.cs +++ b/BitFaster.Caching/Lru/ITelemetryPolicy.cs @@ -28,7 +28,7 @@ public interface ITelemetryPolicy : ICacheMetrics, ICacheEvents void OnItemRemoved(K key, V value, ItemRemovedReason reason); // backcompat: remove conditional compile -#if NETCOREAPP3_0_OR_GREATER +#if NET /// /// Register the update of an item. /// diff --git a/BitFaster.Caching/Lru/StopwatchTickConverter.cs b/BitFaster.Caching/Lru/StopwatchTickConverter.cs index 770e8abb..5de0793b 100644 --- a/BitFaster.Caching/Lru/StopwatchTickConverter.cs +++ b/BitFaster.Caching/Lru/StopwatchTickConverter.cs @@ -6,7 +6,7 @@ namespace BitFaster.Caching.Lru { internal static class StopwatchTickConverter { - // On some platforms (e.g. MacOS), stopwatch and timespan have different resolution + // On some platforms (e.g. MacOS), Stopwatch and TimeSpan have different resolution internal static readonly double stopwatchAdjustmentFactor = Stopwatch.Frequency / (double)TimeSpan.TicksPerSecond; [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/BitFaster.Caching/NullableAttributes.cs b/BitFaster.Caching/NullableAttributes.cs index a0f91e03..615b0b4f 100644 --- a/BitFaster.Caching/NullableAttributes.cs +++ b/BitFaster.Caching/NullableAttributes.cs @@ -8,7 +8,7 @@ namespace System.Diagnostics.CodeAnalysis { -#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48 +#if NETSTANDARD2_0 /// Specifies that null is allowed as an input even if the corresponding type disallows it. [ExcludeFromCodeCoverage] [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] @@ -144,9 +144,7 @@ sealed class DoesNotReturnIfAttribute : Attribute /// Gets the condition parameter value. public bool ParameterValue { get; } } -#endif -#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET45 || NET451 || NET452 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48 /// Specifies that the method or property will ensure that the listed field and property members have not-null values. [ExcludeFromCodeCoverage] [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] diff --git a/BitFaster.Caching/Padding.cs b/BitFaster.Caching/Padding.cs index 12656a14..7628d25c 100644 --- a/BitFaster.Caching/Padding.cs +++ b/BitFaster.Caching/Padding.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace BitFaster.Caching +namespace BitFaster.Caching { internal class Padding { diff --git a/BitFaster.Caching/ScopedAsyncCache.cs b/BitFaster.Caching/ScopedAsyncCache.cs index 9fae539d..128c1b6a 100644 --- a/BitFaster.Caching/ScopedAsyncCache.cs +++ b/BitFaster.Caching/ScopedAsyncCache.cs @@ -87,7 +87,7 @@ public async ValueTask> ScopedGetOrAddAsync(K key, Func /// Adds a key/scoped value pair to the cache if the key does not already exist. Returns a lifetime for either /// the new value, or the existing value if the key already exists.