Skip to content

Commit

Permalink
Add GetOrAdd method
Browse files Browse the repository at this point in the history
  • Loading branch information
InCerryGit committed Apr 26, 2023
1 parent d45b49c commit d4e8fc9
Show file tree
Hide file tree
Showing 6 changed files with 594 additions and 5 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ cache.Set(key, "my cache sync", TimeSpan.FromMinutes(5));
var result = cache.Get<string>(key);
Console.WriteLine(result);

// get or add
result = cache.GetOrAdd(key, () => "my cache sync", TimeSpan.FromMinutes(5));
Console.WriteLine(result);

// delete
cache.Delete(key);

Expand All @@ -75,6 +79,10 @@ await cache.SetAsync(key, "my cache async");
result = await cache.GetAsync<string>(key);
Console.WriteLine(result);

// get or add
result = await cache.GetOrAddAsync(key, () => "my cache async");
Console.WriteLine(result);

// delete
await cache.DeleteAsync(key);

Expand Down
60 changes: 59 additions & 1 deletion src/FasterKv.Cache.Core/FasterKvCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,35 @@ public FasterKvCache(string name,
return result.output.Get<TValue>(_valueSerializer);
}

public TValue GetOrAdd<TValue>(string key, Func<string, TValue> factory)
{
key.ArgumentNotNullOrEmpty();
factory.ArgumentNotNull();

var result = Get<TValue>(key);
if (result is not null)
return result;

result = factory(key);
Set(key, result);
return result;
}

public TValue GetOrAdd<TValue>(string key, Func<string, TValue> factory, TimeSpan expiryTime)
{
key.ArgumentNotNullOrEmpty();
factory.ArgumentNotNull();
expiryTime.ArgumentNotNegativeOrZero();

var result = Get<TValue>(key);
if (result is not null)
return result;

result = factory(key);
Set(key, result, expiryTime);
return result;
}

public void Delete(string key)
{
using var scopeSession = GetSessionWrap();
Expand Down Expand Up @@ -147,7 +176,36 @@ public void Set<TValue>(string key, TValue value, TimeSpan expiryTime)

return result.output.Get<TValue>(_valueSerializer);
}

public async Task<TValue> GetOrAddAsync<TValue>(string key, Func<string, Task<TValue>> factory, CancellationToken token = default)
{
key.ArgumentNotNullOrEmpty();
factory.ArgumentNotNull();

var result = await GetAsync<TValue>(key, token);
if (result is not null)
return result;

result = await factory(key);
await SetAsync(key, result, token);
return result;
}

public async Task<TValue> GetOrAddAsync<TValue>(string key, Func<string, Task<TValue>> factory, TimeSpan expiryTime, CancellationToken token = default)
{
key.ArgumentNotNullOrEmpty();
factory.ArgumentNotNull();
expiryTime.ArgumentNotNegativeOrZero();

var result = await GetAsync<TValue>(key, token);
if (result is not null)
return result;

result = await factory(key);
await SetAsync(key, result, expiryTime, token);
return result;
}

public async Task DeleteAsync(string key, CancellationToken token = default)
{
key.ArgumentNotNull();
Expand All @@ -171,7 +229,7 @@ public async Task SetAsync<TValue>(string key, TValue? value, TimeSpan expiryTim
using var sessionWrap = GetSessionWrap();
await SetInternalAsync(sessionWrap, key, value, token, expiryTime);
}

private async Task SetInternalAsync<TValue>(ClientSessionWrap sessionWrap, string key, TValue? value,
CancellationToken cancellationToken, TimeSpan? expiryTime = null)
{
Expand Down
60 changes: 56 additions & 4 deletions src/FasterKv.Cache.Core/FasterKvStore.TValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,32 @@ public FasterKvCache(string name,
return result.output.Data;
}

public TValue GetOrAdd(string key, Func<string,TValue> factory)
{
key.ArgumentNotNullOrEmpty();

var value = Get(key);
if (value is not null)
return value;

value = factory(key);
Set(key, value);
return value;
}

public TValue GetOrAdd(string key, Func<string,TValue> factory, TimeSpan expiryTime)
{
key.ArgumentNotNullOrEmpty();

var value = Get(key);
if (value is not null)
return value;

value = factory(key);
Set(key, value, expiryTime);
return value;
}

public void Delete(string key)
{
key.ArgumentNotNull();
Expand Down Expand Up @@ -141,31 +167,57 @@ public void Set(string key, TValue value, TimeSpan expiryTime)

return result.output.Data;
}


public async Task<TValue> GetOrAddAsync(string key, Func<string,Task<TValue>> factory, CancellationToken token = default)
{
key.ArgumentNotNullOrEmpty();

var value = await GetAsync(key, token);
if (value is not null)
return value;

value = await factory(key);
await SetAsync(key, value, token);
return value;
}

public async Task<TValue> GetOrAddAsync(string key, Func<string,Task<TValue>> factory, TimeSpan expiryTime, CancellationToken token = default)
{
key.ArgumentNotNullOrEmpty();

var value = await GetAsync(key, token);
if (value is not null)
return value;

value = await factory(key);
await SetAsync(key, value, expiryTime, token);
return value;
}

public async Task DeleteAsync(string key, CancellationToken token = default)
{
key.ArgumentNotNull();

using var scopeSession = GetSessionWrap();
(await scopeSession.Session.DeleteAsync(ref key, token: token).ConfigureAwait(false)).Complete();
}

public async Task SetAsync(string key, TValue? value, CancellationToken token = default)
{
key.ArgumentNotNullOrEmpty();

using var sessionWrap = GetSessionWrap();
await SetInternalAsync(sessionWrap, key, value, token);
}

public async Task SetAsync(string key, TValue? value, TimeSpan expiryTime, CancellationToken token = default)
{
key.ArgumentNotNullOrEmpty();

using var sessionWrap = GetSessionWrap();
await SetInternalAsync(sessionWrap, key, value, token, expiryTime);
}


private void SetInternal(ClientSessionWrap<TValue> sessionWrap, string key, TValue? value,
TimeSpan? expiryTime = null)
Expand Down
Loading

0 comments on commit d4e8fc9

Please sign in to comment.