From ca8ea345417c85fdf95af5eeae3e0584f06e3d2a Mon Sep 17 00:00:00 2001 From: amirsolhi Date: Sun, 18 Dec 2022 14:48:00 +0330 Subject: [PATCH] zremrangebyscore support for both Redis and CSRedis --- ...DefaultCSRedisCachingProvider.SortedSet.cs | 17 ++++++++- src/EasyCaching.Core/IRedisCachingProvider.cs | 18 +++++++++ .../DefaultRedisCachingProvider.SortedSet.cs | 15 +++++++- .../BaseRedisFeatureCachingProviderTest.cs | 37 +++++++++++++++++-- 4 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs index 9465fc3e..08ee7076 100755 --- a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs +++ b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs @@ -1,7 +1,6 @@ namespace EasyCaching.CSRedis { using EasyCaching.Core; - using EasyCaching.Core.Internal; using System.Collections.Generic; using System.Threading.Tasks; @@ -86,6 +85,13 @@ public List ZRangeByScore(string cacheKey, double min, double max, long? c return list; } + public long ZRangeRemByScore(string cacheKey, double min, double max) + { + ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); + + return _cache.ZRemRangeByScore(cacheKey, (decimal)min, (decimal)max); + } + public long? ZRank(string cacheKey, T cacheValue) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); @@ -163,7 +169,7 @@ public async Task ZIncrByAsync(string cacheKey, string field, double val ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); ArgumentCheck.NotNullOrWhiteSpace(field, nameof(field)); - var value= await _cache.ZIncrByAsync(cacheKey, field, (decimal)val); + var value = await _cache.ZIncrByAsync(cacheKey, field, (decimal)val); return (double)value; } @@ -207,6 +213,13 @@ public async Task> ZRangeByScoreAsync(string cacheKey, double min, do return list; } + public async Task ZRangeRemByScoreAsync(string cacheKey, double min, double max) + { + ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); + + return await _cache.ZRemRangeByScoreAsync(cacheKey, (decimal)min, (decimal)max); + } + public async Task ZRankAsync(string cacheKey, T cacheValue) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); diff --git a/src/EasyCaching.Core/IRedisCachingProvider.cs b/src/EasyCaching.Core/IRedisCachingProvider.cs index a317deeb..fc5b6beb 100644 --- a/src/EasyCaching.Core/IRedisCachingProvider.cs +++ b/src/EasyCaching.Core/IRedisCachingProvider.cs @@ -752,6 +752,16 @@ public interface IRedisCachingProvider /// /// List ZRangeByScore(string cacheKey, double min, double max, long? count = null, long offset = 0); + + /// + /// https://redis.io/commands/zremrangebyscore/ + /// + /// + /// + /// + /// The number of elements removed + long ZRangeRemByScore(string cacheKey, double min, double max); + /// /// https://redis.io/commands/zrank /// @@ -835,6 +845,14 @@ public interface IRedisCachingProvider /// Task> ZRangeByScoreAsync(string cacheKey, double min, double max, long? count = null, long offset = 0); /// + /// https://redis.io/commands/zremrangebyscore/ + /// + /// + /// + /// + /// The number of elements removed + Task ZRangeRemByScoreAsync(string cacheKey, double min, double max); + /// /// https://redis.io/commands/zrank /// /// diff --git a/src/EasyCaching.Redis/DefaultRedisCachingProvider.SortedSet.cs b/src/EasyCaching.Redis/DefaultRedisCachingProvider.SortedSet.cs index 4196330f..84e99873 100755 --- a/src/EasyCaching.Redis/DefaultRedisCachingProvider.SortedSet.cs +++ b/src/EasyCaching.Redis/DefaultRedisCachingProvider.SortedSet.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using EasyCaching.Core; - using EasyCaching.Core.Internal; using StackExchange.Redis; /// @@ -92,6 +91,13 @@ public List ZRangeByScore(string cacheKey, double min, double max, long? c return list; } + public long ZRangeRemByScore(string cacheKey, double min, double max) + { + ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); + + return _cache.SortedSetRemoveRangeByScore(cacheKey, min, max); + } + public long? ZRank(string cacheKey, T cacheValue) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); @@ -213,6 +219,13 @@ public async Task> ZRangeByScoreAsync(string cacheKey, double min, do return list; } + public async Task ZRangeRemByScoreAsync(string cacheKey, double min, double max) + { + ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); + + return await _cache.SortedSetRemoveRangeByScoreAsync(cacheKey, min, max); + } + public async Task ZRankAsync(string cacheKey, T cacheValue) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); diff --git a/test/EasyCaching.UnitTests/CachingTests/BaseRedisFeatureCachingProviderTest.cs b/test/EasyCaching.UnitTests/CachingTests/BaseRedisFeatureCachingProviderTest.cs index d2da866e..82bf69f4 100644 --- a/test/EasyCaching.UnitTests/CachingTests/BaseRedisFeatureCachingProviderTest.cs +++ b/test/EasyCaching.UnitTests/CachingTests/BaseRedisFeatureCachingProviderTest.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; using Xunit; + + public abstract class BaseRedisFeatureCachingProviderTest { protected IRedisCachingProvider _provider; @@ -81,7 +83,7 @@ protected virtual async Task StringSet_And_KeyExpire_And_TTL_Async_Should_Succee await _provider.KeyDelAsync(cacheKey); } - + [Fact] protected virtual async Task StringSetWithExpiration_And_Persist_And_TTL_Async_Should_Succeed() { @@ -90,7 +92,7 @@ protected virtual async Task StringSetWithExpiration_And_Persist_And_TTL_Async_S var res = await _provider.StringSetAsync(cacheKey, "123", TimeSpan.FromSeconds(10)); Assert.True(res); - + var initialTtl = await _provider.TTLAsync(cacheKey); Assert.InRange(initialTtl, 1, 10); @@ -1689,7 +1691,36 @@ protected virtual async void ZRangeByScoreAsync_Should_Succeed() Assert.Contains("two", items); _baseProvider.Remove(cacheKey); - } + } + + [Fact] + protected virtual async void ZRangeRemByScoreAsync_Should_Succeed() + { + var cacheKey = $"{_nameSpace}-{Guid.NewGuid().ToString()}"; + + var dict = new Dictionary() + { + { "one", 1}, + { "two", 2}, + { "three", 3}, + { "four", 4}, + }; + + var res = await _provider.ZAddAsync(cacheKey, dict); + + var deletedCount = await _provider.ZRangeRemByScoreAsync(cacheKey, 1, 2); + + var items = await _provider.ZRangeByScoreAsync(cacheKey, 1, 4); + + Assert.Equal(2, deletedCount); + Assert.DoesNotContain("one", items); + Assert.DoesNotContain("two", items); + Assert.Contains("three", items); + Assert.Contains("four", items); + + _baseProvider.Remove(cacheKey); + } + #endregion #region Hyperloglog