/// <summary> /// Creates a memoization cache factory for memoization caches that use an LRU cache eviction strategy. /// </summary> /// <param name="maxCapacity">The maximum capacity of memoization caches returned by the factory.</param> /// <returns>Memoization cache factory for memoization caches that use an LRU cache eviction strategy.</returns> public static IMemoizationCacheFactory CreateLru(int maxCapacity) { if (maxCapacity < 1) { throw new ArgumentOutOfRangeException(nameof(maxCapacity), "A cache should have at a capacity of at least one."); } // // NB: For now, we use the Synchronized sledgehammer to achieve the concurrency safety. There may be // cheaper ways by creating a custom implementation but we'll postpone this until later. // return(MemoizationCacheFactory.CreateLru(maxCapacity).Synchronized()); }
/// <summary> /// Creates a memoization cache factory for memoization caches that use an eviction strategy based on a function to rank cache entries based on metrics. /// Entries that meet the age threshold and have the highest score as computed by the ranker get evicted. /// </summary> /// <typeparam name="TMetric">Type of the metric to rank cache entries by.</typeparam> /// <param name="ranker">The ranker function used to obtain the metric for each entry upon evicting entries from the cache.</param> /// <param name="maxCapacity">The maximum capacity of memoization caches returned by the factory.</param> /// <param name="ageThreshold">The threshold used to decide whether an entry has aged sufficiently in order to be considered for eviction. E.g. a value of 0.9 means that the youngest 10% of entries cannot get evicted.</param> /// <param name="stopwatchFactory">The stopwatch factory used to create stopwatches that measure access times and function invocation times. If omitted, the default stopwatch is used.</param> /// <returns>Memoization cache factory for memoization caches that use a ranking-based cache eviction strategy.</returns> public static IMemoizationCacheFactory CreateEvictedByHighest <TMetric>(Func <IMemoizationCacheEntryMetrics, TMetric> ranker, int maxCapacity, double ageThreshold = 0.9, IStopwatchFactory stopwatchFactory = null) { if (ranker == null) { throw new ArgumentNullException(nameof(ranker)); } if (maxCapacity < 1) { throw new ArgumentOutOfRangeException(nameof(maxCapacity), "A cache should have at a capacity of at least one."); } if (ageThreshold is <= 0 or > 1) { throw new ArgumentOutOfRangeException(nameof(ageThreshold), "The age threshold should be a number between 0 (inclusive) and 1 (exclusive)."); } // // NB: For now, we use the Synchronized sledgehammer to achieve the concurrency safety. There may be // cheaper ways by creating a custom implementation but we'll postpone this until later. // return(MemoizationCacheFactory.CreateEvictedByHighest(ranker, maxCapacity, ageThreshold, stopwatchFactory).Synchronized()); }