private CacheStatsCounter GetCounter(string key) { if (string.IsNullOrWhiteSpace(key)) { throw new ArgumentNullException(key); } CacheStatsCounter counter = null; if (!this.counters.TryGetValue(key, out counter)) { // because of the lazy initialization of region counters, we have to lock at this // point even though the counters dictionary is thread safe the method gets called // so frequently that this is a real performance improvement... lock (this.lockObject) { // check again after pooling threads on the lock if (!this.counters.TryGetValue(key, out counter)) { counter = new CacheStatsCounter(); if (!this.counters.TryAdd(key, counter)) { throw new InvalidOperationException("Failed to initialize counter."); } } } } return(counter); }
/// <summary> /// Initializes a new instance of the <see cref="CacheStats{TCacheValue}"/> class. /// </summary> /// <param name="cacheName">Name of the cache.</param> /// <param name="handleName">Name of the handle.</param> /// <param name="enabled"> /// If set to <c>true</c> the stats are enabled. Otherwise any statistics and performance /// counters will be disabled. /// </param> /// <param name="enablePerformanceCounters"> /// If set to <c>true</c> performance counters and statistics will be enabled. /// </param> /// <exception cref="System.ArgumentNullException"> /// If cacheName or handleName are null. /// </exception> public CacheStats(string cacheName, string handleName, bool enabled = true, bool enablePerformanceCounters = false) { NotNullOrWhiteSpace(cacheName, nameof(cacheName)); NotNullOrWhiteSpace(handleName, nameof(handleName)); // if performance counters are enabled, stats must be enabled, too. _isStatsEnabled = enablePerformanceCounters || enabled; _isPerformanceCounterEnabled = enablePerformanceCounters; _counter = new CacheStatsCounter(); if (_isPerformanceCounterEnabled) { _performanceCounters = new CachePerformanceCounters <TKey, TValue>(cacheName, handleName, this); } }
/// <summary> /// Called when the cache got cleared. /// </summary> public void OnClear() { if (!_isStatsEnabled) { return; } // clear needs a lock, otherwise we might mess up the overall counts foreach (var key in _counters.Keys) { CacheStatsCounter counter = null; if (_counters.TryGetValue(key, out counter)) { counter.Set(CacheStatsCounterType.Items, 0L); counter.Increment(CacheStatsCounterType.ClearCalls); } } }
private CacheStatsCounter GetCounter(string key) { NotNullOrWhiteSpace(key, nameof(key)); CacheStatsCounter counter = null; if (!_counters.TryGetValue(key, out counter)) { counter = new CacheStatsCounter(); if (_counters.TryAdd(key, counter)) { return(counter); } return(GetCounter(key)); } return(counter); }
private CacheStatsCounter GetCounter(string key) { NotNullOrWhiteSpace(key, nameof(key)); CacheStatsCounter counter = null; if (!this.counters.TryGetValue(key, out counter)) { // because of the lazy initialization of region counters, we have to lock at this // point even though the counters dictionary is thread safe the method gets called // so frequently that this is a real performance improvement... lock (this.lockObject) { // check again after pooling threads on the lock if (!this.counters.TryGetValue(key, out counter)) { counter = new CacheStatsCounter(); this.counters.Add(key, counter); } } } return(counter); }