Skip to content

Commit

Permalink
Fixed caching of simple types
Browse files Browse the repository at this point in the history
  • Loading branch information
kubagdynia committed Nov 29, 2023
1 parent 716f376 commit ff9aeae
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 53 deletions.
2 changes: 1 addition & 1 deletion CacheDrive.Tests/MemoryAndFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public async Task CacheShouldBeSavedCorrectly()
string key = "name";

await cacheService.SetAsync(key, "John");

if (cacheService.TryGetValue(key, out string cachedValue))
{
cachedValue.Should().Be("John");
Expand Down
2 changes: 1 addition & 1 deletion CacheDrive/Models/ObjectItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public string CacheKey
=> GetCacheKey(Key);

public static string GetCacheKey(string key)
=> $"{nameof(ObjectItem<T>)}@{key}";
=> $"{typeof(T).Name.ToLower()}@{key}";

public static ObjectItem<T> Create(string key, T value)
=> new() { Key = key, Value = value };
Expand Down
22 changes: 0 additions & 22 deletions CacheDrive/Models/SpecificField.cs

This file was deleted.

24 changes: 13 additions & 11 deletions CacheDrive/Services/MemoryCacheFileStorageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace CacheDrive.Services;

internal class MemoryCacheFileStorageService : MemoryCacheService
{
private const string CacheFolderName = "cache";

public MemoryCacheFileStorageService(IOptions<CacheSettings> settings, IDateService dateService)
: base(settings, dateService)
{
Expand All @@ -24,11 +26,11 @@ public override async Task FlushAsync()
if (!item.Dirty || item.Expired(DateService))
continue;

var cachedItem = JsonSerializer.Serialize(item, JsonSettings.JsonOptions);
string cachedItem = JsonSerializer.Serialize(item, JsonSettings.JsonOptions);

var safeFilename = SafeFilenameRegex().Replace(key, string.Empty);
string safeFilename = SafeFilenameRegex().Replace(input: key, replacement: string.Empty);

var path = CachePath($"{safeFilename}.json");
string path = CachePath(fileName: $"{safeFilename}.json");

await using StreamWriter sw = File.CreateText(path);
await sw.WriteLineAsync(cachedItem);
Expand All @@ -38,13 +40,13 @@ public override async Task FlushAsync()

public override async Task InitializeAsync()
{
var dirs = Directory.GetFiles(GetCacheDirectory(), "*.json");
string[] dirs = Directory.GetFiles(path: GetCacheDirectory(), searchPattern: "*.json");

foreach (var file in dirs)
foreach (string file in dirs)
{
var jsonString = await File.ReadAllTextAsync(file);
string jsonString = await File.ReadAllTextAsync(file);

var cachedItem = JsonSerializer.Deserialize<CachedItem>(jsonString, JsonSettings.JsonOptions);
CachedItem cachedItem = JsonSerializer.Deserialize<CachedItem>(jsonString, JsonSettings.JsonOptions);

if (cachedItem is null) return;

Expand All @@ -64,18 +66,18 @@ private Regex SafeFilenameRegex()
{
if (_safeFilenameRegex is null)
{
var regSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
_safeFilenameRegex = new Regex($"[{Regex.Escape(regSearch)}]");
string regSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
_safeFilenameRegex = new Regex(pattern: $"[{Regex.Escape(regSearch)}]");
}

return _safeFilenameRegex;
}

private string CachePath(string fileName)
=> Path.Combine(Environment.CurrentDirectory, "cache", fileName);
=> Path.Combine(Environment.CurrentDirectory, CacheFolderName, fileName);

private string GetCacheDirectory()
=> Path.Combine(Environment.CurrentDirectory, "cache");
=> Path.Combine(Environment.CurrentDirectory, CacheFolderName);

private void CreateCacheDirectory()
{
Expand Down
38 changes: 20 additions & 18 deletions CacheDrive/Services/MemoryCacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public MemoryCacheService(IOptions<CacheSettings> settings, IDateService dateSer

public bool HasItem(string key)
{
if (Storage.TryGetValue(key, out var cachedItem))
if (Storage.TryGetValue(key, out CachedItem cachedItem))
{
return !cachedItem.Expired(_dateService);
}
Expand All @@ -53,14 +53,16 @@ public bool TryGetValue<T>(string key, out T value)
return true;
}
}

value = default;
return false;
}

private bool TryGetCacheableValue<T>(string key, out T value) where T : ICacheable
{
if (!Storage.TryGetValue(ObjectItem<T>.GetCacheKey(key), out CachedItem cachedItem))
string cacheKey = T.GetCacheKey(key);

if (!Storage.TryGetValue(cacheKey, out CachedItem cachedItem))
{
value = default;
return false;
Expand All @@ -79,7 +81,7 @@ private bool TryGetCacheableValue<T>(string key, out T value) where T : ICacheab

public async Task<T> GetAsync<T>(string key)
{
var cachedItem = await GetCacheableAsync<ObjectItem<T>>(key);
ObjectItem<T> cachedItem = await GetCacheableAsync<ObjectItem<T>>(key);

if (cachedItem is null)
{
Expand All @@ -91,9 +93,9 @@ public async Task<T> GetAsync<T>(string key)

private async Task<T> GetCacheableAsync<T>(string key) where T : ICacheable
{
var cacheKey = T.GetCacheKey(key);
string cacheKey = T.GetCacheKey(key);

var cachedItem = Get(cacheKey);
CachedItem cachedItem = Get(cacheKey);

if (cachedItem is null)
return await Task.FromResult<T>(default);
Expand All @@ -109,9 +111,9 @@ private async Task<T> GetCacheableAsync<T>(string key) where T : ICacheable

public void Set<T>(T item, int expirySeconds = 0) where T : ICacheable
{
var length = GetExpirationLength(expirySeconds);
TimeSpan length = GetExpirationLength(expirySeconds);

if (Storage.TryGetValue(item.CacheKey, out var cached))
if (Storage.TryGetValue(item.CacheKey, out CachedItem cached))
{
cached.Contents = JsonSerializer.SerializeToElement(item, JsonSettings.JsonOptions);
cached.Cached = DateTime.UtcNow;
Expand All @@ -120,7 +122,7 @@ public void Set<T>(T item, int expirySeconds = 0) where T : ICacheable
return;
}

var cachedItem = CachedItem.FromCacheable(item, length, _dateService, true);
CachedItem cachedItem = CachedItem.FromCacheable(item, expiry: length, _dateService, dirty: true);
Set(cachedItem);
}

Expand All @@ -131,7 +133,7 @@ public Task SetAsync<T>(string key, T value)

public Task SetAsync<T>(T item, int expirySeconds = 0) where T : ICacheable
{
var cached = Get(item);
CachedItem cached = Get(item);

TimeSpan length = GetExpirationLength(expirySeconds);

Expand All @@ -144,7 +146,7 @@ public Task SetAsync<T>(T item, int expirySeconds = 0) where T : ICacheable
return Task.CompletedTask;
}

var cachedItem = CachedItem.FromCacheable(item, length, _dateService, true);
CachedItem cachedItem = CachedItem.FromCacheable(item, expiry: length, _dateService, dirty: true);

return SetAsync(cachedItem);
}
Expand Down Expand Up @@ -174,35 +176,35 @@ private Task<bool> DeleteAsync(CachedItem item)

public void DeletePrefix(string prefix)
{
var toDeleted = new List<string>();
List<string> toDeleted = new List<string>();

foreach (var pair in Storage)
foreach (KeyValuePair<string, CachedItem> pair in Storage)
{
if (pair.Key.StartsWith(prefix))
{
toDeleted.Add(pair.Key);
}
}

foreach (var key in toDeleted)
foreach (string key in toDeleted)
{
Delete(key);
}
}

public Task DeletePrefixAsync(string prefix)
{
var toDeleted = new List<string>();
List<string> toDeleted = new List<string>();

foreach (var pair in Storage)
foreach (KeyValuePair<string, CachedItem> pair in Storage)
{
if (pair.Key.StartsWith(prefix))
{
toDeleted.Add(pair.Key);
}
}

foreach (var key in toDeleted)
foreach (string key in toDeleted)
{
DeleteAsync(key);
}
Expand All @@ -220,7 +222,7 @@ private CachedItem Get(ICacheable item)
=> Get(item.CacheKey);

private CachedItem Get(string key)
=> Storage.TryGetValue(key, out var cachedItem) ? cachedItem : null;
=> Storage.TryGetValue(key, out CachedItem cachedItem) ? cachedItem : null;

private void CalculateCacheExpiration()
{
Expand Down

0 comments on commit ff9aeae

Please sign in to comment.