Skip to content

Commit 328b328

Browse files
ahockerstenMichaC
authored andcommitted
Support GetOrAdd and TryGetOrAdd for CacheItem (#160)
Support GetOrAdd and TryGetOrAdd for CacheItem
1 parent b69d1e7 commit 328b328

3 files changed

Lines changed: 183 additions & 20 deletions

File tree

src/CacheManager.Core/BaseCacheManager.GetOrAdd.cs

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public TCacheValue GetOrAdd(string key, Func<string, TCacheValue> valueFactory)
2020
NotNullOrWhiteSpace(key, nameof(key));
2121
NotNull(valueFactory, nameof(valueFactory));
2222

23-
return GetOrAddInternal(key, null, (k, r) => valueFactory(k));
23+
return GetOrAddInternal(key, null, (k, r) => new CacheItem<TCacheValue>(k, valueFactory(k))).Value;
2424
}
2525

2626
/// <inheritdoc />
@@ -30,7 +30,26 @@ public TCacheValue GetOrAdd(string key, string region, Func<string, string, TCac
3030
NotNullOrWhiteSpace(region, nameof(region));
3131
NotNull(valueFactory, nameof(valueFactory));
3232

33-
return GetOrAddInternal(key, region, (k, r) => valueFactory(k, r));
33+
return GetOrAddInternal(key, region, (k, r) => new CacheItem<TCacheValue>(k, r, valueFactory(k, r))).Value;
34+
}
35+
36+
/// <inheritdoc />
37+
public CacheItem<TCacheValue> GetOrAdd(string key, Func<string, CacheItem<TCacheValue>> valueFactory)
38+
{
39+
NotNullOrWhiteSpace(key, nameof(key));
40+
NotNull(valueFactory, nameof(valueFactory));
41+
42+
return GetOrAddInternal(key, null, (k, r) => valueFactory(k));
43+
}
44+
45+
/// <inheritdoc />
46+
public CacheItem<TCacheValue> GetOrAdd(string key, string region, Func<string, string, CacheItem<TCacheValue>> valueFactory)
47+
{
48+
NotNullOrWhiteSpace(key, nameof(key));
49+
NotNullOrWhiteSpace(region, nameof(region));
50+
NotNull(valueFactory, nameof(valueFactory));
51+
52+
return GetOrAddInternal(key, region, valueFactory);
3453
}
3554

3655
/// <inheritdoc />
@@ -39,7 +58,22 @@ public bool TryGetOrAdd(string key, Func<string, TCacheValue> valueFactory, out
3958
NotNullOrWhiteSpace(key, nameof(key));
4059
NotNull(valueFactory, nameof(valueFactory));
4160

42-
return TryGetOrAddInternal(key, null, (k, r) => valueFactory(k), out value);
61+
if (TryGetOrAddInternal(
62+
key,
63+
null,
64+
(k, r) =>
65+
{
66+
var newValue = valueFactory(k);
67+
return newValue == null ? null : new CacheItem<TCacheValue>(k, newValue);
68+
},
69+
out CacheItem<TCacheValue> item))
70+
{
71+
value = item.Value;
72+
return true;
73+
}
74+
75+
value = default(TCacheValue);
76+
return false;
4377
}
4478

4579
/// <inheritdoc />
@@ -49,31 +83,63 @@ public bool TryGetOrAdd(string key, string region, Func<string, string, TCacheVa
4983
NotNullOrWhiteSpace(region, nameof(region));
5084
NotNull(valueFactory, nameof(valueFactory));
5185

52-
return TryGetOrAddInternal(key, region, (k, r) => valueFactory(k, r), out value);
86+
if (TryGetOrAddInternal(
87+
key,
88+
region,
89+
(k, r) =>
90+
{
91+
var newValue = valueFactory(k, r);
92+
return newValue == null ? null : new CacheItem<TCacheValue>(k, r, newValue);
93+
},
94+
out CacheItem<TCacheValue> item))
95+
{
96+
value = item.Value;
97+
return true;
98+
}
99+
100+
value = default(TCacheValue);
101+
return false;
53102
}
54103

