88using System . Threading ;
99using System . Threading . Tasks ;
1010using Microsoft . Extensions . Internal ;
11+ using Microsoft . Extensions . Logging ;
12+ using Microsoft . Extensions . Logging . Abstractions ;
1113using Microsoft . Extensions . Options ;
1214
1315namespace Microsoft . Extensions . Caching . Memory
@@ -21,6 +23,7 @@ public class MemoryCache : IMemoryCache
2123 private readonly ConcurrentDictionary < object , CacheEntry > _entries ;
2224 private long _cacheSize = 0 ;
2325 private bool _disposed ;
26+ private ILogger _logger ;
2427
2528 // We store the delegates locally to prevent allocations
2629 // every time a new CacheEntry is created.
@@ -35,13 +38,27 @@ public class MemoryCache : IMemoryCache
3538 /// </summary>
3639 /// <param name="optionsAccessor">The options of the cache.</param>
3740 public MemoryCache ( IOptions < MemoryCacheOptions > optionsAccessor )
41+ : this ( optionsAccessor , NullLoggerFactory . Instance ) { }
42+
43+ /// <summary>
44+ /// Creates a new <see cref="MemoryCache"/> instance.
45+ /// </summary>
46+ /// <param name="optionsAccessor">The options of the cache.</param>
47+ /// <param name="loggerFactory"></param>
48+ public MemoryCache ( IOptions < MemoryCacheOptions > optionsAccessor , ILoggerFactory loggerFactory )
3849 {
3950 if ( optionsAccessor == null )
4051 {
4152 throw new ArgumentNullException ( nameof ( optionsAccessor ) ) ;
4253 }
4354
55+ if ( loggerFactory == null )
56+ {
57+ throw new ArgumentNullException ( nameof ( loggerFactory ) ) ;
58+ }
59+
4460 _options = optionsAccessor . Value ;
61+ _logger = loggerFactory . CreateLogger < MemoryCache > ( ) ;
4562
4663 _entries = new ConcurrentDictionary < object , CacheEntry > ( ) ;
4764 _setEntry = SetEntry ;
@@ -341,18 +358,25 @@ private bool UpdateCacheSizeExceedsCapacity(CacheEntry entry)
341358
342359 private void TriggerOvercapacityCompaction ( )
343360 {
361+ _logger . LogDebug ( "Overcapacity compaction triggered" ) ;
362+
344363 // Spawn background thread for compaction
345364 ThreadPool . QueueUserWorkItem ( s => OvercapacityCompaction ( ( MemoryCache ) s ) , this ) ;
346365 }
347366
348367 private static void OvercapacityCompaction ( MemoryCache cache )
349368 {
350369 var currentSize = Interlocked . Read ( ref cache . _cacheSize ) ;
370+
371+ cache . _logger . LogDebug ( $ "Overcapacity compaction executing. Current size { currentSize } ") ;
372+
351373 var lowWatermark = cache . _options . SizeLimit * ( 1 - cache . _options . CompactionPercentage ) ;
352374 if ( currentSize > lowWatermark )
353375 {
354376 cache . Compact ( currentSize - ( long ) lowWatermark , entry => entry . Size . Value ) ;
355377 }
378+
379+ cache . _logger . LogDebug ( $ "Overcapacity compaction executed. New size { Interlocked . Read ( ref cache . _cacheSize ) } ") ;
356380 }
357381
358382 /// Remove at least the given percentage (0.10 for 10%) of the total entries (or estimated memory?), according to the following policy:
@@ -481,4 +505,4 @@ private static void ValidateCacheKey(object key)
481505 }
482506 }
483507 }
484- }
508+ }
0 commit comments