示例#1
0
        /// <summary>
        /// Caches some object <paramref name="Item"/>.
        /// </summary>
        /// <param name="HonestItemSizeInBytes">The size of <paramref name="Item"/> in bytes.</param>
        /// <param name="Item">Object which should be cached.</param>
        /// <returns>
        /// A reference code for later access to the object <paramref name="Item"/>.
        /// </returns>
        public static ulong CacheItem(object Item, int HonestItemSizeInBytes)
        {
            RefCounter++;

            Debug.Assert((!(Item is MultidimensionalArray)) || (((MultidimensionalArray)Item).Length * sizeof(double) == HonestItemSizeInBytes));

            CacheBank cb = new CacheBank()
            {
                Item      = Item,
                MemSize   = HonestItemSizeInBytes,
                UseCount  = 1,
                Reference = RefCounter
            };

            while (CurrentSize + cb.MemSize > MaxMem)
            {
                if (!RemoveAtTail())
                {
                    break;
                }
            }

            int iBank = Insert(cb);

            Debug.Assert(object.ReferenceEquals(Banks[iBank], cb));
            Debug.Assert(cb.iBank == iBank);

            ulong R = ((ulong)iBank);

            R |= (((ulong)cb.Reference) << 32);
            return(R);
        }
示例#2
0
        /// <summary>
        /// Returns true if the item stored under reference <paramref name="Reference"/> is still present in the cache, false otherwise.
        /// In contrast to <see cref="GetItem"/>, this is cheaper and does not affect cache statistics.
        /// </summary>
        public static bool IsAlive(ulong Reference)
        {
            int iBank = (int)(Reference & 0x00000000FFFFFFFF);
            int iref  = (int)((Reference & 0xFFFFFFFF00000000) >> 32);

            CacheBank cb = Banks[iBank];

            return(cb != null && iref == cb.Reference);
        }
示例#3
0
        static CacheBank Head; // dummy 'bank', marking the tail of the cache-ranking list (last object to discard)

        static void Remove(int iBank)
        {
            CacheBank toRemove = Banks[iBank];

            Debug.Assert(toRemove.iBank == iBank);
            Banks[iBank]       = null;
            toRemove.prev.next = toRemove.next;
            toRemove.next.prev = toRemove.prev;
            CurrentSize        = CurrentSize - toRemove.MemSize;
            emptyBanks.Add(iBank);
            m_NoOfUsedBanks--;
            Debug.Assert(m_NoOfUsedBanks >= 0);
        }
示例#4
0
        /// <summary>
        /// Removes some cached item from the cache.
        /// </summary>
        public static void ForgetItem(ulong Reference)
        {
            int iBank = (int)(Reference & 0x00000000FFFFFFFF);
            int iref  = (int)((Reference & 0xFFFFFFFF00000000) >> 32);

            CacheBank cb = Banks[iBank];

            if ((cb != null && iref == cb.Reference))
            {
                // object is still in cache, so there is something to forget.
                Remove(iBank);
            }
        }
示例#5
0
        static int Insert(CacheBank cb)
        {
            if (emptyBanks.Count > 0)
            {
                cb.iBank = emptyBanks[emptyBanks.Count - 1];
                emptyBanks.RemoveAt(emptyBanks.Count - 1);
                Debug.Assert(Banks[cb.iBank] == null);
                Banks[cb.iBank] = cb;
            }
            else
            {
                cb.iBank = Banks.Count;
                Banks.Add(cb);
            }
            m_NoOfUsedBanks++;
            CurrentSize += cb.MemSize;// update the bank ranking:
            switch (Strategy)
            {
            case CacheStrategy.DiscardLeastRecentyUsed:
                // insert at head
                cb.next        = Head.next;
                cb.prev        = Head;
                Head.next.prev = cb;
                Head.next      = cb;

                break;

            case CacheStrategy.DiscardLeastFrequentlyUsed:
                // insert at tail
                cb.next        = Tail;
                cb.prev        = Tail.prev;
                Tail.prev.next = cb;
                Tail.prev      = cb;

                // bubble up until the sorting is ok.
                BubbleUp(cb);

                break;

            default:
                throw new NotImplementedException();
            }

            Debug.Assert(Banks[cb.iBank].iBank == cb.iBank);
            return(cb.iBank);
        }
示例#6
0
        static void ResetCache()
        {
            Tail = new CacheBank()
            {
                iBank = int.MinValue
            };
            Head = new CacheBank()
            {
                iBank = int.MinValue
            };

            Tail.prev = Head;
            Head.next = Tail;

            emptyBanks      = new List <int>();
            Banks           = new List <CacheBank>();
            CurrentSize     = 0;
            m_NoOfUsedBanks = 0;
        }
示例#7
0
        private static void BubbleUp(CacheBank a)
        {
            while (
                (!object.ReferenceEquals(a.prev, Head)) && // reached top of ranking
                (a.UseCount >= a.prev.UseCount))        // >= prefers least-recently used in case of doubt
            {
                CacheBank p  = a.prev;
                CacheBank pp = p.prev;
                CacheBank n  = a.next;

                pp.next = a;
                a.next  = p;
                p.next  = n;

                a.prev = pp;
                p.prev = a;
                n.prev = p;
            }
        }
示例#8
0
        static CacheBank Access(int iBank)
        {
            CacheBank a = Banks[iBank];

            if (a == null)
            {
                return(a);
            }

            a.UseCount++;

            // update the bank ranking:
            switch (Strategy)
            {
            case CacheStrategy.DiscardLeastRecentyUsed:
                //

                // remove 'a', where-ever it is...
                a.prev.next = a.next;
                a.next.prev = a.prev;

                // ... and put it on top:
                a.next         = Head.next;
                a.prev         = Head;
                Head.next.prev = a;
                Head.next      = a;

                break;

            case CacheStrategy.DiscardLeastFrequentlyUsed:
                //

                // bubble up until the sorting is ok.
                BubbleUp(a);

                break;

            default:
                throw new NotImplementedException();
            }

            return(a);
        }
示例#9
0
        /// <summary>
        /// Returns the item stored under reference <paramref name="Reference"/>
        /// -- or --
        /// null, if the object has been removed from the cache.
        /// </summary>
        public static object GetItem(ulong Reference)
        {
            int iBank = (int)(Reference & 0x00000000FFFFFFFF);
            int iref  = (int)((Reference & 0xFFFFFFFF00000000) >> 32);

            CacheBank cb = Banks[iBank];

            if (cb != null && iref == cb.Reference)
            {
                Access(iBank);
                Hits++;
                return(cb.Item);
            }
            else
            {
                Misses++;
                return(null);
            }
        }