/// <summary>
        /// Resize the cache. If the new size is smaller than the old size, some items will be evicted from the cache.
        /// The eviction will not follow the ideal policy. Instead, the items at the end of the cache (which may or may not be the oldest)
        /// will be evicted.
        /// </summary>
        /// <param name="newCapacity">Capacity of teh cache after resizing.
        /// This size may not be smaller than CandidateSize + RandomSearchSize + 10;</param>
        public void Resize(int newCapacity)
        {
            newCapacity = Max(newCapacity, CandidateSize + RandomSearchSize + 10);
            var newStorage = new PseudoLRUCache <TItem> .CacheItem[newCapacity];
            var newIndex   = newCapacity - 1;

            for (var position = 0; position < Size; position++)
            {
                var oldIndex = PositionToIndex(position);
                if (newIndex >= 0)
                {
                    newStorage[newIndex] = Storage[oldIndex];
                }
                else
                {
                    Storage[oldIndex].Item = null;
                }
                newIndex--;
            }
            Storage     = newStorage;
            Size        = Min(newCapacity, Size);
            AddPosition = newCapacity - 1 - Size;
            if (AddPosition < 0)
            {
                AddPosition = RingCapacity - 1;  // Ring buffer wrap-around
            }
        }
 private CacheItem(PseudoLRUCache <TItem> cache, TItem item)
 {
     Cache      = cache;
     LastAccess = int.MinValue;
     Item       = item;
 }