Skip to content

Commit

Permalink
Add GetAllKeysByPrefix to InMemory and Redis (dotnetcore#422)
Browse files Browse the repository at this point in the history
* - add getall (inMemory - redis)
- add getall-keys (inMemory - resis)

* refactor get-all and get-all-keys with optional prefix

* add GetAllKeysByPrefix for InMemoryCache and Redis

* handle base KeyPrefix from config in result GetAllKeysByPrefix
  • Loading branch information
meysamhadeli authored Nov 30, 2022
1 parent be302f9 commit 7b63e26
Show file tree
Hide file tree
Showing 24 changed files with 312 additions and 29 deletions.
63 changes: 37 additions & 26 deletions sample/EasyCaching.Demo.ConsoleApp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace EasyCaching.Demo.ConsoleApp
using System.Threading.Tasks;

namespace EasyCaching.Demo.ConsoleApp
{
using EasyCaching.Core;
using EasyCaching.SQLite;
Expand All @@ -16,13 +18,13 @@ static void Main(string[] args)
{
option.UseInMemory("m1");

//option.UseRedis(config =>
//{
// config.DBConfig = new Redis.RedisDBOptions { Configuration = "localhost" };
// config.SerializerName = "json";
//}, "r1");


// option.UseRedis(config =>
// {
// config.DBConfig = new Redis.RedisDBOptions { Configuration = "localhost" };
// config.SerializerName = "json";
// }, "r1");
//
option.UseSQLite(c =>
{
c.DBConfig = new SQLiteDBOptions
Expand All @@ -33,43 +35,51 @@ static void Main(string[] args)
};
}, "s1");

//option.WithJson(jsonSerializerSettingsConfigure: x =>
//{
// x.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.None;
//}, "json");
// option.WithJson(jsonSerializerSettingsConfigure: x =>
// {
// x.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.None;
// }, "json");
});

IServiceProvider serviceProvider = services.BuildServiceProvider();
var factory = serviceProvider.GetService<IEasyCachingProviderFactory>();

//var redisCache = factory.GetCachingProvider("r1");

//redisCache.Set<Product>("rkey", new Product() { Name = "test" }, TimeSpan.FromSeconds(20));

//var redisVal = redisCache.Get<Product>("rkey");

//Console.WriteLine($"redis cache get value, {redisVal.HasValue} {redisVal.IsNull} {redisVal.Value} ");



// var redisCache = factory.GetCachingProvider("r1");
//
// redisCache.Set<Product>("rkey", new Product() { Name = "test" }, TimeSpan.FromSeconds(20));
//
// var redisAllKey = redisCache.GetAllKeysByPrefix("rkey");
//
// var redisVal = redisCache.Get<Product>("rkey");
//
// Console.WriteLine($"redis cache get value, {redisVal.HasValue} {redisVal.IsNull} {redisVal.Value}");



var mCache = factory.GetCachingProvider("m1");

mCache.Set<Product>("mkey1", new Product() { Name = "test" }, TimeSpan.FromSeconds(20));

var mVal1 = mCache.Get<Product>("mkey1");


mCache.Set<string>("mkey", "mvalue", TimeSpan.FromSeconds(20));

var mVal = mCache.Get<string>("mkey");


var mAllKey = mCache.GetAllKeysByPrefix("mk");

Console.WriteLine($"in-memory cache get value, {mVal.HasValue} {mVal.IsNull} {mVal.Value} ");


var sCache = factory.GetCachingProvider("s1");


sCache.Set<string>("skey", "svalue", TimeSpan.FromSeconds(20));


var sVal = sCache.Get<string>("skey");


Console.WriteLine($"sqlite cache get value, {sVal.HasValue} {sVal.IsNull} {sVal.Value} ");

Console.ReadKey();
Expand All @@ -82,3 +92,4 @@ public class Product
public string Name { get; set; }
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ public override async Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T
return result;
}

public override Task<IEnumerable<string>> BaseGetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default)
{
throw new NotSupportedException();
}

/// <summary>
/// Gets the async.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,11 @@ public override IDictionary<string, CacheValue<T>> BaseGetAll<T>(IEnumerable<str
return result;
}

public override IEnumerable<string> BaseGetAllKeysByPrefix(string prefix)
{
throw new NotSupportedException();
}

/// <summary>
/// Handles the prefix of CacheKey.
/// </summary>
Expand Down
54 changes: 54 additions & 0 deletions src/EasyCaching.Core/EasyCachingAbstractProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ protected EasyCachingAbstractProvider(IDistributedLockFactory lockFactory, BaseP
public abstract Task BaseFlushAsync(CancellationToken cancellationToken = default);
public abstract CacheValue<T> BaseGet<T>(string cacheKey, Func<T> dataRetriever, TimeSpan expiration);
public abstract CacheValue<T> BaseGet<T>(string cacheKey);
public abstract IEnumerable<string> BaseGetAllKeysByPrefix(string prefix);
public abstract Task<IEnumerable<string>> BaseGetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default);
public abstract IDictionary<string, CacheValue<T>> BaseGetAll<T>(IEnumerable<string> cacheKeys);
public abstract Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T>(IEnumerable<string> cacheKeys, CancellationToken cancellationToken = default);
public abstract Task<CacheValue<T>> BaseGetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, TimeSpan expiration, CancellationToken cancellationToken = default);
Expand Down Expand Up @@ -256,6 +258,58 @@ public CacheValue<T> Get<T>(string cacheKey)
}
}
}

