Skip to content

Commit 9336f2b

Browse files
authored
interface provides enumeration (#163)
* icache+asynccache * keys * tests * enumerate scoped * test scoped * test IEnumerable
1 parent 0a53611 commit 9336f2b

14 files changed

+278
-4
lines changed

BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -169,6 +170,52 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
169170
this.cache.TryUpdate(1, new Disposable()).Should().BeTrue();
170171
}
171172

173+
[Fact]
174+
public void WhenItemsAddedKeysContainsTheKeys()
175+
{
176+
cache.Count.Should().Be(0);
177+
cache.AddOrUpdate(1, new Disposable());
178+
cache.AddOrUpdate(2, new Disposable());
179+
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
180+
}
181+
182+
[Fact]
183+
public void WhenItemsAddedGenericEnumerateContainsKvps()
184+
{
185+
var d1 = new Disposable();
186+
var d2 = new Disposable();
187+
188+
cache.Count.Should().Be(0);
189+
cache.AddOrUpdate(1, d1);
190+
cache.AddOrUpdate(2, d2);
191+
cache
192+
.Select(kvp => new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value))
193+
.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
194+
}
195+
196+
[Fact]
197+
public void WhenItemsAddedEnumerateContainsKvps()
198+
{
199+
var d1 = new Disposable();
200+
var d2 = new Disposable();
201+
202+
cache.Count.Should().Be(0);
203+
cache.AddOrUpdate(1, d1);
204+
cache.AddOrUpdate(2, d2);
205+
206+
var enumerable = (IEnumerable)cache;
207+
208+
var list = new List<KeyValuePair<int, Disposable>>();
209+
210+
foreach (var i in enumerable)
211+
{
212+
var kvp = (KeyValuePair<int, Scoped<Disposable>>)i;
213+
list.Add(new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value));
214+
}
215+
216+
list.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
217+
}
218+
172219
protected void OnItemRemoved(object sender, ItemRemovedEventArgs<int, Scoped<Disposable>> e)
173220
{
174221
this.removedItems.Add(e);

BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -169,6 +170,52 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
169170
this.cache.TryUpdate(1, new Disposable()).Should().BeTrue();
170171
}
171172

173+
[Fact]
174+
public void WhenItemsAddedKeysContainsTheKeys()
175+
{
176+
cache.Count.Should().Be(0);
177+
cache.AddOrUpdate(1, new Disposable());
178+
cache.AddOrUpdate(2, new Disposable());
179+
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
180+
}
181+
182+
[Fact]
183+
public void WhenItemsAddedGenericEnumerateContainsKvps()
184+
{
185+
var d1 = new Disposable();
186+
var d2 = new Disposable();
187+
188+
cache.Count.Should().Be(0);
189+
cache.AddOrUpdate(1, d1);
190+
cache.AddOrUpdate(2, d2);
191+
cache
192+
.Select(kvp => new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value))
193+
.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
194+
}
195+
196+
[Fact]
197+
public void WhenItemsAddedEnumerateContainsKvps()
198+
{
199+
var d1 = new Disposable();
200+
var d2 = new Disposable();
201+
202+
cache.Count.Should().Be(0);
203+
cache.AddOrUpdate(1, d1);
204+
cache.AddOrUpdate(2, d2);
205+
206+
var enumerable = (IEnumerable)cache;
207+
208+
var list = new List<KeyValuePair<int, Disposable>>();
209+
210+
foreach (var i in enumerable)
211+
{
212+
var kvp = (KeyValuePair<int, Scoped<Disposable>>)i;
213+
list.Add(new KeyValuePair<int, Disposable>(kvp.Key, kvp.Value.CreateLifetime().Value));
214+
}
215+
216+
list.Should().BeEquivalentTo(new[] { new KeyValuePair<int, Disposable>(1, d1), new KeyValuePair<int, Disposable>(2, d2) });
217+
}
218+
172219
protected void OnItemRemoved(object sender, ItemRemovedEventArgs<int, Scoped<Disposable>> e)
173220
{
174221
this.removedItems.Add(e);

BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryAsyncCacheTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -147,6 +148,35 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
147148
value.Should().Be(2);
148149
}
149150

