Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -169,6 +170,52 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
this.cache.TryUpdate(1, new Disposable()).Should().BeTrue();
}

[Fact]
public void WhenItemsAddedKeysContainsTheKeys()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, new Disposable());
cache.AddOrUpdate(2, new Disposable());
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
}

[Fact]
public void WhenItemsAddedGenericEnumerateContainsKvps()
{
var d1 = new Disposable();
var d2 = new Disposable();

cache.Count.Should().Be(0);
cache.AddOrUpdate(1, d1);
cache.AddOrUpdate(2, d2);
cache
.Select(kvp => new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value))
.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
}

[Fact]
public void WhenItemsAddedEnumerateContainsKvps()
{
var d1 = new Disposable();
var d2 = new Disposable();

cache.Count.Should().Be(0);
cache.AddOrUpdate(1, d1);
cache.AddOrUpdate(2, d2);

var enumerable = (IEnumerable)cache;

var list = new List<KeyValuePair<int, Disposable>>();

foreach (var i in enumerable)
{
var kvp = (KeyValuePair<int, Scoped<Disposable>>)i;
list.Add(new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value));
}

list.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
}

protected void OnItemRemoved(object sender, ItemRemovedEventArgs<int, Scoped<Disposable>> e)
{
this.removedItems.Add(e);
Expand Down
47 changes: 47 additions & 0 deletions BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -169,6 +170,52 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
this.cache.TryUpdate(1, new Disposable()).Should().BeTrue();
}

[Fact]
public void WhenItemsAddedKeysContainsTheKeys()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, new Disposable());
cache.AddOrUpdate(2, new Disposable());
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
}

[Fact]
public void WhenItemsAddedGenericEnumerateContainsKvps()
{
var d1 = new Disposable();
var d2 = new Disposable();

cache.Count.Should().Be(0);
cache.AddOrUpdate(1, d1);
cache.AddOrUpdate(2, d2);
cache
.Select(kvp => new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value))
.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
}

[Fact]
public void WhenItemsAddedEnumerateContainsKvps()
{
var d1 = new Disposable();
var d2 = new Disposable();

cache.Count.Should().Be(0);
cache.AddOrUpdate(1, d1);
cache.AddOrUpdate(2, d2);

var enumerable = (IEnumerable)cache;

var list = new List<KeyValuePair<int, Disposable>>();

foreach (var i in enumerable)
{
var kvp = (KeyValuePair<int, Scoped<Disposable>>)i;
list.Add(new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value));
}

list.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
}

protected void OnItemRemoved(object sender, ItemRemovedEventArgs<int, Scoped<Disposable>> e)
{
this.removedItems.Add(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -147,6 +148,35 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
value.Should().Be(2);
}

[Fact]
public void WhenItemsAddedKeysContainsTheKeys()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, 1);
cache.AddOrUpdate(2, 2);
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
}

[Fact]
public void WhenItemsAddedGenericEnumerateContainsKvps()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, 1);
cache.AddOrUpdate(2, 2);
cache.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
}

[Fact]
public void WhenItemsAddedEnumerateContainsKvps()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, 1);
cache.AddOrUpdate(2, 2);

var enumerable = (IEnumerable)cache;
enumerable.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
}

private void OnItemRemoved(object sender, ItemRemovedEventArgs<int, int> e)
{
this.removedItems.Add(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -147,6 +148,35 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
value.Should().Be(2);
}

[Fact]
public void WhenItemsAddedKeysContainsTheKeys()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, 1);
cache.AddOrUpdate(2, 2);
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
}

[Fact]
public void WhenItemsAddedGenericEnumerateContainsKvps()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, 1);
cache.AddOrUpdate(2, 2);
cache.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
}

[Fact]
public void WhenItemsAddedEnumerateContainsKvps()
{
cache.Count.Should().Be(0);
cache.AddOrUpdate(1, 1);
cache.AddOrUpdate(2, 2);

var enumerable = (IEnumerable)cache;
enumerable.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
}

