Beispiel #1
0
                public Cache(Func <T, R> function, Func <IMemoizationCacheEntryMetrics, TMetric> ranker, int maxCapacity, bool descending, double ageThreshold, bool cacheError, IStopwatchFactory stopwatchFactory)
                {
                    _function = args =>
                    {
                        var weakArgs = WeakReferenceExtensions.Create(args);

                        var invokeDuration = default(TimeSpan);
#if DEBUG
                        Interlocked.Increment(ref _invocationCount);
#endif
                        Trim();

                        var res = default(IMetricsCacheEntry <WeakReference <T>, R>);
                        try
                        {
                            var swInvokeStart = _stopwatch.ElapsedTicks;

                            var value = function(args);

                            invokeDuration = new TimeSpan(_stopwatch.ElapsedTicks - swInvokeStart);

                            res = new MetricsValueCacheEntry <WeakReference <T>, R>(weakArgs, value);
                        }
                        catch (Exception ex) when(_cacheError)
                        {
                            res = new MetricsErrorCacheEntry <WeakReference <T>, R>(weakArgs, ex);
                        }

                        res.CreationTime   = new TimeSpan(_stopwatch.ElapsedTicks);
                        res.InvokeDuration = invokeDuration;

                        _lock.EnterWriteLock();
                        try
                        {
                            _entries.Add(res);
                        }
                        finally
                        {
                            _lock.ExitWriteLock();
                        }

                        return(res);
                    };

                    _cache     = new WeakCacheDictionary <T, IMetricsCacheEntry <WeakReference <T>, R> >();
                    _lock      = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
                    _entries   = new HashSet <IMetricsCacheEntry <WeakReference <T>, R> >();
                    _stopwatch = stopwatchFactory.StartNew();

                    //
                    // Exclude newest items which have statically irrelevant data, so they get a chance to become relevant.
                    //
                    var candidates = _entries.OrderBy(e => _stopwatch.ElapsedTicks - e.CreationTime.Ticks).Take(Math.Max(1, (int)(maxCapacity * ageThreshold)));
                    _ranker = descending ? candidates.OrderByDescending(e => ranker(e)) : candidates.OrderBy(e => ranker(e));

                    _maxCapacity = maxCapacity;
                    _cacheError  = cacheError;
                }
Beispiel #2
0
                public Cache(Func <T, R> function, Func <IMemoizationCacheEntryMetrics, TMetric> ranker, int maxCapacity, bool descending, double ageThreshold, IEqualityComparer <T> comparer, bool cacheError, IStopwatchFactory stopwatchFactory)
                {
                    _function = args =>
                    {
                        var invokeDuration = default(TimeSpan);
#if DEBUG
                        _invocationCount++;
#endif
                        Trim();

                        var res = default(IMetricsCacheEntry <T, R>);
                        try
                        {
                            var swInvokeStart = _stopwatch.ElapsedTicks;

                            var value = function(args);

                            invokeDuration = new TimeSpan(_stopwatch.ElapsedTicks - swInvokeStart);

                            res = new MetricsValueCacheEntry <T, R>(args, value);
                        }
                        catch (Exception ex) when(_cacheError)
                        {
                            res = new MetricsErrorCacheEntry <T, R>(args, ex);
                        }

                        res.CreationTime   = new TimeSpan(_stopwatch.ElapsedTicks);
                        res.InvokeDuration = invokeDuration;

                        return(res);
                    };

                    _cache     = new CacheDictionary <T, IMetricsCacheEntry <T, R> >(comparer);
                    _stopwatch = stopwatchFactory.StartNew();

                    //
                    // Exclude newest items which have statically irrelevant data, so they get a chance to become relevant.
                    //
                    var candidates = _cache.Values.OrderBy(e => _stopwatch.ElapsedTicks - e.CreationTime.Ticks).Take(Math.Max(1, (int)(maxCapacity * ageThreshold)));
                    _ranker = descending ? candidates.OrderByDescending(e => ranker(e)) : candidates.OrderBy(e => ranker(e));

                    _maxCapacity = maxCapacity;
                    _cacheError  = cacheError;
                }