Exemple #1
0
        public virtual void CollectGarbage()
        {
            int count = items.Count;

            if (count <= NoGcCount)
            {
                return;
            }

            Exception error        = null;
            int       removedCount = 0;

            try {
                // Filtering
                var newItems = new Dictionary <TKey, GCHandle>();
                foreach (var pair in items)
                {
                    var cached = pair.Value;
                    var item   = cached.Target;
                    if (item != null)
                    {
                        newItems.Add(pair.Key, cached);
                    }
                    else
                    {
                        cached.Free();
                    }
                }
                removedCount = count - newItems.Count;
                // Done
                items = newItems;
                time  = 0;
            }
            catch (Exception e) {
                error = e;
                throw;
            }
            finally {
                // Logging
                if (CoreLog.IsLogged(LogLevel.Debug))
                {
                    CoreLog.Debug("WeakCache.CollectGarbage: removed: {0} from {1}", removedCount, count);
                    if (error != null)
                    {
                        CoreLog.Debug(error, "Caught at WeakCache.CollectGarbage");
                    }
                }
            }
        }
Exemple #2
0
        public virtual void CollectGarbage()
        {
            int       count        = items.Count;
            Exception error        = null;
            int       removedCount = 0;

            try {
                // Filtering
                var newItems = new Dictionary <object, WeakEntry>(new WeakEntryEqualityComparer());;
                foreach (var pair in items)
                {
                    var entry = pair.Value;
                    var value = entry.Value;
                    if (value.Key != null)
                    {
                        newItems.Add(entry, entry);
                    }
                    else
                    {
                        entry.Dispose();
                    }
                }
                removedCount = count - newItems.Count;

                // Done
                items = newItems;
                time  = 0;
            }
            catch (Exception e) {
                error = e;
                throw;
            }
            finally {
                // Logging
                if (CoreLog.IsLogged(LogLevel.Debug))
                {
                    CoreLog.Debug("WeakestCache.CollectGarbage: removed: {0} from {1}", removedCount, count);
                    if (error != null)
                    {
                        CoreLog.Debug(error, "Caught at WeakestCache.CollectGarbage");
                    }
                }
            }
        }
        /// <inheritdoc/>
        public virtual void CollectGarbage()
        {
            int count = items.Count;

            if (count <= capacity)
            {
                return;
            }

            Exception error        = null;
            int       removedCount = 0;
            double    effeciency   = 0;

            try {
                // Preparing arrays for selection
                var times = new int[count];
                var hits  = new int[count];
                int i     = 0;
                foreach (var pair in items)
                {
                    var cached = pair.Value;
                    times[i] = cached.HitTime;
                    hits[i]  = cached.HitCount;
                    i++;
                }

                // Selection
                Func <int, int, int> reversedIntComparer = (l, r) => r - l;
                int minTime = times.Select(reversedIntComparer, lruCapacity);
                int minHits = hits.Select(reversedIntComparer, mfuCapacity);

                // Filtering
                var newItems = new Dictionary <TKey, CachedItem>();
                foreach (var pair in items)
                {
                    var cached = pair.Value;
                    if (cached.HitTime > minTime || cached.HitCount > minHits)
                    {
                        newItems.Add(pair.Key, new CachedItem(cached.Item));
                    }
                }
                bool done = newItems.Count > capacity;
                foreach (var pair in items)
                {
                    var cached = pair.Value;
                    if (!done && (
                            (cached.HitTime == minTime && cached.HitCount <= minHits) ||
                            (cached.HitCount == minHits && cached.HitTime <= minTime)))
                    {
                        newItems.Add(pair.Key, new CachedItem(cached.Item));
                        if (newItems.Count > capacity)
                        {
                            done = true;
                        }
                    }
                    else if (cached.HitTime > minTime || cached.HitCount > minHits)
                    {
                        // Already added, so doing nothing ...
                    }
                    else
                    {
                        removedCount++;
                        if (chainedCache != null)
                        {
                            chainedCache.Add(cached.Item, true);
                        }
                        ItemRemoved(pair.Key);
                    }
                }

                // Updating timeShift
                if (efficiencyFactor < 0)
                {
                    timeShift = -efficiencyFactor; // Constant timeShift is defined
                }
                else
                {
                    // Relative effeciency factor is defined
                    if (removedCount < 1)
                    {
                        removedCount = 1;
                    }
                    effeciency =
                        ((double)GcOperationCost * removedCount + time) /
                        ((double)GcOperationCost * count + time);
                    timeShift  = ((int)Math.Ceiling(Math.Log(1 / effeciency, 2)));
                    timeShift += efficiencyFactor;
                    if (timeShift > 7)
                    {
                        timeShift = 7;
                    }
                    if (timeShift < 1)
                    {
                        timeShift = 1;
                    }
                }

                // Done
                items = newItems;
                time  = 0;
            }
            catch (Exception e) {
                error = e;
                throw;
            }
            finally {
                // Logging
                if (CoreLog.IsLogged(LogLevel.Debug))
                {
                    CoreLog.Debug("MfLruCache.CollectGarbage: removed: {0} from {1}, efficiency: {2}, time shift: {3}",
                                  removedCount, count, effeciency, timeShift);
                    if (error != null)
                    {
                        CoreLog.Debug(error, "Caught at MfLruCache.CollectGarbage");
                    }
                }
            }
        }