diff --git a/CacheDrive/Services/HashString.cs b/CacheDrive/Services/HashString.cs new file mode 100644 index 0000000..d00fd14 --- /dev/null +++ b/CacheDrive/Services/HashString.cs @@ -0,0 +1,17 @@ +using System; +using System.Security.Cryptography; + +namespace CacheDrive.Services; + +internal static class HashString +{ + public static string HashKey(string key) + { + // Convert the string to a byte array first, to be processed + var textBytes = System.Text.Encoding.UTF8.GetBytes(key); + var hashBytes = SHA256.HashData(textBytes); + + // Convert back to a string, removing the '-' that BitConverter adds + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); + } +} \ No newline at end of file diff --git a/CacheDrive/Services/ICacheService.cs b/CacheDrive/Services/ICacheService.cs index e79d975..e17810e 100644 --- a/CacheDrive/Services/ICacheService.cs +++ b/CacheDrive/Services/ICacheService.cs @@ -25,6 +25,14 @@ public interface ICacheService /// true if the key was found in the cache, otherwise, false. bool HasItem(string key); + /// + /// Returns whether an object with the specified key exists in the cache. + /// + /// The key of the value to check. + /// Whether the key should be hashed. Can be used for long keys. + /// true if the key was found in the cache, otherwise, false. + bool HasItem(string key, bool hashKey); + /// /// Attempts to get the value associated with the specified key from the cache. /// @@ -37,6 +45,19 @@ public interface ICacheService /// true if the key was found in the cache, otherwise, false. bool TryGetValue(string key, out T value); + /// + /// Attempts to get the value associated with the specified key from the cache. + /// + /// The key of the value to get. + /// Whether the key should be hashed. Can be used for long keys. + /// + /// When this method returns, value contains the object from + /// the cache with the specified key or the default value of + /// , if the operation failed. + /// + /// true if the key was found in the cache, otherwise, false. + bool TryGetValue(string key, bool hashKey, out T value); + /// /// Get the value associated with the specified key from the cache. /// @@ -45,6 +66,16 @@ public interface ICacheService /// key or the default value of T, if the operation failed. /// T Get(string key); + + /// + /// Get the value associated with the specified key from the cache. + /// + /// The key of the value to get. + /// Whether the key should be hashed. Can be used for long keys. + /// The value contains the object from the cache with the specified + /// key or the default value of T, if the operation failed. + /// + T Get(string key, bool hashKey); /// /// Get the value associated with the specified key from the cache. @@ -55,6 +86,16 @@ public interface ICacheService /// Task GetAsync(string key); + /// + /// Get the value associated with the specified key from the cache. + /// + /// The key of the value to get. + /// Whether the key should be hashed. Can be used for long keys. + /// The value contains the object from the cache with the specified + /// key or the default value of T, if the operation failed. + /// + Task GetAsync(string key, bool hashKey); + /// /// Adds a value to the cache if the key does not already exist, or updates if the key already exists. /// @@ -63,6 +104,16 @@ public interface ICacheService /// After how many seconds a given value will expire in the cache. Optional parameter. /// By default, the value is taken from the configuration. void Set(string key, T value, int expirySeconds = 0); + + /// + /// Adds a value to the cache if the key does not already exist, or updates if the key already exists. + /// + /// The key to be added or whose value should be updated. + /// The value to add or update. + /// Whether the key should be hashed. Can be used for long keys. + /// After how many seconds a given value will expire in the cache. Optional parameter. + /// By default, the value is taken from the configuration. + void Set(string key, T value, bool hashKey, int expirySeconds = 0); /// /// Adds a value to the cache if the key does not already exist, or updates if the key already exists. @@ -73,12 +124,30 @@ public interface ICacheService /// By default, the value is taken from the configuration. Task SetAsync(string key, T value, int expirySeconds = 0); + /// + /// Adds a value to the cache if the key does not already exist, or updates if the key already exists. + /// + /// The key to be added or whose value should be updated. + /// The value to add or update. + /// Whether the key should be hashed. Can be used for long keys. + /// After how many seconds a given value will expire in the cache. Optional parameter. + /// By default, the value is taken from the configuration. + Task SetAsync(string key, T value, bool hashKey, int expirySeconds = 0); + /// /// Deletes the object associated with the given key. /// /// The key of the element to be remove. /// true if an object was removed successfully; otherwise, false. bool Delete(string key); + + /// + /// Deletes the object associated with the given key. + /// + /// The key of the element to be remove. + /// Whether the key should be hashed. Can be used for long keys. + /// true if an object was removed successfully; otherwise, false. + bool Delete(string key, bool hashKey); /// /// Deletes the object associated with the given key. @@ -87,6 +156,14 @@ public interface ICacheService /// true if an object was removed successfully; otherwise, false. Task DeleteAsync(string key); + /// + /// Deletes the object associated with the given key. + /// + /// The key of the element to be remove. + /// Whether the key should be hashed. Can be used for long keys. + /// true if an object was removed successfully; otherwise, false. + Task DeleteAsync(string key, bool hashKey); + /// /// Returns the number of objects in the cache. /// diff --git a/CacheDrive/Services/MemoryCacheService.cs b/CacheDrive/Services/MemoryCacheService.cs index b66cd42..0ff0b86 100644 --- a/CacheDrive/Services/MemoryCacheService.cs +++ b/CacheDrive/Services/MemoryCacheService.cs @@ -47,7 +47,10 @@ public bool HasItem(string key) return false; } - + + public bool HasItem(string key, bool hashKey) + => HasItem(hashKey ? HashString.HashKey(key) : key); + public bool TryGetValue(string key, out T value) { if (!CacheSettings.CacheEnabled) @@ -75,6 +78,9 @@ public bool TryGetValue(string key, out T value) return false; } + public bool TryGetValue(string key, bool hashKey, out T value) + => TryGetValue(hashKey ? HashString.HashKey(key) : key, out value); + private bool TryGetCacheableValue(string key, out T value) where T : ICacheable { string cacheKey = T.GetCacheKey(key); @@ -112,7 +118,10 @@ public T Get(string key) return cachedItem.Value; } - + + public T Get(string key, bool hashKey) + => Get(hashKey ? HashString.HashKey(key) : key); + public async Task GetAsync(string key) { if (!CacheSettings.CacheEnabled) @@ -130,6 +139,9 @@ public async Task GetAsync(string key) return await Task.FromResult(cachedItem.Value); } + public Task GetAsync(string key, bool hashKey) + => GetAsync(hashKey ? HashString.HashKey(key) : key); + private async Task GetCacheableAsync(string key) where T : ICacheable { string cacheKey = T.GetCacheKey(key); @@ -175,7 +187,10 @@ public void Set(string key, T value, int expirySeconds = 0) SetCacheableItem(CacheableItem.Create(key, value), expirySeconds); } - + + public void Set(string key, T value, bool hashKey, int expirySeconds = 0) + => Set(hashKey ? HashString.HashKey(key) : key, value, expirySeconds); + public Task SetAsync(string key, T value, int expirySeconds = 0) { if (!CacheSettings.CacheEnabled) @@ -185,7 +200,10 @@ public Task SetAsync(string key, T value, int expirySeconds = 0) return SetAsync(CacheableItem.Create(key, value), expirySeconds); } - + + public Task SetAsync(string key, T value, bool hashKey, int expirySeconds = 0) + => SetAsync(hashKey ? HashString.HashKey(key) : key, value, expirySeconds); + private void SetCacheableItem(T item, int expirySeconds = 0) where T : ICacheable { TimeSpan length = GetExpirationLength(expirySeconds); @@ -253,6 +271,9 @@ public bool Delete(string key) return key is not null && Storage.TryRemove(CacheableItem.GetCacheKey(key), out _); } + public bool Delete(string key, bool hashKey) + => Delete(hashKey ? HashString.HashKey(key) : key); + public Task DeleteAsync(string key) { if (!CacheSettings.CacheEnabled) @@ -263,6 +284,9 @@ public Task DeleteAsync(string key) return key is null ? Task.FromResult(false) : DeleteAsync(CacheableItem.GetCacheKey(key)); } + public Task DeleteAsync(string key, bool hashKey) + => DeleteAsync(hashKey ? HashString.HashKey(key) : key); + private Task DeleteAsync(string key) => key is null ? Task.FromResult(false) : Task.FromResult(Storage.TryRemove(key, out _));