private void OnItemRemoved(object sender, ItemRemovedEventArgs<int, int> e)
{
this.removedItems.Add(e);
Expand Down
7 changes: 6 additions & 1 deletion BitFaster.Caching/IAsyncCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace BitFaster.Caching
/// </summary>
/// <typeparam name="K">The type of keys in the cache.</typeparam>
/// <typeparam name="V">The type of values in the cache.</typeparam>
public interface IAsyncCache<K, V>
public interface IAsyncCache<K, V> : IEnumerable<KeyValuePair<K, V>>
{
/// <summary>
/// Gets the total number of items that can be stored in the cache.
Expand All @@ -33,6 +33,11 @@ public interface IAsyncCache<K, V>
/// </summary>
ICacheEvents<K, V> Events { get; }

/// <summary>
/// Gets a collection containing the keys in the cache.
/// </summary>
ICollection<K> Keys { get; }

/// <summary>
/// Attempts to get the value associated with the specified key from the cache.
/// </summary>
Expand Down
7 changes: 6 additions & 1 deletion BitFaster.Caching/ICache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace BitFaster.Caching
/// </summary>
/// <typeparam name="K">The type of keys in the cache.</typeparam>
/// <typeparam name="V">The type of values in the cache.</typeparam>
public interface ICache<K, V>
public interface ICache<K, V> : IEnumerable<KeyValuePair<K, V>>
{
/// <summary>
/// Gets the total number of items that can be stored in the cache.
Expand All @@ -33,6 +33,11 @@ public interface ICache<K, V>
/// </summary>
ICacheEvents<K, V> Events { get; }

/// <summary>
/// Gets a collection containing the keys in the cache.
/// </summary>
ICollection<K> Keys { get; }

/// <summary>
/// Attempts to get the value associated with the specified key from the cache.
/// </summary>
Expand Down
7 changes: 6 additions & 1 deletion BitFaster.Caching/IScopedAsyncCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace BitFaster.Caching
/// </summary>
/// <typeparam name="K">The type of keys in the cache.</typeparam>
/// <typeparam name="V">The type of values in the cache.</typeparam>
public interface IScopedAsyncCache<K, V> where V : IDisposable
public interface IScopedAsyncCache<K, V> : IEnumerable<KeyValuePair<K, Scoped<V>>> where V : IDisposable
{
/// <summary>
/// Gets the total number of items that can be stored in the cache.
Expand All @@ -37,6 +37,11 @@ public interface IScopedAsyncCache<K, V> where V : IDisposable
/// </remarks>
ICacheEvents<K, Scoped<V>> Events { get; }

/// <summary>
/// Gets a collection containing the keys in the cache.
/// </summary>
ICollection<K> Keys { get; }

/// <summary>
/// Attempts to create a lifetime for the value associated with the specified key from the cache
/// </summary>
Expand Down
7 changes: 6 additions & 1 deletion BitFaster.Caching/IScopedCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace BitFaster.Caching
/// </summary>
/// <typeparam name="K">The type of keys in the cache.</typeparam>
/// <typeparam name="V">The type of values in the cache.</typeparam>
public interface IScopedCache<K, V> where V : IDisposable
public interface IScopedCache<K, V> : IEnumerable<KeyValuePair<K, Scoped<V>>> where V : IDisposable
{
/// <summary>
/// Gets the total number of items that can be stored in the cache.
Expand All @@ -37,6 +37,11 @@ public interface IScopedCache<K, V> where V : IDisposable
/// </remarks>
ICacheEvents<K, Scoped<V>> Events { get; }

/// <summary>
/// Gets a collection containing the keys in the cache.
/// </summary>
ICollection<K> Keys { get; }

/// <summary>
/// Attempts to create a lifetime for the value associated with the specified key from the cache
/// </summary>
Expand Down
17 changes: 17 additions & 0 deletions BitFaster.Caching/ScopedAsyncCache.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -40,6 +41,9 @@ public ScopedAsyncCache(IAsyncCache<K, Scoped<V>> cache)
///<inheritdoc/>
public ICacheEvents<K, Scoped<V>> Events => this.cache.Events;

///<inheritdoc/>
public ICollection<K> Keys => this.cache.Keys;

///<inheritdoc/>
public void AddOrUpdate(K key, V value)
{
Expand Down Expand Up @@ -107,5 +111,18 @@ public bool TryUpdate(K key, V value)
{
return this.cache.TryUpdate(key, new Scoped<V>(value));
}

public IEnumerator<KeyValuePair<K, Scoped<V>>> GetEnumerator()
{
foreach (var kvp in this.cache)
{
yield return kvp;
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return ((ScopedAsyncCache<K, V>)this).GetEnumerator();
}
}
}
17 changes: 17 additions & 0 deletions BitFaster.Caching/ScopedCache.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -40,6 +41,9 @@ public ScopedCache(ICache<K, Scoped<V>> cache)
///<inheritdoc/>
public ICacheEvents<K, Scoped<V>> Events => this.cache.Events;

///<inheritdoc/>
public ICollection<K> Keys => this.cache.Keys;

///<inheritdoc/>
public void AddOrUpdate(K key, V value)
{
Expand Down Expand Up @@ -107,5 +111,18 @@ public bool TryUpdate(K key, V value)
{
return this.cache.TryUpdate(key, new Scoped<V>(value));
}

public IEnumerator<KeyValuePair<K, Scoped<V>>> GetEnumerator()
{
foreach (var kvp in this.cache)
{
yield return kvp;
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return ((ScopedCache<K, V>)this).GetEnumerator();
}
}
}
16 changes: 16 additions & 0 deletions BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -30,6 +31,8 @@ public AtomicFactoryAsyncCache(ICache<K, AsyncAtomicFactory<K, V>> cache)

public ICacheEvents<K, V> Events => this.eventProxy;

public ICollection<K> Keys => this.cache.Keys;

public void AddOrUpdate(K key, V value)
{
cache.AddOrUpdate(key, new AsyncAtomicFactory<K, V>(value));
Expand Down Expand Up @@ -76,6 +79,19 @@ public bool TryUpdate(K key, V value)
return cache.TryUpdate(key, new AsyncAtomicFactory<K, V>(value));
}

public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
foreach (var kvp in this.cache)
{
yield return new KeyValuePair<K, V>(kvp.Key, kvp.Value.ValueIfCreated);
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return ((AtomicFactoryAsyncCache<K, V>)this).GetEnumerator();
}

private class EventProxy : CacheEventProxyBase<K, AsyncAtomicFactory<K, V>, V>
{
public EventProxy(ICacheEvents<K, AsyncAtomicFactory<K, V>> inner)
Expand Down
Loading