public IEnumerable<string> GetAllKeysByPrefix(string prefix)
{
var operationId = s_diagnosticListener.WriteGetCacheBefore(new BeforeGetRequestEventData(CachingProviderType.ToString(), Name, nameof(GetAllKeysByPrefix), new[] { prefix }));
Exception e = null;
try
{
return BaseGetAllKeysByPrefix(prefix);
}
catch (Exception ex)
{
e = ex;
throw;
}
finally
{
if (e != null)
{
s_diagnosticListener.WriteGetCacheError(operationId, e);
}
else
{
s_diagnosticListener.WriteGetCacheAfter(operationId);
}
}
}

public async Task<IEnumerable<string>> GetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default)
{
var operationId = s_diagnosticListener.WriteGetCacheBefore(new BeforeGetRequestEventData(CachingProviderType.ToString(), Name, nameof(GetAllKeysByPrefixAsync), new[] { prefix }));
Exception e = null;
try
{
return await BaseGetAllKeysByPrefixAsync(prefix);
}
catch (Exception ex)
{
e = ex;
throw;
}
finally
{
if (e != null)
{
s_diagnosticListener.WriteGetCacheError(operationId, e);
}
else
{
s_diagnosticListener.WriteGetCacheAfter(operationId);
}
}
}

public IDictionary<string, CacheValue<T>> GetAll<T>(IEnumerable<string> cacheKeys)
{
Expand Down
17 changes: 16 additions & 1 deletion src/EasyCaching.Core/IEasyCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,23 @@ public interface IEasyCachingProvider : IEasyCachingProviderBase
/// </summary>
/// <value><c>true</c> if is use lock; otherwise, <c>false</c>.</value>
bool UseLock { get; }

/// <summary>
/// Gets all keys by prefix.
/// </summary>
/// <param name="prefix">Prefix.</param>
/// <returns>The all keys by prefix.</returns>
IEnumerable<string> GetAllKeysByPrefix(string prefix);

/// <summary>
/// Gets all keys by prefix async.
/// </summary>
/// <param name="prefix">Prefix.</param>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>The all keys by prefix async.</returns>
Task<IEnumerable<string>> GetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default);

/// <summary>
/// <summary>
/// Gets all.
/// </summary>
/// <returns>The all.</returns>
Expand Down
6 changes: 6 additions & 0 deletions src/EasyCaching.Disk/DefaultDiskCachingProvider.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public override async Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T
return dict;
}


public override Task<IEnumerable<string>> BaseGetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default)
{
throw new NotSupportedException();
}

public override async Task<CacheValue<T>> BaseGetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, TimeSpan expiration, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
Expand Down
5 changes: 5 additions & 0 deletions src/EasyCaching.Disk/DefaultDiskCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ public override IDictionary<string, CacheValue<T>> BaseGetAll<T>(IEnumerable<str
return dict;
}

public override IEnumerable<string> BaseGetAllKeysByPrefix(string prefix)
{
throw new NotSupportedException();
}

public override IDictionary<string, CacheValue<T>> BaseGetByPrefix<T>(string prefix)
{
ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public override async Task BaseFlushAsync(CancellationToken cancellationToken =
}
}

public override Task<IEnumerable<string>> BaseGetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default)
{
throw new NotSupportedException();
}

public override async Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T>(IEnumerable<string> cacheKeys,
CancellationToken cancellationToken = default)
Expand Down
5 changes: 5 additions & 0 deletions src/EasyCaching.FasterKv/DefaultFasterKvCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ public override CacheValue<T> BaseGet<T>(string cacheKey)
using var session = GetSession();
return BaseGetInternal<T>(cacheKey, session);
}

public override IEnumerable<string> BaseGetAllKeysByPrefix(string prefix)
{
throw new NotSupportedException();
}

public override IDictionary<string, CacheValue<T>> BaseGetAll<T>(IEnumerable<string> cacheKeys)
{
Expand Down
15 changes: 15 additions & 0 deletions src/EasyCaching.InMemory/DefaultInMemoryCachingProvider.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,21 @@ public override async Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T

return await Task.FromResult(_cache.GetAll<T>(cacheKeys));
}