55-
private bool TryGetOrAddInternal(string key, string region, Func<string, string, TCacheValue> valueFactory, out TCacheValue value)
104+
/// <inheritdoc />
105+
public bool TryGetOrAdd(string key, Func<string, CacheItem<TCacheValue>> valueFactory, out CacheItem<TCacheValue> item)
56106
{
57-
value = default(TCacheValue);
107+
NotNullOrWhiteSpace(key, nameof(key));
108+
NotNull(valueFactory, nameof(valueFactory));
109+
110+
return TryGetOrAddInternal(key, null, (k, r) => valueFactory(k), out item);
111+
}
112+
113+
/// <inheritdoc />
114+
public bool TryGetOrAdd(string key, string region, Func<string, string, CacheItem<TCacheValue>> valueFactory, out CacheItem<TCacheValue> item)
115+
{
116+
NotNullOrWhiteSpace(key, nameof(key));
117+
NotNullOrWhiteSpace(region, nameof(region));
118+
NotNull(valueFactory, nameof(valueFactory));
119+
120+
return TryGetOrAddInternal(key, region, valueFactory, out item);
121+
}
122+
123+
private bool TryGetOrAddInternal(string key, string region, Func<string, string, CacheItem<TCacheValue>> valueFactory, out CacheItem<TCacheValue> item)
124+
{
125+
item = default(CacheItem<TCacheValue>);
58126
var tries = 0;
59127
do
60128
{
61129
tries++;
62-
var item = GetCacheItemInternal(key, region);
130+
item = GetCacheItemInternal(key, region);
63131
if (item != null)
64132
{
65-
value = item.Value;
66133
return true;
67134
}
68135

69-
value = valueFactory(key, region);
136+
item = valueFactory(key, region);
70137

71-
if (value == null)
138+
if (item == null)
72139
{
73140
return false;
74141
}
75142

76-
item = string.IsNullOrWhiteSpace(region) ? new CacheItem<TCacheValue>(key, value) : new CacheItem<TCacheValue>(key, region, value);
77143
if (AddInternal(item))
78144
{
79145
return true;
@@ -84,7 +150,7 @@ private bool TryGetOrAddInternal(string key, string region, Func<string, string,
84150
return false;
85151
}
86152

87-
private TCacheValue GetOrAddInternal(string key, string region, Func<string, string, TCacheValue> valueFactory)
153+
private CacheItem<TCacheValue> GetOrAddInternal(string key, string region, Func<string, string, CacheItem<TCacheValue>> valueFactory)
88154
{
89155
var tries = 0;
90156
do
@@ -93,21 +159,20 @@ private TCacheValue GetOrAddInternal(string key, string region, Func<string, str
93159
var item = GetCacheItemInternal(key, region);
94160
if (item != null)
95161
{
96-
return item.Value;
162+
return item;
97163
}
98164

99-
var newValue = valueFactory(key, region);
165+
item = valueFactory(key, region);
100166

101167
// Throw explicit to me more consistent. Otherwise it would throw later eventually...
102-
if (newValue == null)
168+
if (item == null)
103169
{
104-
throw new InvalidOperationException("The value which should be added must not be null.");
170+
throw new InvalidOperationException("The CacheItem which should be added must not be null.");
105171
}
106172

107-
item = string.IsNullOrWhiteSpace(region) ? new CacheItem<TCacheValue>(key, newValue) : new CacheItem<TCacheValue>(key, region, newValue);
108173
if (AddInternal(item))
109174
{
110-
return newValue;
175+
return item;
111176
}
112177
}
113178
while (tries <= Configuration.MaxRetries);

src/CacheManager.Core/ICacheManager.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,31 @@ public interface ICacheManager<TCacheValue> : ICache<TCacheValue>
337337
/// </exception>
338338
TCacheValue GetOrAdd(string key, string region, Func<string, string, TCacheValue> valueFactory);
339339

340+
/// <summary>
341+
/// Returns an existing item or adds the item to the cache if it does not exist.
342+
/// The <paramref name="valueFactory"/> will be evaluated only if the item does not exist.
343+
/// </summary>
344+
/// <param name="key">The cache key.</param>
345+
/// <param name="valueFactory">The method which creates the value which should be added.</param>
346+
/// <returns>Either the added or the existing value.</returns>
347+
/// <exception cref="ArgumentException">
348+
/// If either <paramref name="key"/> or <paramref name="valueFactory"/> is null.
349+
/// </exception>
350+
CacheItem<TCacheValue> GetOrAdd(string key, Func<string, CacheItem<TCacheValue>> valueFactory);
351+
352+
/// <summary>
353+
/// Returns an existing item or adds the item to the cache if it does not exist.
354+
/// The <paramref name="valueFactory"/> will be evaluated only if the item does not exist.
355+
/// </summary>
356+
/// <param name="key">The cache key.</param>
357+
/// <param name="region">The cache region.</param>
358+
/// <param name="valueFactory">The method which creates the value which should be added.</param>
359+
/// <returns>Either the added or the existing value.</returns>
360+
/// <exception cref="ArgumentException">
361+
/// If either <paramref name="key"/> or <paramref name="valueFactory"/> is null.
362+
/// </exception>
363+
CacheItem<TCacheValue> GetOrAdd(string key, string region, Func<string, string, CacheItem<TCacheValue>> valueFactory);
364+
340365
/// <summary>
341366
/// Tries to either retrieve an existing item or add the item to the cache if it does not exist.
342367
/// The <paramref name="valueFactory"/> will be evaluated only if the item does not exist.
@@ -364,6 +389,31 @@ public interface ICacheManager<TCacheValue> : ICache<TCacheValue>
364389
/// </exception>
365390
bool TryGetOrAdd(string key, string region, Func<string, string, TCacheValue> valueFactory, out TCacheValue value);
366391

392+
/// <summary>
393+
/// Tries to either retrieve an existing item or add the item to the cache if it does not exist.
394+
/// </summary>
395+
/// <param name="key">The cache key.</param>
396+
/// <param name="valueFactory">The method which creates the value which should be added.</param>
397+
/// <param name="item">The cache item.</param>
398+
/// <returns><c>True</c> if the operation succeeds, <c>False</c> in case there are too many retries or the <paramref name="valueFactory"/> returns null.</returns>
399+
/// <exception cref="ArgumentException">
400+
/// If either <paramref name="key"/> or <paramref name="valueFactory"/> is null.
401+
/// </exception>
402+
bool TryGetOrAdd(string key, Func<string, CacheItem<TCacheValue>> valueFactory, out CacheItem<TCacheValue> item);
403+
404+
/// <summary>
405+
/// Tries to either retrieve an existing item or add the item to the cache if it does not exist.
406+
/// </summary>
407+
/// <param name="key">The cache key.</param>
408+
/// <param name="region">The cache region.</param>
409+
/// <param name="valueFactory">The method which creates the value which should be added.</param>
410+
/// <param name="item">The cache item.</param>
411+
/// <returns><c>True</c> if the operation succeeds, <c>False</c> in case there are too many retries or the <paramref name="valueFactory"/> returns null.</returns>
412+
/// <exception cref="ArgumentException">
413+
/// If either <paramref name="key"/> or <paramref name="valueFactory"/> is null.
414+
/// </exception>
415+
bool TryGetOrAdd(string key, string region, Func<string, string, CacheItem<TCacheValue>> valueFactory, out CacheItem<TCacheValue> item);
416+
367417
/// <summary>
368418
/// Updates an existing key in the cache.
369419
/// <para>

0 commit comments

Comments
 (0)