/// <summary>
        /// Remove old items or items beyond capacity from LifespanMgr allowing them to be garbage collected
        /// </summary>
        /// <remarks>
        /// Since we do not physically move items when touched we must check items in bag to determine if they should
        /// be deleted or moved. Also items that were removed by setting value to null get removed now.  Rremoving
        /// an item from LifespanMgr allows it to be garbage collected. If removed item is retrieved by index prior
        /// to GC then it will be readded to LifespanMgr.
        /// </remarks>
        private void CleanUp(DateTime now)
        {
            lock (this)
            {
                int        itemsAboveCapacity = Stats.Current - Stats.Capacity;
                AgeBag <T> bag = bags[OldestBagIndex];

                while (AlmostOutOfBags || bag.HasExpired(maxAge, now) ||
                       (itemsAboveCapacity > 0 && bag.HasReachedMinimumAge(minAge, now)))
                {
                    // cache is still too big / old so remove oldest bag
                    Node <T> node = bag.First;
                    bag.First = null;

                    while (node != null)
                    {
                        Node <T> next = node.Next;
                        node.Next = null;
                        if (node.Value != null && node.Bag != null)
                        {
                            if (node.Bag == bag)
                            {
                                // item has not been touched since bag was closed, so remove it from LifespanMgr
                                ++itemsAboveCapacity;
                                node.Remove();
                            }
                            else
                            {
                                // item has been touched and should be moved to correct age bag now
                                node.Next      = node.Bag.First;
                                node.Bag.First = node;
                            }
                        }

                        node = next;
                    }

                    bag = bags[++OldestBagIndex];

                    if (HasProcessedAllBags)
                    {
                        break;
                    }
                }

                OpenBag(++CurrentBagIndex);

                EnsureIndexIsValid();
            }
        }
Exemple #2
0
 private bool BagNeedsCleaning(AgeBag <T> bag, int itemsAboveCapacity, DateTime now)
 {
     return(bag.HasExpired(maxAge, now) || (itemsAboveCapacity > 0 && bag.HasReachedMinimumAge(minAge, now)));
 }