From 13d1e98ce1ab62bf7abde6b8ba64ee97f3d014f6 Mon Sep 17 00:00:00 2001 From: neon-sunset <20912188+neon-sunset@users.noreply.github.com> Date: Sat, 18 Mar 2023 23:46:28 +0200 Subject: [PATCH] Add `Cached.Save(K1..K7, V, TimeSpan)` and move save logic from CachedExtensions --- src/FastCache.Cached/Cached.Save.cs | 72 ++++++ src/FastCache.Cached/Cached.TryGet.cs | 2 +- src/FastCache.Cached/CachedExtensions.cs | 95 +++----- tests/FastCache.CachedTests/Cached_Save.cs | 270 +++++++++++++++++++++ 4 files changed, 371 insertions(+), 68 deletions(-) create mode 100644 src/FastCache.Cached/Cached.Save.cs create mode 100644 tests/FastCache.CachedTests/Cached_Save.cs diff --git a/src/FastCache.Cached/Cached.Save.cs b/src/FastCache.Cached/Cached.Save.cs new file mode 100644 index 0000000..ba9c8b4 --- /dev/null +++ b/src/FastCache.Cached/Cached.Save.cs @@ -0,0 +1,72 @@ +namespace FastCache; + +public static partial class Cached +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K key, V value, TimeSpan expiration) where K : notnull => + SaveInternal(key, value, expiration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K key, V value, TimeSpan expiration, uint limit) where K : notnull => + SaveInternal(key, value, expiration, limit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, V value, TimeSpan expiration) => + SaveInternal((param1, param2), value, expiration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, V value, TimeSpan expiration, uint limit) => + SaveInternal((param1, param2), value, expiration, limit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, V value, TimeSpan expiration) => + SaveInternal((param1, param2, param3), value, expiration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, V value, TimeSpan expiration, uint limit) => + SaveInternal((param1, param2, param3), value, expiration, limit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, V value, TimeSpan expiration) => + SaveInternal((param1, param2, param3, param4), value, expiration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, V value, TimeSpan expiration, uint limit) => + SaveInternal((param1, param2, param3, param4), value, expiration, limit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, V value, TimeSpan expiration) => + SaveInternal((param1, param2, param3, param4, param5), value, expiration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, V value, TimeSpan expiration, uint limit) => + SaveInternal((param1, param2, param3, param4, param5), value, expiration, limit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, V value, TimeSpan expiration) => + SaveInternal((param1, param2, param3, param4, param5, param6), value, expiration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, V value, TimeSpan expiration, uint limit) => + SaveInternal((param1, param2, param3, param4, param5, param6), value, expiration, limit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, K7 param7, V value, TimeSpan expiration) => + SaveInternal((param1, param2, param3, param4, param5, param6, param7), value, expiration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static V Save(K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, K7 param7, V value, TimeSpan expiration, uint limit) => + SaveInternal((param1, param2, param3, param4, param5, param6, param7), value, expiration, limit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static V SaveInternal(K key, V value, TimeSpan expiration) where K : notnull + { + return new Cached(key, default!, found: false).Save(value, expiration); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static V SaveInternal(K key, V value, TimeSpan expiration, uint limit) where K : notnull + { + return new Cached(key, default!, found: false).Save(value, expiration, limit); + } +} \ No newline at end of file diff --git a/src/FastCache.Cached/Cached.TryGet.cs b/src/FastCache.Cached/Cached.TryGet.cs index 47760b8..b1684ee 100644 --- a/src/FastCache.Cached/Cached.TryGet.cs +++ b/src/FastCache.Cached/Cached.TryGet.cs @@ -1,6 +1,6 @@ namespace FastCache; -public static class Cached +public static partial class Cached { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGet(K key, out Cached cached) where K : notnull diff --git a/src/FastCache.Cached/CachedExtensions.cs b/src/FastCache.Cached/CachedExtensions.cs index 7f7d343..142225a 100644 --- a/src/FastCache.Cached/CachedExtensions.cs +++ b/src/FastCache.Cached/CachedExtensions.cs @@ -2,85 +2,46 @@ namespace FastCache.Extensions; public static class CachedExtensions { - public static V Cache(this V value, K key, TimeSpan expiration) where K : notnull - { - return CacheInternal(key, value, expiration); - } + public static V Cache(this V value, K key, TimeSpan expiration) where K : notnull => + Cached.Save(key, value, expiration); - public static V Cache(this V value, K key, TimeSpan expiration, uint limit) where K : notnull - { - return CacheInternal(key, value, expiration, limit); - } + public static V Cache(this V value, K key, TimeSpan expiration, uint limit) where K : notnull => + Cached.Save(key, value, expiration, limit); - public static V Cache(this V value, K1 param1, K2 param2, TimeSpan expiration) - { - return CacheInternal((param1, param2), value, expiration); - } + public static V Cache(this V value, K1 param1, K2 param2, TimeSpan expiration) => + Cached.Save(param1, param2, value, expiration); - public static V Cache(this V value, K1 param1, K2 param2, TimeSpan expiration, uint limit) - { - return CacheInternal((param1, param2), value, expiration, limit); - } + public static V Cache(this V value, K1 param1, K2 param2, TimeSpan expiration, uint limit) => + Cached.Save(param1, param2, value, expiration, limit); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, TimeSpan expiration) - { - return CacheInternal((param1, param2, param3), value, expiration); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, TimeSpan expiration) => + Cached.Save(param1, param2, param3, value, expiration); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, TimeSpan expiration, uint limit) - { - return CacheInternal((param1, param2, param3), value, expiration, limit); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, TimeSpan expiration, uint limit) => + Cached.Save(param1, param2, param3, value, expiration, limit); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, TimeSpan expiration) - { - return CacheInternal((param1, param2, param3, param4), value, expiration); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, TimeSpan expiration) => + Cached.Save(param1, param2, param3, param4, value, expiration); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, TimeSpan expiration, uint limit) - { - return CacheInternal((param1, param2, param3, param4), value, expiration, limit); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, TimeSpan expiration, uint limit) => + Cached.Save(param1, param2, param3, param4, value, expiration, limit); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, TimeSpan expiration) - { - return CacheInternal((param1, param2, param3, param4, param5), value, expiration); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, TimeSpan expiration) => + Cached.Save(param1, param2, param3, param4, param5, value, expiration); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, TimeSpan expiration, uint limit) - { - return CacheInternal((param1, param2, param3, param4, param5), value, expiration, limit); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, TimeSpan expiration, uint limit) => + Cached.Save(param1, param2, param3, param4, param5, value, expiration, limit); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, TimeSpan expiration) - { - return CacheInternal((param1, param2, param3, param4, param5, param6), value, expiration); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, TimeSpan expiration) => + Cached.Save(param1, param2, param3, param4, param5, param6, value, expiration); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, TimeSpan expiration, uint limit) - { - return CacheInternal((param1, param2, param3, param4, param5, param6), value, expiration, limit); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, TimeSpan expiration, uint limit) => + Cached.Save(param1, param2, param3, param4, param5, param6, value, expiration, limit); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, K7 param7, TimeSpan expiration) - { - return CacheInternal((param1, param2, param3, param4, param5, param6, param7), value, expiration); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, K7 param7, TimeSpan expiration) => + Cached.Save(param1, param2, param3, param4, param5, param6, param7, value, expiration); - public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, K7 param7, TimeSpan expiration, uint limit) - { - return CacheInternal((param1, param2, param3, param4, param5, param6, param7), value, expiration, limit); - } + public static V Cache(this V value, K1 param1, K2 param2, K3 param3, K4 param4, K5 param5, K6 param6, K7 param7, TimeSpan expiration, uint limit) => + Cached.Save(param1, param2, param3, param4, param5, param6, param7, value, expiration, limit); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static V CacheInternal(K key, V value, TimeSpan expiration) where K : notnull - { - return new Cached(key, default!, found: false).Save(value, expiration); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static V CacheInternal(K key, V value, TimeSpan expiration, uint limit) where K : notnull - { - return new Cached(key, default!, found: false).Save(value, expiration, limit); - } } diff --git a/tests/FastCache.CachedTests/Cached_Save.cs b/tests/FastCache.CachedTests/Cached_Save.cs new file mode 100644 index 0000000..f71cb35 --- /dev/null +++ b/tests/FastCache.CachedTests/Cached_Save.cs @@ -0,0 +1,270 @@ +namespace FastCache.CachedTests; + +public sealed class CachedTests_Save +{ + [Fact] + public void SaveK1_SavesCorrectly() + { + var k1 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, out _); + var returnValue = Cached.Save(k1, value, TimeSpan.FromSeconds(30)); + var foundAfter = Cached.TryGet(k1, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK1Limit_SavesCorrectly() + { + var k1 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, out _); + var returnValue = Cached.Save(k1, value, TimeSpan.FromSeconds(30), limit: int.MaxValue); + var foundAfter = Cached.TryGet(k1, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK2_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, out _); + var returnValue = Cached.Save(k1, k2, value, TimeSpan.FromSeconds(30)); + var foundAfter = Cached.TryGet(k1, k2, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK2Limit_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, out _); + var returnValue = Cached.Save(k1, k2, value, TimeSpan.FromSeconds(30), limit: int.MaxValue); + var foundAfter = Cached.TryGet(k1, k2, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK3_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, out _); + var returnValue = Cached.Save(k1, k2, k3, value, TimeSpan.FromSeconds(30)); + var foundAfter = Cached.TryGet(k1, k2, k3, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK3Limit_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, out _); + var returnValue = Cached.Save(k1, k2, k3, value, TimeSpan.FromSeconds(30), limit: int.MaxValue); + var foundAfter = Cached.TryGet(k1, k2, k3, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK4_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, value, TimeSpan.FromSeconds(30)); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK4Limit_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, value, TimeSpan.FromSeconds(30), limit: int.MaxValue); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK5_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var k5 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, k5, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, k5, value, TimeSpan.FromSeconds(30)); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, k5, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK5Limit_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var k5 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, k5, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, k5, value, TimeSpan.FromSeconds(30), limit: int.MaxValue); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, k5, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK6_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var k5 = GetTestKey(); + var k6 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, k5, k6, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, k5, k6, value, TimeSpan.FromSeconds(30)); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, k5, k6, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK6Limit_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var k5 = GetTestKey(); + var k6 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, k5, k6, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, k5, k6, value, TimeSpan.FromSeconds(30), limit: int.MaxValue); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, k5, k6, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK7_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var k5 = GetTestKey(); + var k6 = GetTestKey(); + var k7 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, k5, k6, k7, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, k5, k6, k7, value, TimeSpan.FromSeconds(30)); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, k5, k6, k7, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } + + [Fact] + public void SaveK7Limit_SavesCorrectly() + { + var k1 = GetTestKey(); + var k2 = GetTestKey(); + var k3 = GetTestKey(); + var k4 = GetTestKey(); + var k5 = GetTestKey(); + var k6 = GetTestKey(); + var k7 = GetTestKey(); + var value = GetRandomString(); + + var foundBefore = Cached.TryGet(k1, k2, k3, k4, k5, k6, k7, out _); + var returnValue = Cached.Save(k1, k2, k3, k4, k5, k6, k7, value, TimeSpan.FromSeconds(30), limit: int.MaxValue); + var foundAfter = Cached.TryGet(k1, k2, k3, k4, k5, k6, k7, out var cachedAfter); + + Assert.True(foundAfter); + Assert.False(foundBefore); + Assert.Equal(value, returnValue); + Assert.Equal(value, cachedAfter); + } +}