151+
[Fact]
152+
public void WhenItemsAddedKeysContainsTheKeys()
153+
{
154+
cache.Count.Should().Be(0);
155+
cache.AddOrUpdate(1, 1);
156+
cache.AddOrUpdate(2, 2);
157+
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
158+
}
159+
160+
[Fact]
161+
public void WhenItemsAddedGenericEnumerateContainsKvps()
162+
{
163+
cache.Count.Should().Be(0);
164+
cache.AddOrUpdate(1, 1);
165+
cache.AddOrUpdate(2, 2);
166+
cache.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
167+
}
168+
169+
[Fact]
170+
public void WhenItemsAddedEnumerateContainsKvps()
171+
{
172+
cache.Count.Should().Be(0);
173+
cache.AddOrUpdate(1, 1);
174+
cache.AddOrUpdate(2, 2);
175+
176+
var enumerable = (IEnumerable)cache;
177+
enumerable.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
178+
}
179+
150180
private void OnItemRemoved(object sender, ItemRemovedEventArgs<int, int> e)
151181
{
152182
this.removedItems.Add(e);

BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryCacheTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -147,6 +148,35 @@ public void WhenKeyExistsTryUpdateReturnsTrue()
147148
value.Should().Be(2);
148149
}
149150

151+
[Fact]
152+
public void WhenItemsAddedKeysContainsTheKeys()
153+
{
154+
cache.Count.Should().Be(0);
155+
cache.AddOrUpdate(1, 1);
156+
cache.AddOrUpdate(2, 2);
157+
cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 });
158+
}
159+
160+
[Fact]
161+
public void WhenItemsAddedGenericEnumerateContainsKvps()
162+
{
163+
cache.Count.Should().Be(0);
164+
cache.AddOrUpdate(1, 1);
165+
cache.AddOrUpdate(2, 2);
166+
cache.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
167+
}
168+
169+
[Fact]
170+
public void WhenItemsAddedEnumerateContainsKvps()
171+
{
172+
cache.Count.Should().Be(0);
173+
cache.AddOrUpdate(1, 1);
174+
cache.AddOrUpdate(2, 2);
175+
176+
var enumerable = (IEnumerable)cache;
177+
enumerable.Should().BeEquivalentTo(new[] { new KeyValuePair<int, int>(1, 1), new KeyValuePair<int, int>(2, 2) });
178+
}
179+
150180
private void OnItemRemoved(object sender, ItemRemovedEventArgs<int, int> e)
151181
{
152182
this.removedItems.Add(e);

BitFaster.Caching/IAsyncCache.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace BitFaster.Caching
1111
/// </summary>
1212
/// <typeparam name="K">The type of keys in the cache.</typeparam>
1313
/// <typeparam name="V">The type of values in the cache.</typeparam>
14-
public interface IAsyncCache<K, V>
14+
public interface IAsyncCache<K, V> : IEnumerable<KeyValuePair<K, V>>
1515
{
1616
/// <summary>
1717
/// Gets the total number of items that can be stored in the cache.
@@ -33,6 +33,11 @@ public interface IAsyncCache<K, V>
3333
/// </summary>
3434
ICacheEvents<K, V> Events { get; }
3535

36+
/// <summary>
37+
/// Gets a collection containing the keys in the cache.
38+
/// </summary>
39+
ICollection<K> Keys { get; }
40+
3641
/// <summary>
3742
/// Attempts to get the value associated with the specified key from the cache.
3843
/// </summary>

BitFaster.Caching/ICache.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace BitFaster.Caching
1111
/// </summary>
1212
/// <typeparam name="K">The type of keys in the cache.</typeparam>
1313
/// <typeparam name="V">The type of values in the cache.</typeparam>
14-
public interface ICache<K, V>
14+
public interface ICache<K, V> : IEnumerable<KeyValuePair<K, V>>
1515
{
1616
/// <summary>
1717
/// Gets the total number of items that can be stored in the cache.
@@ -33,6 +33,11 @@ public interface ICache<K, V>
3333
/// </summary>
3434
ICacheEvents<K, V> Events { get; }
3535

36+
/// <summary>
37+
/// Gets a collection containing the keys in the cache.
38+
/// </summary>
39+
ICollection<K> Keys { get; }
40+
3641
/// <summary>
3742
/// Attempts to get the value associated with the specified key from the cache.
3843
/// </summary>

BitFaster.Caching/IScopedAsyncCache.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace BitFaster.Caching
1111
/// </summary>
1212
/// <typeparam name="K">The type of keys in the cache.</typeparam>
1313
/// <typeparam name="V">The type of values in the cache.</typeparam>
14-
public interface IScopedAsyncCache<K, V> where V : IDisposable
14+
public interface IScopedAsyncCache<K, V> : IEnumerable<KeyValuePair<K, Scoped<V>>> where V : IDisposable
1515
{
1616
/// <summary>
1717
/// Gets the total number of items that can be stored in the cache.
@@ -37,6 +37,11 @@ public interface IScopedAsyncCache<K, V> where V : IDisposable
3737
/// </remarks>
3838
ICacheEvents<K, Scoped<V>> Events { get; }
3939

40+
/// <summary>
41+
/// Gets a collection containing the keys in the cache.
42+
/// </summary>
43+
ICollection<K> Keys { get; }
44+
4045
/// <summary>
4146
/// Attempts to create a lifetime for the value associated with the specified key from the cache
4247
/// </summary>

BitFaster.Caching/IScopedCache.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace BitFaster.Caching
1111
/// </summary>
1212
/// <typeparam name="K">The type of keys in the cache.</typeparam>
1313
/// <typeparam name="V">The type of values in the cache.</typeparam>
14-
public interface IScopedCache<K, V> where V : IDisposable
14+
public interface IScopedCache<K, V> : IEnumerable<KeyValuePair<K, Scoped<V>>> where V : IDisposable
1515
{
1616
/// <summary>
1717
/// Gets the total number of items that can be stored in the cache.
@@ -37,6 +37,11 @@ public interface IScopedCache<K, V> where V : IDisposable
3737
/// </remarks>
3838
ICacheEvents<K, Scoped<V>> Events { get; }
3939

40+
/// <summary>
41+
/// Gets a collection containing the keys in the cache.
42+
/// </summary>
43+
ICollection<K> Keys { get; }
44+
4045
/// <summary>
4146
/// Attempts to create a lifetime for the value associated with the specified key from the cache
4247
/// </summary>

BitFaster.Caching/ScopedAsyncCache.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -40,6 +41,9 @@ public ScopedAsyncCache(IAsyncCache<K, Scoped<V>> cache)
4041
///<inheritdoc/>
4142
public ICacheEvents<K, Scoped<V>> Events => this.cache.Events;
4243

44+
///<inheritdoc/>
45+
public ICollection<K> Keys => this.cache.Keys;
46+
4347
///<inheritdoc/>
4448
public void AddOrUpdate(K key, V value)
4549
{
@@ -107,5 +111,18 @@ public bool TryUpdate(K key, V value)
107111
{
108112
return this.cache.TryUpdate(key, new Scoped<V>(value));
109113
}
114+
115+
public IEnumerator<KeyValuePair<K, Scoped<V>>> GetEnumerator()
116+
{
117+
foreach (var kvp in this.cache)
118+
{
119+
yield return kvp;
120+
}
121+
}
122+
123+
IEnumerator IEnumerable.GetEnumerator()
124+
{
125+
return ((ScopedAsyncCache<K, V>)this).GetEnumerator();
126+
}
110127
}
111128
}

BitFaster.Caching/ScopedCache.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -40,6 +41,9 @@ public ScopedCache(ICache<K, Scoped<V>> cache)
4041
///<inheritdoc/>
4142
public ICacheEvents<K, Scoped<V>> Events => this.cache.Events;
4243

44+
///<inheritdoc/>
45+
public ICollection<K> Keys => this.cache.Keys;
46+
4347
///<inheritdoc/>
4448
public void AddOrUpdate(K key, V value)
4549
{
@@ -107,5 +111,18 @@ public bool TryUpdate(K key, V value)
107111
{
108112
return this.cache.TryUpdate(key, new Scoped<V>(value));
109113
}
114+
115+
public IEnumerator<KeyValuePair<K, Scoped<V>>> GetEnumerator()
116+
{
117+
foreach (var kvp in this.cache)
118+
{
119+
yield return kvp;
120+
}
121+
}
122+
123+
IEnumerator IEnumerable.GetEnumerator()
124+
{
125+
return ((ScopedCache<K, V>)this).GetEnumerator();
126+
}
110127
}
111128
}

0 commit comments

Comments
 (0)