From 9ffc96a1a8471c8eb76442327f04846bbdb9de23 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 17 Jul 2022 14:20:42 -0700 Subject: [PATCH 1/6] metrics --- BitFaster.Caching/ICache.cs | 2 ++ BitFaster.Caching/ICacheMetrics.cs | 23 +++++++++++++++++++ BitFaster.Caching/IScopedCache.cs | 5 ++++ BitFaster.Caching/Lru/ClassicLru.cs | 22 ++++++++++++++---- BitFaster.Caching/Lru/ITelemetryPolicy.cs | 4 ++-- BitFaster.Caching/Lru/NoTelemetryPolicy.cs | 2 ++ .../Lru/TemplateConcurrentLru.cs | 2 ++ BitFaster.Caching/ScopedCache.cs | 2 ++ 8 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 BitFaster.Caching/ICacheMetrics.cs diff --git a/BitFaster.Caching/ICache.cs b/BitFaster.Caching/ICache.cs index 87d307f5..8aa54d4e 100644 --- a/BitFaster.Caching/ICache.cs +++ b/BitFaster.Caching/ICache.cs @@ -23,6 +23,8 @@ public interface ICache /// int Count { get; } + ICacheMetrics Metrics { get; } + /// /// Attempts to get the value associated with the specified key from the cache. /// diff --git a/BitFaster.Caching/ICacheMetrics.cs b/BitFaster.Caching/ICacheMetrics.cs new file mode 100644 index 00000000..e2cdb84c --- /dev/null +++ b/BitFaster.Caching/ICacheMetrics.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BitFaster.Caching +{ + public interface ICacheMetrics + { + /// + /// Gets the ratio of hits to misses, where a value of 1 indicates 100% hits. + /// + double HitRatio { get; } + + /// + /// Gets the total number of requests made to the cache. + /// + long Total { get; } + + //bool IsEnabled { get; } + } +} diff --git a/BitFaster.Caching/IScopedCache.cs b/BitFaster.Caching/IScopedCache.cs index 5ae4ae63..e66bc92b 100644 --- a/BitFaster.Caching/IScopedCache.cs +++ b/BitFaster.Caching/IScopedCache.cs @@ -23,6 +23,11 @@ public interface IScopedCache where V : IDisposable /// int Count { get; } + /// + /// Gets the cache metrics. + /// + ICacheMetrics Metrics { get; } + /// /// Attempts to create a lifetime for the value associated with the specified key from the cache /// diff --git a/BitFaster.Caching/Lru/ClassicLru.cs b/BitFaster.Caching/Lru/ClassicLru.cs index afda93b1..fd8c5350 100644 --- a/BitFaster.Caching/Lru/ClassicLru.cs +++ b/BitFaster.Caching/Lru/ClassicLru.cs @@ -24,8 +24,7 @@ public sealed class ClassicLru : ICache, IEnumerable> dictionary; private readonly LinkedList linkedList = new LinkedList(); - private long requestHitCount; - private long requestTotalCount; + private readonly CacheMetrics metrics = new CacheMetrics(); public ClassicLru(int capacity) : this(Defaults.ConcurrencyLevel, capacity, EqualityComparer.Default) @@ -57,7 +56,10 @@ public ClassicLru(int concurrencyLevel, int capacity, IEqualityComparer compa /// /// Gets the ratio of hits to misses, where a value of 1 indicates 100% hits. /// - public double HitRatio => (double)requestHitCount / (double)requestTotalCount; + public double HitRatio => this.Metrics.HitRatio; + + /// + public ICacheMetrics Metrics => this.Metrics; /// /// Gets a collection containing the keys in the cache. @@ -83,12 +85,12 @@ public IEnumerator> GetEnumerator() /// public bool TryGet(K key, out V value) { - Interlocked.Increment(ref requestTotalCount); + Interlocked.Increment(ref this.metrics.requestTotalCount); if (dictionary.TryGetValue(key, out var node)) { LockAndMoveToEnd(node); - Interlocked.Increment(ref requestHitCount); + Interlocked.Increment(ref this.metrics.requestHitCount); value = node.Value.Value; return true; } @@ -366,5 +368,15 @@ public LruItem(K k, V v) public V Value { get; set; } } + + private class CacheMetrics : ICacheMetrics + { + public long requestHitCount; + public long requestTotalCount; + + public double HitRatio => (double)requestHitCount / (double)requestTotalCount; + + public long Total => requestTotalCount; + } } } diff --git a/BitFaster.Caching/Lru/ITelemetryPolicy.cs b/BitFaster.Caching/Lru/ITelemetryPolicy.cs index 64246e73..47dfb369 100644 --- a/BitFaster.Caching/Lru/ITelemetryPolicy.cs +++ b/BitFaster.Caching/Lru/ITelemetryPolicy.cs @@ -6,7 +6,7 @@ namespace BitFaster.Caching.Lru { - public interface ITelemetryPolicy + public interface ITelemetryPolicy : ICacheMetrics { void IncrementMiss(); @@ -14,7 +14,7 @@ public interface ITelemetryPolicy void OnItemRemoved(K key, V value, ItemRemovedReason reason); - double HitRatio { get; } + //double HitRatio { get; } void SetEventSource(object source); } diff --git a/BitFaster.Caching/Lru/NoTelemetryPolicy.cs b/BitFaster.Caching/Lru/NoTelemetryPolicy.cs index 2f6b2825..b151508e 100644 --- a/BitFaster.Caching/Lru/NoTelemetryPolicy.cs +++ b/BitFaster.Caching/Lru/NoTelemetryPolicy.cs @@ -11,6 +11,8 @@ public struct NoTelemetryPolicy : ITelemetryPolicy { public double HitRatio => 0.0; + public long Total => 0; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void IncrementMiss() { diff --git a/BitFaster.Caching/Lru/TemplateConcurrentLru.cs b/BitFaster.Caching/Lru/TemplateConcurrentLru.cs index 16024f24..3aece220 100644 --- a/BitFaster.Caching/Lru/TemplateConcurrentLru.cs +++ b/BitFaster.Caching/Lru/TemplateConcurrentLru.cs @@ -91,6 +91,8 @@ public TemplateConcurrentLru( /// public int Capacity => this.capacity.Hot + this.capacity.Warm + this.capacity.Cold; + public ICacheMetrics Metrics => this.telemetryPolicy; + public int HotCount => this.hotCount; public int WarmCount => this.warmCount; diff --git a/BitFaster.Caching/ScopedCache.cs b/BitFaster.Caching/ScopedCache.cs index 4180170e..689e114c 100644 --- a/BitFaster.Caching/ScopedCache.cs +++ b/BitFaster.Caching/ScopedCache.cs @@ -37,6 +37,8 @@ public ScopedCache(ICache> cache) /// public int Count => this.cache.Count; + public ICacheMetrics Metrics => this.cache.Metrics; + /// public void AddOrUpdate(K key, V value) { From 9187fc697a5c41695b61b07f4d3ba7886b21c214 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 17 Jul 2022 14:32:38 -0700 Subject: [PATCH 2/6] docs --- BitFaster.Caching/ICache.cs | 3 +++ BitFaster.Caching/ICacheMetrics.cs | 20 ++++++++++++++++++- BitFaster.Caching/Lru/ClassicLru.cs | 6 ++++++ BitFaster.Caching/Lru/NoTelemetryPolicy.cs | 6 ++++++ BitFaster.Caching/Lru/TelemetryPolicy.cs | 6 ++++++ .../Lru/TemplateConcurrentLru.cs | 1 + BitFaster.Caching/ScopedCache.cs | 1 + 7 files changed, 42 insertions(+), 1 deletion(-) diff --git a/BitFaster.Caching/ICache.cs b/BitFaster.Caching/ICache.cs index 8aa54d4e..7d771a59 100644 --- a/BitFaster.Caching/ICache.cs +++ b/BitFaster.Caching/ICache.cs @@ -23,6 +23,9 @@ public interface ICache /// int Count { get; } + /// + /// Gets the cache metrics. + /// ICacheMetrics Metrics { get; } /// diff --git a/BitFaster.Caching/ICacheMetrics.cs b/BitFaster.Caching/ICacheMetrics.cs index e2cdb84c..e5539a06 100644 --- a/BitFaster.Caching/ICacheMetrics.cs +++ b/BitFaster.Caching/ICacheMetrics.cs @@ -6,6 +6,11 @@ namespace BitFaster.Caching { + /// + /// Represents cache metrics collected over the lifetime of the cache. + /// If metrics are disabled, the IsEnabled property returns false + /// and all other properties return zero. + /// public interface ICacheMetrics { /// @@ -18,6 +23,19 @@ public interface ICacheMetrics /// long Total { get; } - //bool IsEnabled { get; } + /// + /// Gets the total number of cache hits. + /// + long Hits { get; } + + /// + /// Gets the total number of cache misses. + /// + long Misses { get; } + + /// + /// Gets a value indicating whether metrics are enabled. + /// + bool IsEnabled { get; } } } diff --git a/BitFaster.Caching/Lru/ClassicLru.cs b/BitFaster.Caching/Lru/ClassicLru.cs index fd8c5350..a339de93 100644 --- a/BitFaster.Caching/Lru/ClassicLru.cs +++ b/BitFaster.Caching/Lru/ClassicLru.cs @@ -377,6 +377,12 @@ private class CacheMetrics : ICacheMetrics public double HitRatio => (double)requestHitCount / (double)requestTotalCount; public long Total => requestTotalCount; + + public long Hits => requestHitCount; + + public long Misses => requestTotalCount - requestHitCount; + + public bool IsEnabled => true; } } } diff --git a/BitFaster.Caching/Lru/NoTelemetryPolicy.cs b/BitFaster.Caching/Lru/NoTelemetryPolicy.cs index b151508e..e78910d8 100644 --- a/BitFaster.Caching/Lru/NoTelemetryPolicy.cs +++ b/BitFaster.Caching/Lru/NoTelemetryPolicy.cs @@ -13,6 +13,12 @@ public struct NoTelemetryPolicy : ITelemetryPolicy public long Total => 0; + public long Hits => 0; + + public long Misses => 0; + + public bool IsEnabled => false; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void IncrementMiss() { diff --git a/BitFaster.Caching/Lru/TelemetryPolicy.cs b/BitFaster.Caching/Lru/TelemetryPolicy.cs index 17c3c06d..1ef28e29 100644 --- a/BitFaster.Caching/Lru/TelemetryPolicy.cs +++ b/BitFaster.Caching/Lru/TelemetryPolicy.cs @@ -18,6 +18,12 @@ public struct TelemetryPolicy : ITelemetryPolicy public long Total => this.hitCount + this.missCount; + public long Hits => this.hitCount; + + public long Misses => this.missCount; + + public bool IsEnabled => true; + public EventHandler> ItemRemoved; public void IncrementMiss() diff --git a/BitFaster.Caching/Lru/TemplateConcurrentLru.cs b/BitFaster.Caching/Lru/TemplateConcurrentLru.cs index 3aece220..5f7db1b5 100644 --- a/BitFaster.Caching/Lru/TemplateConcurrentLru.cs +++ b/BitFaster.Caching/Lru/TemplateConcurrentLru.cs @@ -91,6 +91,7 @@ public TemplateConcurrentLru( /// public int Capacity => this.capacity.Hot + this.capacity.Warm + this.capacity.Cold; + /// public ICacheMetrics Metrics => this.telemetryPolicy; public int HotCount => this.hotCount; diff --git a/BitFaster.Caching/ScopedCache.cs b/BitFaster.Caching/ScopedCache.cs index 689e114c..b746a0a9 100644 --- a/BitFaster.Caching/ScopedCache.cs +++ b/BitFaster.Caching/ScopedCache.cs @@ -37,6 +37,7 @@ public ScopedCache(ICache> cache) /// public int Count => this.cache.Count; + /// public ICacheMetrics Metrics => this.cache.Metrics; /// From 552d19f20eb9673e669c30504878987d87e38a30 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 17 Jul 2022 14:39:02 -0700 Subject: [PATCH 3/6] mark obsolete --- BitFaster.Caching.HitRateAnalysis/Arc/Analysis.cs | 4 ++-- BitFaster.Caching.HitRateAnalysis/Glimpse/Analysis.cs | 4 ++-- BitFaster.Caching.HitRateAnalysis/Wikibench/Analysis.cs | 4 ++-- BitFaster.Caching.HitRateAnalysis/Zipfian/Runner.cs | 6 +++--- BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs | 2 ++ BitFaster.Caching.UnitTests/Lru/ConcurrentTLruTests.cs | 2 ++ BitFaster.Caching/Lru/ConcurrentLru.cs | 1 + BitFaster.Caching/Lru/ConcurrentTLru.cs | 1 + 8 files changed, 15 insertions(+), 9 deletions(-) diff --git a/BitFaster.Caching.HitRateAnalysis/Arc/Analysis.cs b/BitFaster.Caching.HitRateAnalysis/Arc/Analysis.cs index 4727fbd6..23022a76 100644 --- a/BitFaster.Caching.HitRateAnalysis/Arc/Analysis.cs +++ b/BitFaster.Caching.HitRateAnalysis/Arc/Analysis.cs @@ -24,9 +24,9 @@ public Analysis(int cacheSize) public int CacheSize => concurrentLru.Capacity; - public double ConcurrentLruHitRate => concurrentLru.HitRatio * 100; + public double ConcurrentLruHitRate => concurrentLru.Metrics.HitRatio * 100; - public double ClassicLruHitRate => classicLru.HitRatio * 100; + public double ClassicLruHitRate => classicLru.Metrics.HitRatio * 100; public void TestKey(long key) { diff --git a/BitFaster.Caching.HitRateAnalysis/Glimpse/Analysis.cs b/BitFaster.Caching.HitRateAnalysis/Glimpse/Analysis.cs index e3c8964d..265e6469 100644 --- a/BitFaster.Caching.HitRateAnalysis/Glimpse/Analysis.cs +++ b/BitFaster.Caching.HitRateAnalysis/Glimpse/Analysis.cs @@ -24,9 +24,9 @@ public Analysis(int cacheSize) public int CacheSize => this.concurrentLru.Capacity; - public double ConcurrentLruHitRate => this.concurrentLru.HitRatio * 100; + public double ConcurrentLruHitRate => this.concurrentLru.Metrics.HitRatio * 100; - public double ClassicLruHitRate => this.classicLru.HitRatio * 100; + public double ClassicLruHitRate => this.classicLru.Metrics.HitRatio * 100; public void TestKey(long key) { diff --git a/BitFaster.Caching.HitRateAnalysis/Wikibench/Analysis.cs b/BitFaster.Caching.HitRateAnalysis/Wikibench/Analysis.cs index 65505617..2a6680bd 100644 --- a/BitFaster.Caching.HitRateAnalysis/Wikibench/Analysis.cs +++ b/BitFaster.Caching.HitRateAnalysis/Wikibench/Analysis.cs @@ -24,9 +24,9 @@ public Analysis(int cacheSize) public int CacheSize => this.concurrentLru.Capacity; - public double ConcurrentLruHitRate => this.concurrentLru.HitRatio * 100; + public double ConcurrentLruHitRate => this.concurrentLru.Metrics.HitRatio * 100; - public double ClassicLruHitRate => this.classicLru.HitRatio * 100; + public double ClassicLruHitRate => this.classicLru.Metrics.HitRatio * 100; public void TestUri(Uri uri) { diff --git a/BitFaster.Caching.HitRateAnalysis/Zipfian/Runner.cs b/BitFaster.Caching.HitRateAnalysis/Zipfian/Runner.cs index 44cca7b6..c11cc5ab 100644 --- a/BitFaster.Caching.HitRateAnalysis/Zipfian/Runner.cs +++ b/BitFaster.Caching.HitRateAnalysis/Zipfian/Runner.cs @@ -134,7 +134,7 @@ public static void Run() CacheSizePercent = a.CacheSizePercent * 100.0, Samples = a.Samples, IsScan = false, - HitRatio = concurrentLru.HitRatio * 100.0, + HitRatio = concurrentLru.Metrics.HitRatio * 100.0, Duration = lruSw.Elapsed, }); @@ -146,7 +146,7 @@ public static void Run() CacheSizePercent = a.CacheSizePercent * 100.0, Samples = a.Samples, IsScan = true, - HitRatio = classicLruScan.HitRatio * 100.0, + HitRatio = classicLruScan.Metrics.HitRatio * 100.0, Duration = clruSwScan.Elapsed, }); @@ -158,7 +158,7 @@ public static void Run() CacheSizePercent = a.CacheSizePercent * 100.0, Samples = a.Samples, IsScan = true, - HitRatio = concurrentLruScan.HitRatio * 100.0, + HitRatio = concurrentLruScan.Metrics.HitRatio * 100.0, Duration = lruSwScan.Elapsed, }); } diff --git a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs index acdaa0e3..8b4b3eb5 100644 --- a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs @@ -184,7 +184,9 @@ public void WhenItemIsAddedThenRetrievedHitRatioIsHalf() lru.GetOrAdd(1, valueFactory.Create); bool result = lru.TryGet(1, out var value); +#pragma warning disable CS0618 // Type or member is obsolete lru.HitRatio.Should().Be(0.5); +#pragma warning restore CS0618 // Type or member is obsolete } [Fact] diff --git a/BitFaster.Caching.UnitTests/Lru/ConcurrentTLruTests.cs b/BitFaster.Caching.UnitTests/Lru/ConcurrentTLruTests.cs index 258de271..ce1df5f5 100644 --- a/BitFaster.Caching.UnitTests/Lru/ConcurrentTLruTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ConcurrentTLruTests.cs @@ -130,7 +130,9 @@ public void WhenItemIsAddedThenRetrievedHitRatioIsHalf() lru.GetOrAdd(1, valueFactory.Create); bool result = lru.TryGet(1, out var value); +#pragma warning disable CS0618 // Type or member is obsolete lru.HitRatio.Should().Be(0.5); +#pragma warning restore CS0618 // Type or member is obsolete } [Fact] diff --git a/BitFaster.Caching/Lru/ConcurrentLru.cs b/BitFaster.Caching/Lru/ConcurrentLru.cs index 954f81fd..2a0d4964 100644 --- a/BitFaster.Caching/Lru/ConcurrentLru.cs +++ b/BitFaster.Caching/Lru/ConcurrentLru.cs @@ -46,6 +46,7 @@ public ConcurrentLru(int concurrencyLevel, ICapacityPartition capacity, IEqualit /// /// Gets the ratio of hits to misses, where a value of 1 indicates 100% hits. /// + [ObsoleteAttribute("This property is obsolete. Use Metrics instead.", false)] public double HitRatio => this.telemetryPolicy.HitRatio; /// diff --git a/BitFaster.Caching/Lru/ConcurrentTLru.cs b/BitFaster.Caching/Lru/ConcurrentTLru.cs index bdbd00ea..e6147ca8 100644 --- a/BitFaster.Caching/Lru/ConcurrentTLru.cs +++ b/BitFaster.Caching/Lru/ConcurrentTLru.cs @@ -49,6 +49,7 @@ public ConcurrentTLru(int concurrencyLevel, ICapacityPartition capacity, IEquali /// /// Gets the ratio of hits to misses, where a value of 1 indicates 100% hits. /// + [ObsoleteAttribute("This property is obsolete. Use Metrics instead.", false)] public double HitRatio => this.telemetryPolicy.HitRatio; /// From ca68740176de37bd9c95a17576563c0763347da2 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 17 Jul 2022 14:50:46 -0700 Subject: [PATCH 4/6] stack overflow --- BitFaster.Caching/Lru/ClassicLru.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BitFaster.Caching/Lru/ClassicLru.cs b/BitFaster.Caching/Lru/ClassicLru.cs index a339de93..7c1ea831 100644 --- a/BitFaster.Caching/Lru/ClassicLru.cs +++ b/BitFaster.Caching/Lru/ClassicLru.cs @@ -59,7 +59,7 @@ public ClassicLru(int concurrencyLevel, int capacity, IEqualityComparer compa public double HitRatio => this.Metrics.HitRatio; /// - public ICacheMetrics Metrics => this.Metrics; + public ICacheMetrics Metrics => this.metrics; /// /// Gets a collection containing the keys in the cache. From a9af7dc95596701f335ab25a1db4f22aaabc433d Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 17 Jul 2022 15:11:40 -0700 Subject: [PATCH 5/6] tests --- .../Lru/ClassicLruTests.cs | 44 +++++++++++++++++++ .../Lru/ConcurrentLruTests.cs | 9 ++++ .../Lru/NoTelemetryPolicyTests.cs | 24 ++++++++++ .../Lru/TelemetryPolicyTests.cs | 30 +++++++++++++ .../ScopedCacheTests.cs | 10 +++++ BitFaster.Caching/Lru/ClassicLru.cs | 1 + 6 files changed, 118 insertions(+) diff --git a/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs b/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs index 99d3bb04..2c1036c6 100644 --- a/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs @@ -118,7 +118,51 @@ public void WhenItemIsAddedThenRetrievedHitRatioIsHalf() lru.GetOrAdd(1, valueFactory.Create); bool result = lru.TryGet(1, out var value); +#pragma warning disable CS0618 // Type or member is obsolete lru.HitRatio.Should().Be(0.5); +#pragma warning restore CS0618 // Type or member is obsolete + } + + [Fact] + public void MetricsAreEnabled() + { + lru.Metrics.IsEnabled.Should().BeTrue(); + } + + [Fact] + public void WhenItemIsAddedThenRetrievedMetricHitRatioIsHalf() + { + lru.GetOrAdd(1, valueFactory.Create); + bool result = lru.TryGet(1, out var value); + + lru.Metrics.HitRatio.Should().Be(0.5); + } + + [Fact] + public void WhenItemIsAddedThenRetrievedMetricHitsIs1() + { + lru.GetOrAdd(1, valueFactory.Create); + bool result = lru.TryGet(1, out var value); + + lru.Metrics.Hits.Should().Be(1); + } + + [Fact] + public void WhenItemIsAddedThenRetrievedMetricTotalIs2() + { + lru.GetOrAdd(1, valueFactory.Create); + bool result = lru.TryGet(1, out var value); + + lru.Metrics.Total.Should().Be(2); + } + + [Fact] + public void WhenItemDoesNotExistTryGetIncrementsMiss() + { + lru.GetOrAdd(1, valueFactory.Create); + bool result = lru.TryGet(1, out var value); + + lru.Metrics.Misses.Should().Be(1); } [Fact] diff --git a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs index 8b4b3eb5..c4218365 100644 --- a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs @@ -189,6 +189,15 @@ public void WhenItemIsAddedThenRetrievedHitRatioIsHalf() #pragma warning restore CS0618 // Type or member is obsolete } + [Fact] + public void WhenItemIsAddedThenRetrievedMetricHitRatioIsHalf() + { + lru.GetOrAdd(1, valueFactory.Create); + bool result = lru.TryGet(1, out var value); + + lru.Metrics.HitRatio.Should().Be(0.5); + } + [Fact] public void WhenKeyIsRequestedItIsCreatedAndCached() { diff --git a/BitFaster.Caching.UnitTests/Lru/NoTelemetryPolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/NoTelemetryPolicyTests.cs index 7408e4b1..f937926e 100644 --- a/BitFaster.Caching.UnitTests/Lru/NoTelemetryPolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/NoTelemetryPolicyTests.cs @@ -17,6 +17,30 @@ public void HitRatioIsZero() counter.HitRatio.Should().Be(0); } + [Fact] + public void TotalIsZero() + { + counter.Total.Should().Be(0); + } + + [Fact] + public void HitsIsZero() + { + counter.Hits.Should().Be(0); + } + + [Fact] + public void MissesIsZero() + { + counter.Misses.Should().Be(0); + } + + [Fact] + public void IsEnabledIsFalse() + { + counter.IsEnabled.Should().BeFalse(); + } + [Fact] public void IncrementHitCountIsNoOp() { diff --git a/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs index 007231dc..dbdeb7c7 100644 --- a/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/TelemetryPolicyTests.cs @@ -11,6 +11,36 @@ public class TelemetryPolicyTests { private TelemetryPolicy telemetryPolicy = default; + [Fact] + public void WhenHitTotalIs1() + { + telemetryPolicy.Total.Should().Be(0); + telemetryPolicy.IncrementHit(); + telemetryPolicy.Total.Should().Be(1); + } + + [Fact] + public void WhenHitHitsIs1() + { + telemetryPolicy.Hits.Should().Be(0); + telemetryPolicy.IncrementHit(); + telemetryPolicy.Hits.Should().Be(1); + } + + [Fact] + public void WhenMissMissesIs1() + { + telemetryPolicy.Misses.Should().Be(0); + telemetryPolicy.IncrementMiss(); + telemetryPolicy.Misses.Should().Be(1); + } + + [Fact] + public void IsEnabledIsTrue() + { + telemetryPolicy.IsEnabled.Should().BeTrue(); + } + [Fact] public void WhenHitCountAndTotalCountAreEqualRatioIs1() { diff --git a/BitFaster.Caching.UnitTests/ScopedCacheTests.cs b/BitFaster.Caching.UnitTests/ScopedCacheTests.cs index b6675af7..aa484bea 100644 --- a/BitFaster.Caching.UnitTests/ScopedCacheTests.cs +++ b/BitFaster.Caching.UnitTests/ScopedCacheTests.cs @@ -38,6 +38,16 @@ public void WhenItemIsAddedCountIsCorrect() this.cache.Count.Should().Be(1); } + [Fact] + public void WhenItemIsAddedThenLookedUpMetricsAreCorrect() + { + this.cache.AddOrUpdate(1, new Disposable()); + this.cache.ScopedGetOrAdd(1, k => new Scoped(new Disposable())); + + this.cache.Metrics.Misses.Should().Be(0); + this.cache.Metrics.Hits.Should().Be(1); + } + [Fact] public void WhenKeyDoesNotExistAddOrUpdateAddsNewItem() { diff --git a/BitFaster.Caching/Lru/ClassicLru.cs b/BitFaster.Caching/Lru/ClassicLru.cs index 7c1ea831..199b3cf3 100644 --- a/BitFaster.Caching/Lru/ClassicLru.cs +++ b/BitFaster.Caching/Lru/ClassicLru.cs @@ -56,6 +56,7 @@ public ClassicLru(int concurrencyLevel, int capacity, IEqualityComparer compa /// /// Gets the ratio of hits to misses, where a value of 1 indicates 100% hits. /// + [ObsoleteAttribute("This property is obsolete. Use Metrics instead.", false)] public double HitRatio => this.Metrics.HitRatio; /// From c9abc75711d23967d3569d5d7010cf5b039bd96e Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 17 Jul 2022 15:18:25 -0700 Subject: [PATCH 6/6] cleanup --- BitFaster.Caching/Lru/ITelemetryPolicy.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/BitFaster.Caching/Lru/ITelemetryPolicy.cs b/BitFaster.Caching/Lru/ITelemetryPolicy.cs index 47dfb369..781ab9de 100644 --- a/BitFaster.Caching/Lru/ITelemetryPolicy.cs +++ b/BitFaster.Caching/Lru/ITelemetryPolicy.cs @@ -14,8 +14,6 @@ public interface ITelemetryPolicy : ICacheMetrics void OnItemRemoved(K key, V value, ItemRemovedReason reason); - //double HitRatio { get; } - void SetEventSource(object source); } }