Skip to content

Commit 3796d9d

Browse files
authored
debug (#224)
* debug * test count * lru metrics * scoped
1 parent dfd8ffa commit 3796d9d

25 files changed

+179
-50
lines changed

BitFaster.Caching.UnitTests/Buffers/StripedMpscBufferTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ public void CapacityReturnsCapacity()
2121
buffer.Capacity.Should().Be(32);
2222
}
2323

24+
[Fact]
25+
public void CountReturnsCount()
26+
{
27+
buffer.Count.Should().Be(0);
28+
29+
for (var i = 0; i < stripeCount; i++)
30+
{
31+
for (var j = 0; j < bufferSize; j++)
32+
{
33+
buffer.TryAdd(1.ToString()).Should().Be(BufferStatus.Success);
34+
}
35+
}
36+
37+
buffer.Count.Should().Be(buffer.Capacity);
38+
}
39+
2440
[Fact]
2541
public void WhenBufferIsFullTryAddReturnsFull()
2642
{

BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
4+
using System.Diagnostics;
65
using System.Threading.Tasks;
76

87
namespace BitFaster.Caching.Atomic
98
{
9+
[DebuggerDisplay("Count = {Count}")]
1010
public sealed class AtomicFactoryAsyncCache<K, V> : IAsyncCache<K, V>
1111
{
1212
private readonly ICache<K, AsyncAtomicFactory<K, V>> cache;

BitFaster.Caching/Atomic/AtomicFactoryCache.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
6-
using System.Threading.Tasks;
4+
using System.Diagnostics;
75

86
namespace BitFaster.Caching.Atomic
97
{
8+
[DebuggerDisplay("Count = {Count}")]
109
public sealed class AtomicFactoryCache<K, V> : ICache<K, V>
1110
{
1211
private readonly ICache<K, AtomicFactory<K, V>> cache;

BitFaster.Caching/Atomic/AtomicFactoryScopedAsyncCache.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
4+
using System.Diagnostics;
65
using System.Threading;
76
using System.Threading.Tasks;
87

98
namespace BitFaster.Caching.Atomic
109
{
10+
[DebuggerDisplay("Count = {Count}")]
1111
public sealed class AtomicFactoryScopedAsyncCache<K, V> : IScopedAsyncCache<K, V> where V : IDisposable
1212
{
1313
private readonly ICache<K, ScopedAsyncAtomicFactory<K, V>> cache;

BitFaster.Caching/Atomic/AtomicFactoryScopedCache.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
4+
using System.Diagnostics;
65
using System.Threading;
7-
using System.Threading.Tasks;
86

97
namespace BitFaster.Caching.Atomic
108
{
9+
[DebuggerDisplay("Count = {Count}")]
1110
public sealed class AtomicFactoryScopedCache<K, V> : IScopedCache<K, V> where V : IDisposable
1211
{
1312
private readonly ICache<K, ScopedAtomicFactory<K, V>> cache;

BitFaster.Caching/Atomic/ScopedAsyncAtomicFactory.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
2+
using System.Diagnostics;
53
using System.Threading;
64
using System.Threading.Tasks;
75

86
namespace BitFaster.Caching.Atomic
97
{
8+
[DebuggerDisplay("IsValueCreated={initializer == null}, Value={ScopeIfCreated}")]
109
public sealed class ScopedAsyncAtomicFactory<K, V> : IScoped<V>, IDisposable where V : IDisposable
1110
{
1211
private Scoped<V> scope;

BitFaster.Caching/Atomic/ScopedAtomicFactory.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Diagnostics;
4-
using System.Linq;
5-
using System.Text;
63
using System.Threading;
7-
using System.Threading.Tasks;
84

95
namespace BitFaster.Caching.Atomic
106
{
117
// Requirements:
128
// 1. Exactly once disposal.
139
// 2. Exactly once invocation of value factory (synchronized create).
1410
// 3. Resolve race between create dispose init, if disposed is called before value is created, scoped value is disposed for life.
11+
[DebuggerDisplay("IsValueCreated={initializer == null}, Value={ScopeIfCreated}")]
1512
public sealed class ScopedAtomicFactory<K, V> : IScoped<V>, IDisposable where V : IDisposable
1613
{
1714
private Scoped<V> scope;

BitFaster.Caching/Buffers/MpscBoundedBuffer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Text;
45
using System.Threading;
56
using System.Threading.Tasks;
@@ -14,6 +15,7 @@ namespace BitFaster.Caching.Buffers
1415
/// Based on BoundedBuffer by Ben Manes.
1516
/// https://github.com/ben-manes/caffeine/blob/master/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedBuffer.java
1617
/// </remarks>
18+
[DebuggerDisplay("Count = {Count}/{Capacity}")]
1719
public class MpscBoundedBuffer<T> where T : class
1820
{
1921
private T[] buffer;

BitFaster.Caching/Buffers/StripedMpscBuffer.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
35
using System.Text;
46
using System.Threading;
57

@@ -15,6 +17,7 @@ namespace BitFaster.Caching.Buffers
1517
/// rehashed to select a different buffer to retry up to 3 times. Using this approach
1618
/// writes scale linearly with number of concurrent threads.
1719
/// </summary>
20+
[DebuggerDisplay("Count = {Count}/{Capacity}")]
1821
public class StripedMpscBuffer<T> where T : class
1922
{
2023
const int MaxAttempts = 3;
@@ -32,6 +35,8 @@ public StripedMpscBuffer(int stripeCount, int bufferSize)
3235
}
3336
}
3437

38+
public int Count => buffers.Sum(b => b.Count);
39+
3540
public int Capacity => buffers.Length * buffers[0].Capacity;
3641

3742
public int DrainTo(T[] outputBuffer)

BitFaster.Caching/Lfu/ConcurrentLfu.cs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ namespace BitFaster.Caching.Lfu
3131
/// Based on Caffeine written by Ben Manes.
3232
/// https://www.apache.org/licenses/LICENSE-2.0
3333
/// </remarks>
34+
[DebuggerTypeProxy(typeof(ConcurrentLfu<,>.LfuDebugView))]
35+
[DebuggerDisplay("Count = {Count}/{Capacity}")]
3436
public sealed class ConcurrentLfu<K, V> : ICache<K, V>, IAsyncCache<K, V>, IBoundedPolicy
3537
{
3638
private const int MaxWriteBufferRetries = 100;
@@ -644,7 +646,7 @@ private void ReFitProtected()
644646
}
645647
}
646648

647-
[DebuggerDisplay("{Format()}")]
649+
[DebuggerDisplay("{Format(),nq}")]
648650
private class DrainStatus
649651
{
650652
public const int Idle = 0;
@@ -687,7 +689,7 @@ public int Status()
687689
}
688690

689691
[ExcludeFromCodeCoverage]
690-
private string Format()
692+
internal string Format()
691693
{
692694
switch (this.drainStatus.Value)
693695
{
@@ -705,7 +707,8 @@ private string Format()
705707
}
706708
}
707709

708-
private class CacheMetrics : ICacheMetrics
710+
[DebuggerDisplay("Hit = {Hits}, Miss = {Misses}, Upd = {Updated}, Evict = {Evicted}")]
711+
internal class CacheMetrics : ICacheMetrics
709712
{
710713
public long requestHitCount;
711714
public long requestMissCount;
@@ -741,6 +744,40 @@ public string FormatLruString()
741744
return sb.ToString();
742745
}
743746
#endif
747+
748+
[ExcludeFromCodeCoverage]
749+
internal class LfuDebugView
750+
{
751+
private ConcurrentLfu<K, V> lfu;
752+
753+
public LfuDebugView(ConcurrentLfu<K, V> lfu)
754+
{
755+
this.lfu = lfu;
756+
}
757+
758+
public string Maintenance => lfu.drainStatus.Format();
759+
760+
public ICacheMetrics Metrics => lfu.metrics;
761+
762+
public StripedMpscBuffer<LfuNode<K, V>> ReadBuffer => this.lfu.readBuffer;
763+
764+
public StripedMpscBuffer<LfuNode<K, V>> WriteBuffer => this.lfu.writeBuffer;
765+
766+
public KeyValuePair<K, V>[] Items
767+
{
768+
get
769+
{
770+
var items = new KeyValuePair<K, V>[lfu.Count];
771+
772+
int index = 0;
773+
foreach (var kvp in lfu)
774+
{
775+
items[index++] = kvp;
776+
}
777+
return items;
778+
}
779+
}
780+
}
744781
}
745782

746783
// Explicit layout cannot be a generic class member

0 commit comments

Comments
 (0)