/// <summary>
/// Get all cacheKey by prefix async.
/// </summary>
/// <param name="prefix">Cache keys.</param>
/// <param name="cancellationToken">Cache keys.</param>
/// <returns>Get all cacheKey by prefix async.</returns>
public override Task<IEnumerable<string>> BaseGetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default)
{
if (_options.EnableLogging)
_logger?.LogInformation("GetAllKeysAsync");

return Task.FromResult(_cache.GetAllKeys(prefix));
}

/// <summary>
/// Gets the by prefix async.
Expand Down
13 changes: 13 additions & 0 deletions src/EasyCaching.InMemory/DefaultInMemoryCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,19 @@ public override IDictionary<string, CacheValue<T>> BaseGetAll<T>(IEnumerable<str
return _cache.GetAll<T>(cacheKeys);
}

/// <summary>
/// Get all cacheKey by prefix.
/// </summary>
/// <param name="prefix">Prefix.</param>
/// <returns>Get all cacheKey by prefix.</returns>
public override IEnumerable<string> BaseGetAllKeysByPrefix(string prefix)
{
if (_options.EnableLogging)
_logger?.LogInformation("GetAllKeys");

return _cache.GetAllKeys(prefix);
}

/// <summary>
/// Gets the by prefix.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions src/EasyCaching.InMemory/Internal/IInMemoryCaching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public interface IInMemoryCaching
bool Remove(string key);
int RemoveByPrefix(string prefix);
int RemoveByPattern(string searchKey, SearchKeyPattern searchPattern);
IEnumerable<string> GetAllKeys(string prefix);
IDictionary<string, CacheValue<T>> GetAll<T>(IEnumerable<string> keys);
int SetAll<T>(IDictionary<string, T> values, TimeSpan? expiresIn = null);
bool Replace<T>(string key, T value, TimeSpan? expiresIn = null);
Expand Down
15 changes: 15 additions & 0 deletions src/EasyCaching.InMemory/Internal/InMemoryCaching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ public int RemoveByPattern(string searchKey, SearchKeyPattern searchPattern)
return RemoveAll(keysToRemove);
}

public IEnumerable<string> GetAllKeys(string prefix)
{
return _memory.Values.Where(x => x.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) && x.ExpiresAt > SystemClock.UtcNow)
.Select(x=> x.Key).ToList();
}

private static bool FilterByPattern(string key, string searchKey, SearchKeyPattern searchKeyPattern)
{
switch (searchKeyPattern)
Expand All @@ -306,6 +312,15 @@ public IDictionary<string, CacheValue<T>> GetAll<T>(IEnumerable<string> keys)
return map;
}

public IDictionary<string, CacheValue<T>> GetAll<T>(string prefix = "")
{
var values = string.IsNullOrEmpty(prefix)
? _memory.Values.Where(x => x.ExpiresAt > SystemClock.UtcNow)
: _memory.Values.Where(x => x.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) && x.ExpiresAt > SystemClock.UtcNow);

return values.ToDictionary(k => k.Key, v => new CacheValue<T>(v.GetValue<T>(_options.EnableReadDeepClone), true));
}

public int SetAll<T>(IDictionary<string, T> values, TimeSpan? expiresIn = null)
{
if (values == null || values.Count == 0) return 0;
Expand Down
5 changes: 5 additions & 0 deletions src/EasyCaching.LiteDB/DefaultLiteDBCachingProvider.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ public override async Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T
ArgumentCheck.NotNullAndCountGTZero(cacheKeys, nameof(cacheKeys));
return await Task.Run(() => BaseGetAll<T>(cacheKeys), cancellationToken);
}

public override Task<IEnumerable<string>> BaseGetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default)
{
throw new NotSupportedException();
}

/// <summary>
/// Gets the by prefix async.
Expand Down
5 changes: 5 additions & 0 deletions src/EasyCaching.LiteDB/DefaultLiteDBCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@ public override IDictionary<string, CacheValue<T>> BaseGetAll<T>(IEnumerable<str
return GetDict<T>(list);
}

public override IEnumerable<string> BaseGetAllKeysByPrefix(string prefix)
{
throw new NotSupportedException();
}

/// <summary>
/// Gets the dict.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ public override async Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T
pair => pair.Key,
pair => ConvertFromStoredValue<T>(pair.Value));
}

public override Task<IEnumerable<string>> BaseGetAllKeysByPrefixAsync(string prefix, CancellationToken cancellationToken = default)
{
throw new NotSupportedException();
}

/// <summary>
/// Gets the by prefix async.
Expand Down
5 changes: 5 additions & 0 deletions src/EasyCaching.Memcached/DefaultMemcachedCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ public override IDictionary<string, CacheValue<T>> BaseGetAll<T>(IEnumerable<str
pair => ConvertFromStoredValue<T>(pair.Value));
}

public override IEnumerable<string> BaseGetAllKeysByPrefix(string prefix)
{
throw new NotSupportedException();
}

/// <summary>
/// Gets the by prefix.
/// </summary>
Expand Down
Loading

0 comments on commit 7b63e26

Please sign in to comment.