Skip to content

Commit 63e253e

Browse files
authored
Implement TryUpdate (#61)
* TryUpdate * cleanup
1 parent 53cfbee commit 63e253e

File tree

6 files changed

+81
-3
lines changed

6 files changed

+81
-3
lines changed

BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,5 +257,24 @@ public void WhenKeyDoesNotExistTryRemoveReturnsFalse()
257257

258258
lru.TryRemove(2).Should().BeFalse();
259259
}
260+
261+
[Fact]
262+
public void WhenKeyExistsTryUpdateUpdatesValueAndReturnsTrue()
263+
{
264+
lru.GetOrAdd(1, valueFactory.Create);
265+
266+
lru.TryUpdate(1, "2").Should().BeTrue();
267+
268+
lru.TryGet(1, out var value);
269+
value.Should().Be("2");
270+
}
271+
272+
[Fact]
273+
public void WhenKeyDoesNotExistTryUpdateReturnsFalse()
274+
{
275+
lru.GetOrAdd(1, valueFactory.Create);
276+
277+
lru.TryUpdate(2, "3").Should().BeFalse();
278+
}
260279
}
261280
}

BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,5 +373,24 @@ public void WhenRepeatedlyAddingAndRemovingSameValueLruRemainsInConsistentState(
373373
lru.TryRemove(1);
374374
}
375375
}
376+
377+
[Fact]
378+
public void WhenKeyExistsTryUpdateUpdatesValueAndReturnsTrue()
379+
{
380+
lru.GetOrAdd(1, valueFactory.Create);
381+
382+
lru.TryUpdate(1, "2").Should().BeTrue();
383+
384+
lru.TryGet(1, out var value);
385+
value.Should().Be("2");
386+
}
387+
388+
[Fact]
389+
public void WhenKeyDoesNotExistTryUpdateReturnsFalse()
390+
{
391+
lru.GetOrAdd(1, valueFactory.Create);
392+
393+
lru.TryUpdate(2, "3").Should().BeFalse();
394+
}
376395
}
377396
}

BitFaster.Caching/ICache.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,18 @@ public interface ICache<K, V>
4141
Task<V> GetOrAddAsync(K key, Func<K, Task<V>> valueFactory);
4242

4343
/// <summary>
44-
/// Attempts to remove and return the value that has the specified key from the cache.
44+
/// Attempts to remove the value that has the specified key.
4545
/// </summary>
4646
/// <param name="key">The key of the element to remove.</param>
4747
/// <returns>true if the object was removed successfully; otherwise, false.</returns>
4848
bool TryRemove(K key);
49+
50+
/// <summary>
51+
/// Attempts to update the value that has the specified key.
52+
/// </summary>
53+
/// <param name="key">The key of the element to update.</param>
54+
/// <param name="value">The new value.</param>
55+
/// <returns>true if the object was updated successfully; otherwise, false.</returns>
56+
bool TryUpdate(K key, V value);
4957
}
5058
}

BitFaster.Caching/Lru/ClassicLru.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,19 @@ public bool TryRemove(K key)
193193
return false;
194194
}
195195

196+
///<inheritdoc/>
197+
///<remarks>Note: Calling this method does not affect LRU order.</remarks>
198+
public bool TryUpdate(K key, V value)
199+
{
200+
if (this.dictionary.TryGetValue(key, out var node))
201+
{
202+
node.Value.Value = value;
203+
return true;
204+
}
205+
206+
return false;
207+
}
208+
196209
// Thead A reads x from the dictionary. Thread B adds a new item. Thread A moves x to the end. Thread B now removes the new first Node (removal is atomic on both data structures).
197210
private void LockAndMoveToEnd(LinkedListNode<LruItem> node)
198211
{
@@ -226,7 +239,7 @@ public LruItem(K k, V v)
226239

227240
public K Key { get; }
228241

229-
public V Value { get; }
242+
public V Value { get; set; }
230243
}
231244
}
232245
}

BitFaster.Caching/Lru/LruItem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public LruItem(K k, V v)
1919

2020
public readonly K Key;
2121

22-
public readonly V Value;
22+
public V Value { get; set; }
2323

2424
public bool WasAccessed
2525
{

BitFaster.Caching/Lru/TemplateConcurrentLru.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,25 @@ public bool TryRemove(K key)
223223
return false;
224224
}
225225

226+
///<inheritdoc/>
227+
///<remarks>Note: Calling this method does not affect LRU order.</remarks>
228+
public bool TryUpdate(K key, V value)
229+
{
230+
if (this.dictionary.TryGetValue(key, out var existing))
231+
{
232+
lock (existing)
233+
{
234+
if (!existing.WasRemoved)
235+
{
236+
existing.Value = value;
237+
return true;
238+
}
239+
}
240+
}
241+
242+
return false;
243+
}
244+
226245
private void Cycle()
227246
{
228247
// There will be races when queue count == queue capacity. Two threads may each dequeue items.

0 commit comments

Comments
 (0)