Пример #1
0
        private void AddUsageEntryToFreeList(UsageEntryRef entryRef)
        {
            Debug.Assert(entryRef.IsRef1, "entryRef.IsRef1");

            UsageEntry[] entries    = (_pages[(entryRef.PageIndex)]._entries);
            int          entryIndex = entryRef.Ref1Index;

            Debug.Assert(entries[entryIndex]._cacheEntry == null, "entries[entryIndex]._cacheEntry == null");
            entries[entryIndex]._utcDate    = DateTime.MinValue;
            entries[entryIndex]._ref1._prev = UsageEntryRef.INVALID;
            entries[entryIndex]._ref2._next = UsageEntryRef.INVALID;
            entries[entryIndex]._ref2._prev = UsageEntryRef.INVALID;

            entries[entryIndex]._ref1._next = ((entries)[0]._ref1._next);
            ((entries)[0]._ref1._next)      = entryRef;

            _cEntriesInUse--;
            int pageIndex = entryRef.PageIndex;

            ((entries)[0]._cFree)++;
            if (((entries)[0]._cFree) == 1)
            {
                AddToListHead(pageIndex, ref _freeEntryList);
            }
            else if (((entries)[0]._cFree) == NUM_ENTRIES)
            {
                RemovePage(pageIndex);
            }
        }
Пример #2
0
        internal void RemoveCacheEntry(MemoryCacheEntry cacheEntry)
        {
            lock (this)
            {
                UsageEntryRef entryRef = cacheEntry.UsageEntryRef;
                if (entryRef.IsInvalid)
                {
                    return;
                }

                UsageEntry[] entries    = (_pages[(entryRef.PageIndex)]._entries);
                int          entryIndex = entryRef.Ref1Index;

                cacheEntry.UsageEntryRef        = UsageEntryRef.INVALID;
                entries[entryIndex]._cacheEntry = null;

                RemoveEntryFromLastRefList(entryRef);

                AddUsageEntryToFreeList(entryRef);

                Reduce();

                Dbg.Trace("CacheUsageRemove",
                          "Removed item=" + cacheEntry.Key +
                          ",_bucket=" + _bucket +
                          ",ref=" + entryRef);
            }
        }
Пример #3
0
        internal MemoryCacheEntry(string key,
                                  object value,
                                  DateTimeOffset absExp,
                                  TimeSpan slidingExp,
                                  CacheItemPriority priority,
                                  Collection <ChangeMonitor> dependencies,
                                  CacheEntryRemovedCallback removedCallback,
                                  MemoryCache cache) : base(key)
        {
            if (value is null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            _utcCreated = DateTime.UtcNow;
            _value      = value;

            _slidingExp = slidingExp;
            if (_slidingExp > TimeSpan.Zero)
            {
                _utcAbsExp = _utcCreated + _slidingExp;
            }
            else
            {
                _utcAbsExp = absExp.UtcDateTime;
            }

            _expiresEntryRef = ExpiresEntryRef.INVALID;
            _expiresBucket   = 0xff;

            _usageEntryRef = UsageEntryRef.INVALID;
            if (priority == CacheItemPriority.NotRemovable)
            {
                _usageBucket = 0xff;
            }
            else
            {
                _usageBucket = 0;
            }

            _callback = removedCallback;

            // CacheItemPolicy.ChangeMonitors is frequently the source for 'dependencies', and that property
            // is never null. So check that the collection of dependencies is not empty before allocating
            // the 'seldom' used fields.
            if (dependencies != null && dependencies.Count > 0)
            {
                _fields = new SeldomUsedFields();
                _fields._dependencies = dependencies;
                _fields._cache        = cache;
            }
        }
Пример #4
0
        internal MemoryCacheEntry(String key,
                                  Object value,
                                  DateTimeOffset absExp,
                                  TimeSpan slidingExp,
                                  CacheItemPriority priority,
                                  Collection <ChangeMonitor> dependencies,
                                  CacheEntryRemovedCallback removedCallback,
                                  MemoryCache cache) : base(key)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            _utcCreated = DateTime.UtcNow;
            _value      = value;

            _slidingExp = slidingExp;
            if (_slidingExp > TimeSpan.Zero)
            {
                _utcAbsExp = _utcCreated + _slidingExp;
            }
            else
            {
                _utcAbsExp = absExp.UtcDateTime;
            }

            _expiresEntryRef = ExpiresEntryRef.INVALID;
            _expiresBucket   = 0xff;

            _usageEntryRef = UsageEntryRef.INVALID;
            if (priority == CacheItemPriority.NotRemovable)
            {
                _usageBucket = 0xff;
            }
            else
            {
                _usageBucket = 0;
            }

            _callback = removedCallback;

            if (dependencies != null)
            {
                _fields = new SeldomUsedFields();
                _fields._dependencies = dependencies;
                _fields._cache        = cache;
            }
        }
 internal void RemoveCacheEntry(MemoryCacheEntry cacheEntry)
 {
     lock (this)
     {
         UsageEntryRef usageEntryRef = cacheEntry.UsageEntryRef;
         if (!usageEntryRef.IsInvalid)
         {
             UsageEntry[] entryArray = this._pages[usageEntryRef.PageIndex]._entries;
             int          index      = usageEntryRef.Ref1Index;
             cacheEntry.UsageEntryRef      = UsageEntryRef.INVALID;
             entryArray[index]._cacheEntry = null;
             this.RemoveEntryFromLastRefList(usageEntryRef);
             this.AddUsageEntryToFreeList(usageEntryRef);
             this.Reduce();
         }
     }
 }
        private void AddUsageEntryToFreeList(UsageEntryRef entryRef)
        {
            UsageEntry[] entryArray = this._pages[entryRef.PageIndex]._entries;
            int          index      = entryRef.Ref1Index;

            entryArray[index]._utcDate    = DateTime.MinValue;
            entryArray[index]._ref1._prev = UsageEntryRef.INVALID;
            entryArray[index]._ref2._next = UsageEntryRef.INVALID;
            entryArray[index]._ref2._prev = UsageEntryRef.INVALID;
            entryArray[index]._ref1._next = entryArray[0]._ref1._next;
            entryArray[0]._ref1._next     = entryRef;
            this._cEntriesInUse--;
            int pageIndex = entryRef.PageIndex;

            entryArray[0]._cFree++;
            if (entryArray[0]._cFree == 1)
            {
                this.AddToListHead(pageIndex, ref this._freeEntryList);
            }
            else if (entryArray[0]._cFree == 0x7f)
            {
                this.RemovePage(pageIndex);
            }
        }
 internal int FlushUnderUsedItems(int maxFlush, bool force)
 {
     UsageEntry[] entryArray;
     int num;
     UsageEntryRef ref6;
     UsageEntryRef ref7;
     if (this._cEntriesInUse == 0)
     {
         return 0;
     }
     UsageEntryRef iNVALID = UsageEntryRef.INVALID;
     int num2 = 0;
     try
     {
         this._cacheUsage.MemoryCacheStore.BlockInsert();
         lock (this)
         {
             UsageEntryRef ref4;
             if (this._cEntriesInUse == 0)
             {
                 return 0;
             }
             DateTime utcNow = DateTime.UtcNow;
             for (UsageEntryRef ref3 = this._lastRefTail; (this._cEntriesInFlush < maxFlush) && !ref3.IsInvalid; ref3 = ref4)
             {
                 for (ref4 = this._pages[ref3.PageIndex]._entries[ref3.Ref2Index]._ref2._prev; ref4.IsRef1; ref4 = this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._prev)
                 {
                 }
                 entryArray = this._pages[ref3.PageIndex]._entries;
                 num = ref3.Ref2Index;
                 if (!force)
                 {
                     DateTime time = entryArray[num]._utcDate;
                     if (((utcNow - time) <= CacheUsage.NEWADD_INTERVAL) && (utcNow >= time))
                     {
                         continue;
                     }
                 }
                 UsageEntryRef entryRef = new UsageEntryRef(ref3.PageIndex, ref3.Ref2Index);
                 entryArray[num]._cacheEntry.UsageEntryRef = UsageEntryRef.INVALID;
                 this.RemoveEntryFromLastRefList(entryRef);
                 entryArray[num]._ref1._next = iNVALID;
                 iNVALID = entryRef;
                 num2++;
                 this._cEntriesInFlush++;
             }
             if (num2 == 0)
             {
                 return 0;
             }
             this._blockReduce = true;
         }
     }
     finally
     {
         this._cacheUsage.MemoryCacheStore.UnblockInsert();
     }
     MemoryCacheStore memoryCacheStore = this._cacheUsage.MemoryCacheStore;
     for (ref6 = iNVALID; !ref6.IsInvalid; ref6 = ref7)
     {
         entryArray = this._pages[ref6.PageIndex]._entries;
         num = ref6.Ref1Index;
         ref7 = entryArray[num]._ref1._next;
         MemoryCacheEntry key = entryArray[num]._cacheEntry;
         entryArray[num]._cacheEntry = null;
         memoryCacheStore.Remove(key, key, CacheEntryRemovedReason.Evicted);
     }
     try
     {
         this._cacheUsage.MemoryCacheStore.BlockInsert();
         lock (this)
         {
             for (ref6 = iNVALID; !ref6.IsInvalid; ref6 = ref7)
             {
                 entryArray = this._pages[ref6.PageIndex]._entries;
                 num = ref6.Ref1Index;
                 ref7 = entryArray[num]._ref1._next;
                 this._cEntriesInFlush--;
                 this.AddUsageEntryToFreeList(ref6);
             }
             this._blockReduce = false;
             this.Reduce();
         }
     }
     finally
     {
         this._cacheUsage.MemoryCacheStore.UnblockInsert();
     }
     return num2;
 }
 internal void AddCacheEntry(MemoryCacheEntry cacheEntry)
 {
     lock (this)
     {
         if (this._freeEntryList._head == -1)
         {
             this.Expand();
         }
         UsageEntryRef freeUsageEntry = this.GetFreeUsageEntry();
         UsageEntryRef ref3 = new UsageEntryRef(freeUsageEntry.PageIndex, -freeUsageEntry.Ref1Index);
         cacheEntry.UsageEntryRef = freeUsageEntry;
         UsageEntry[] entryArray = this._pages[freeUsageEntry.PageIndex]._entries;
         int index = freeUsageEntry.Ref1Index;
         entryArray[index]._cacheEntry = cacheEntry;
         entryArray[index]._utcDate = DateTime.UtcNow;
         entryArray[index]._ref1._prev = UsageEntryRef.INVALID;
         entryArray[index]._ref2._next = this._addRef2Head;
         if (this._lastRefHead.IsInvalid)
         {
             entryArray[index]._ref1._next = ref3;
             entryArray[index]._ref2._prev = freeUsageEntry;
             this._lastRefTail = ref3;
         }
         else
         {
             UsageEntryRef iNVALID;
             UsageEntryRef ref5;
             entryArray[index]._ref1._next = this._lastRefHead;
             if (this._lastRefHead.IsRef1)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref1Index]._ref1._prev = freeUsageEntry;
             }
             else if (this._lastRefHead.IsRef2)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref2Index]._ref2._prev = freeUsageEntry;
             }
             else
             {
                 this._lastRefTail = freeUsageEntry;
             }
             if (this._addRef2Head.IsInvalid)
             {
                 ref5 = this._lastRefTail;
                 iNVALID = UsageEntryRef.INVALID;
             }
             else
             {
                 ref5 = this._pages[this._addRef2Head.PageIndex]._entries[this._addRef2Head.Ref2Index]._ref2._prev;
                 iNVALID = this._addRef2Head;
             }
             entryArray[index]._ref2._prev = ref5;
             if (ref5.IsRef1)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._next = ref3;
             }
             else if (ref5.IsRef2)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._next = ref3;
             }
             else
             {
                 this._lastRefHead = ref3;
             }
             if (iNVALID.IsRef1)
             {
                 this._pages[iNVALID.PageIndex]._entries[iNVALID.Ref1Index]._ref1._prev = ref3;
             }
             else if (iNVALID.IsRef2)
             {
                 this._pages[iNVALID.PageIndex]._entries[iNVALID.Ref2Index]._ref2._prev = ref3;
             }
             else
             {
                 this._lastRefTail = ref3;
             }
         }
         this._lastRefHead = freeUsageEntry;
         this._addRef2Head = ref3;
         this._cEntriesInUse++;
     }
 }
 internal void UpdateCacheEntry(MemoryCacheEntry cacheEntry)
 {
     lock (this)
     {
         UsageEntryRef usageEntryRef = cacheEntry.UsageEntryRef;
         if (!usageEntryRef.IsInvalid)
         {
             UsageEntry[]  entryArray = this._pages[usageEntryRef.PageIndex]._entries;
             int           index      = usageEntryRef.Ref1Index;
             UsageEntryRef ref3       = new UsageEntryRef(usageEntryRef.PageIndex, -usageEntryRef.Ref1Index);
             UsageEntryRef ref4       = entryArray[index]._ref2._prev;
             UsageEntryRef ref5       = entryArray[index]._ref2._next;
             if (ref4.IsRef1)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._next = ref5;
             }
             else if (ref4.IsRef2)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref2Index]._ref2._next = ref5;
             }
             else
             {
                 this._lastRefHead = ref5;
             }
             if (ref5.IsRef1)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._prev = ref4;
             }
             else if (ref5.IsRef2)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._prev = ref4;
             }
             else
             {
                 this._lastRefTail = ref4;
             }
             if (this._addRef2Head == ref3)
             {
                 this._addRef2Head = ref5;
             }
             entryArray[index]._ref2 = entryArray[index]._ref1;
             ref4 = entryArray[index]._ref2._prev;
             ref5 = entryArray[index]._ref2._next;
             if (ref4.IsRef1)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._next = ref3;
             }
             else if (ref4.IsRef2)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref2Index]._ref2._next = ref3;
             }
             else
             {
                 this._lastRefHead = ref3;
             }
             if (ref5.IsRef1)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._prev = ref3;
             }
             else if (ref5.IsRef2)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._prev = ref3;
             }
             else
             {
                 this._lastRefTail = ref3;
             }
             entryArray[index]._ref1._prev = UsageEntryRef.INVALID;
             entryArray[index]._ref1._next = this._lastRefHead;
             if (this._lastRefHead.IsRef1)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref1Index]._ref1._prev = usageEntryRef;
             }
             else if (this._lastRefHead.IsRef2)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref2Index]._ref2._prev = usageEntryRef;
             }
             else
             {
                 this._lastRefTail = usageEntryRef;
             }
             this._lastRefHead = usageEntryRef;
         }
     }
 }
 private void AddUsageEntryToFreeList(UsageEntryRef entryRef)
 {
     UsageEntry[] entryArray = this._pages[entryRef.PageIndex]._entries;
     int index = entryRef.Ref1Index;
     entryArray[index]._utcDate = DateTime.MinValue;
     entryArray[index]._ref1._prev = UsageEntryRef.INVALID;
     entryArray[index]._ref2._next = UsageEntryRef.INVALID;
     entryArray[index]._ref2._prev = UsageEntryRef.INVALID;
     entryArray[index]._ref1._next = entryArray[0]._ref1._next;
     entryArray[0]._ref1._next = entryRef;
     this._cEntriesInUse--;
     int pageIndex = entryRef.PageIndex;
     entryArray[0]._cFree++;
     if (entryArray[0]._cFree == 1)
     {
         this.AddToListHead(pageIndex, ref this._freeEntryList);
     }
     else if (entryArray[0]._cFree == 0x7f)
     {
         this.RemovePage(pageIndex);
     }
 }
Пример #11
0
        private void Reduce()
        {
            if (_cEntriesInUse >= _minEntriesInUse || _blockReduce)
            {
                return;
            }

            Debug.Assert(_freeEntryList._head != -1, "_freeEntryList._head != -1");
            Debug.Assert(_freeEntryList._tail != -1, "_freeEntryList._tail != -1");
            Debug.Assert(_freeEntryList._head != _freeEntryList._tail, "_freeEntryList._head != _freeEntryList._tail");

            int meanFree         = (int)(NUM_ENTRIES - (NUM_ENTRIES * MIN_LOAD_FACTOR));
            int pageIndexLast    = _freeEntryList._tail;
            int pageIndexCurrent = _freeEntryList._head;
            int pageIndexNext;

            UsageEntry[] entries;

            for (; ;)
            {
                pageIndexNext = (_pages[(pageIndexCurrent)]._pageNext);

                if ((((_pages[(pageIndexCurrent)]._entries))[0]._cFree) > meanFree)
                {
                    MoveToListTail(pageIndexCurrent, ref _freeEntryList);
                }
                else
                {
                    MoveToListHead(pageIndexCurrent, ref _freeEntryList);
                }

                if (pageIndexCurrent == pageIndexLast)
                {
                    break;
                }

                pageIndexCurrent = pageIndexNext;
            }

            for (; ;)
            {
                if (_freeEntryList._tail == -1)
                {
                    break;
                }

                entries = (_pages[(_freeEntryList._tail)]._entries);
                Debug.Assert(((entries)[0]._cFree) > 0, "FreeEntryCount(entries) > 0");
                int availableFreeEntries = (_cPagesInUse * NUM_ENTRIES) - ((entries)[0]._cFree) - _cEntriesInUse;
                if (availableFreeEntries < (NUM_ENTRIES - ((entries)[0]._cFree)))
                {
                    break;
                }

                for (int i = 1; i < entries.Length; i++)
                {
                    if (entries[i]._cacheEntry == null)
                    {
                        continue;
                    }

                    Debug.Assert(_freeEntryList._head != _freeEntryList._tail, "_freeEntryList._head != _freeEntryList._tail");
                    UsageEntryRef newRef1 = GetFreeUsageEntry();
                    UsageEntryRef newRef2 = (new UsageEntryRef((newRef1).PageIndex, -(newRef1).Ref1Index));
                    Debug.Assert(newRef1.PageIndex != _freeEntryList._tail, "newRef1.PageIndex != _freeEntryList._tail");

                    UsageEntryRef oldRef1 = new UsageEntryRef(_freeEntryList._tail, i);
                    UsageEntryRef oldRef2 = (new UsageEntryRef((oldRef1).PageIndex, -(oldRef1).Ref1Index));

                    MemoryCacheEntry cacheEntry = entries[i]._cacheEntry;
                    Debug.Assert(cacheEntry.UsageEntryRef == oldRef1, "cacheEntry.UsageEntryRef == oldRef1");
                    cacheEntry.UsageEntryRef = newRef1;

                    UsageEntry[] newEntries = (_pages[(newRef1.PageIndex)]._entries);
                    newEntries[newRef1.Ref1Index] = entries[i];

                    ((entries)[0]._cFree)++;

                    UsageEntryRef prev = newEntries[newRef1.Ref1Index]._ref1._prev;
                    Debug.Assert(prev != oldRef2, "prev != oldRef2");

                    UsageEntryRef next = newEntries[newRef1.Ref1Index]._ref1._next;
                    if (next == oldRef2)
                    {
                        next = newRef2;
                    }

                    { if ((prev).IsRef1)
                      {
                          (_pages[((prev).PageIndex)]._entries)[(prev).Ref1Index]._ref1._next = (newRef1);
                      }
                      else if ((prev).IsRef2)
                      {
                          (_pages[((prev).PageIndex)]._entries)[(prev).Ref2Index]._ref2._next = (newRef1);
                      }
                      else
                      {
                          _lastRefHead = (newRef1);
                      } };
                    { if ((next).IsRef1)
                      {
                          (_pages[((next).PageIndex)]._entries)[(next).Ref1Index]._ref1._prev = (newRef1);
                      }
                      else if ((next).IsRef2)
                      {
                          (_pages[((next).PageIndex)]._entries)[(next).Ref2Index]._ref2._prev = (newRef1);
                      }
                      else
                      {
                          _lastRefTail = (newRef1);
                      } };

                    prev = newEntries[newRef1.Ref1Index]._ref2._prev;
                    if (prev == oldRef1)
                    {
                        prev = newRef1;
                    }

                    next = newEntries[newRef1.Ref1Index]._ref2._next;
                    Debug.Assert(next != oldRef1, "next != oldRef1");

                    { if ((prev).IsRef1)
                      {
                          (_pages[((prev).PageIndex)]._entries)[(prev).Ref1Index]._ref1._next = (newRef2);
                      }
                      else if ((prev).IsRef2)
                      {
                          (_pages[((prev).PageIndex)]._entries)[(prev).Ref2Index]._ref2._next = (newRef2);
                      }
                      else
                      {
                          _lastRefHead = (newRef2);
                      } };
                    { if ((next).IsRef1)
                      {
                          (_pages[((next).PageIndex)]._entries)[(next).Ref1Index]._ref1._prev = (newRef2);
                      }
                      else if ((next).IsRef2)
                      {
                          (_pages[((next).PageIndex)]._entries)[(next).Ref2Index]._ref2._prev = (newRef2);
                      }
                      else
                      {
                          _lastRefTail = (newRef2);
                      } };

                    if (_addRef2Head == oldRef2)
                    {
                        _addRef2Head = newRef2;
                    }
                }

                RemovePage(_freeEntryList._tail);
            }
        }
        private void RemoveEntryFromLastRefList(UsageEntryRef entryRef)
        {
            UsageEntry[]  entryArray = this._pages[entryRef.PageIndex]._entries;
            int           index      = entryRef.Ref1Index;
            UsageEntryRef ref2       = entryArray[index]._ref1._prev;
            UsageEntryRef ref3       = entryArray[index]._ref1._next;

            if (ref2.IsRef1)
            {
                this._pages[ref2.PageIndex]._entries[ref2.Ref1Index]._ref1._next = ref3;
            }
            else if (ref2.IsRef2)
            {
                this._pages[ref2.PageIndex]._entries[ref2.Ref2Index]._ref2._next = ref3;
            }
            else
            {
                this._lastRefHead = ref3;
            }
            if (ref3.IsRef1)
            {
                this._pages[ref3.PageIndex]._entries[ref3.Ref1Index]._ref1._prev = ref2;
            }
            else if (ref3.IsRef2)
            {
                this._pages[ref3.PageIndex]._entries[ref3.Ref2Index]._ref2._prev = ref2;
            }
            else
            {
                this._lastRefTail = ref2;
            }
            ref2 = entryArray[index]._ref2._prev;
            ref3 = entryArray[index]._ref2._next;
            UsageEntryRef ref4 = new UsageEntryRef(entryRef.PageIndex, -entryRef.Ref1Index);

            if (ref2.IsRef1)
            {
                this._pages[ref2.PageIndex]._entries[ref2.Ref1Index]._ref1._next = ref3;
            }
            else if (ref2.IsRef2)
            {
                this._pages[ref2.PageIndex]._entries[ref2.Ref2Index]._ref2._next = ref3;
            }
            else
            {
                this._lastRefHead = ref3;
            }
            if (ref3.IsRef1)
            {
                this._pages[ref3.PageIndex]._entries[ref3.Ref1Index]._ref1._prev = ref2;
            }
            else if (ref3.IsRef2)
            {
                this._pages[ref3.PageIndex]._entries[ref3.Ref2Index]._ref2._prev = ref2;
            }
            else
            {
                this._lastRefTail = ref2;
            }
            if (this._addRef2Head == ref4)
            {
                this._addRef2Head = ref3;
            }
        }
 internal void AddCacheEntry(MemoryCacheEntry cacheEntry)
 {
     lock (this)
     {
         if (this._freeEntryList._head == -1)
         {
             this.Expand();
         }
         UsageEntryRef freeUsageEntry = this.GetFreeUsageEntry();
         UsageEntryRef ref3           = new UsageEntryRef(freeUsageEntry.PageIndex, -freeUsageEntry.Ref1Index);
         cacheEntry.UsageEntryRef = freeUsageEntry;
         UsageEntry[] entryArray = this._pages[freeUsageEntry.PageIndex]._entries;
         int          index      = freeUsageEntry.Ref1Index;
         entryArray[index]._cacheEntry = cacheEntry;
         entryArray[index]._utcDate    = DateTime.UtcNow;
         entryArray[index]._ref1._prev = UsageEntryRef.INVALID;
         entryArray[index]._ref2._next = this._addRef2Head;
         if (this._lastRefHead.IsInvalid)
         {
             entryArray[index]._ref1._next = ref3;
             entryArray[index]._ref2._prev = freeUsageEntry;
             this._lastRefTail             = ref3;
         }
         else
         {
             UsageEntryRef iNVALID;
             UsageEntryRef ref5;
             entryArray[index]._ref1._next = this._lastRefHead;
             if (this._lastRefHead.IsRef1)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref1Index]._ref1._prev = freeUsageEntry;
             }
             else if (this._lastRefHead.IsRef2)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref2Index]._ref2._prev = freeUsageEntry;
             }
             else
             {
                 this._lastRefTail = freeUsageEntry;
             }
             if (this._addRef2Head.IsInvalid)
             {
                 ref5    = this._lastRefTail;
                 iNVALID = UsageEntryRef.INVALID;
             }
             else
             {
                 ref5    = this._pages[this._addRef2Head.PageIndex]._entries[this._addRef2Head.Ref2Index]._ref2._prev;
                 iNVALID = this._addRef2Head;
             }
             entryArray[index]._ref2._prev = ref5;
             if (ref5.IsRef1)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._next = ref3;
             }
             else if (ref5.IsRef2)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._next = ref3;
             }
             else
             {
                 this._lastRefHead = ref3;
             }
             if (iNVALID.IsRef1)
             {
                 this._pages[iNVALID.PageIndex]._entries[iNVALID.Ref1Index]._ref1._prev = ref3;
             }
             else if (iNVALID.IsRef2)
             {
                 this._pages[iNVALID.PageIndex]._entries[iNVALID.Ref2Index]._ref2._prev = ref3;
             }
             else
             {
                 this._lastRefTail = ref3;
             }
         }
         this._lastRefHead = freeUsageEntry;
         this._addRef2Head = ref3;
         this._cEntriesInUse++;
     }
 }
        private void Reduce()
        {
            int num4;

            if ((this._cEntriesInUse >= this._minEntriesInUse) || this._blockReduce)
            {
                return;
            }
            int num   = 0x3f;
            int num2  = this._freeEntryList._tail;
            int index = this._freeEntryList._head;

Label_0032:
            num4 = this._pages[index]._pageNext;
            if (this._pages[index]._entries[0]._cFree > num)
            {
                this.MoveToListTail(index, ref this._freeEntryList);
            }
            else
            {
                this.MoveToListHead(index, ref this._freeEntryList);
            }
            if (index != num2)
            {
                index = num4;
                goto Label_0032;
            }
            while (this._freeEntryList._tail != -1)
            {
                UsageEntry[] entryArray = this._pages[this._freeEntryList._tail]._entries;
                int          num5       = ((this._cPagesInUse * 0x7f) - entryArray[0]._cFree) - this._cEntriesInUse;
                if (num5 < (0x7f - entryArray[0]._cFree))
                {
                    return;
                }
                for (int i = 1; i < entryArray.Length; i++)
                {
                    if (entryArray[i]._cacheEntry != null)
                    {
                        UsageEntryRef freeUsageEntry = this.GetFreeUsageEntry();
                        UsageEntryRef ref3           = new UsageEntryRef(freeUsageEntry.PageIndex, -freeUsageEntry.Ref1Index);
                        UsageEntryRef ref4           = new UsageEntryRef(this._freeEntryList._tail, i);
                        UsageEntryRef ref5           = new UsageEntryRef(ref4.PageIndex, -ref4.Ref1Index);
                        entryArray[i]._cacheEntry.UsageEntryRef = freeUsageEntry;
                        UsageEntry[] entryArray2 = this._pages[freeUsageEntry.PageIndex]._entries;
                        entryArray2[freeUsageEntry.Ref1Index] = entryArray[i];
                        entryArray[0]._cFree++;
                        UsageEntryRef ref6 = entryArray2[freeUsageEntry.Ref1Index]._ref1._prev;
                        UsageEntryRef ref7 = entryArray2[freeUsageEntry.Ref1Index]._ref1._next;
                        if (ref7 == ref5)
                        {
                            ref7 = ref3;
                        }
                        if (ref6.IsRef1)
                        {
                            this._pages[ref6.PageIndex]._entries[ref6.Ref1Index]._ref1._next = freeUsageEntry;
                        }
                        else if (ref6.IsRef2)
                        {
                            this._pages[ref6.PageIndex]._entries[ref6.Ref2Index]._ref2._next = freeUsageEntry;
                        }
                        else
                        {
                            this._lastRefHead = freeUsageEntry;
                        }
                        if (ref7.IsRef1)
                        {
                            this._pages[ref7.PageIndex]._entries[ref7.Ref1Index]._ref1._prev = freeUsageEntry;
                        }
                        else if (ref7.IsRef2)
                        {
                            this._pages[ref7.PageIndex]._entries[ref7.Ref2Index]._ref2._prev = freeUsageEntry;
                        }
                        else
                        {
                            this._lastRefTail = freeUsageEntry;
                        }
                        ref6 = entryArray2[freeUsageEntry.Ref1Index]._ref2._prev;
                        if (ref6 == ref4)
                        {
                            ref6 = freeUsageEntry;
                        }
                        ref7 = entryArray2[freeUsageEntry.Ref1Index]._ref2._next;
                        if (ref6.IsRef1)
                        {
                            this._pages[ref6.PageIndex]._entries[ref6.Ref1Index]._ref1._next = ref3;
                        }
                        else if (ref6.IsRef2)
                        {
                            this._pages[ref6.PageIndex]._entries[ref6.Ref2Index]._ref2._next = ref3;
                        }
                        else
                        {
                            this._lastRefHead = ref3;
                        }
                        if (ref7.IsRef1)
                        {
                            this._pages[ref7.PageIndex]._entries[ref7.Ref1Index]._ref1._prev = ref3;
                        }
                        else if (ref7.IsRef2)
                        {
                            this._pages[ref7.PageIndex]._entries[ref7.Ref2Index]._ref2._prev = ref3;
                        }
                        else
                        {
                            this._lastRefTail = ref3;
                        }
                        if (this._addRef2Head == ref5)
                        {
                            this._addRef2Head = ref3;
                        }
                    }
                }
                this.RemovePage(this._freeEntryList._tail);
            }
            return;
        }
 internal void UpdateCacheEntry(MemoryCacheEntry cacheEntry)
 {
     lock (this)
     {
         UsageEntryRef usageEntryRef = cacheEntry.UsageEntryRef;
         if (!usageEntryRef.IsInvalid)
         {
             UsageEntry[] entryArray = this._pages[usageEntryRef.PageIndex]._entries;
             int index = usageEntryRef.Ref1Index;
             UsageEntryRef ref3 = new UsageEntryRef(usageEntryRef.PageIndex, -usageEntryRef.Ref1Index);
             UsageEntryRef ref4 = entryArray[index]._ref2._prev;
             UsageEntryRef ref5 = entryArray[index]._ref2._next;
             if (ref4.IsRef1)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._next = ref5;
             }
             else if (ref4.IsRef2)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref2Index]._ref2._next = ref5;
             }
             else
             {
                 this._lastRefHead = ref5;
             }
             if (ref5.IsRef1)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._prev = ref4;
             }
             else if (ref5.IsRef2)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._prev = ref4;
             }
             else
             {
                 this._lastRefTail = ref4;
             }
             if (this._addRef2Head == ref3)
             {
                 this._addRef2Head = ref5;
             }
             entryArray[index]._ref2 = entryArray[index]._ref1;
             ref4 = entryArray[index]._ref2._prev;
             ref5 = entryArray[index]._ref2._next;
             if (ref4.IsRef1)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._next = ref3;
             }
             else if (ref4.IsRef2)
             {
                 this._pages[ref4.PageIndex]._entries[ref4.Ref2Index]._ref2._next = ref3;
             }
             else
             {
                 this._lastRefHead = ref3;
             }
             if (ref5.IsRef1)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._prev = ref3;
             }
             else if (ref5.IsRef2)
             {
                 this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._prev = ref3;
             }
             else
             {
                 this._lastRefTail = ref3;
             }
             entryArray[index]._ref1._prev = UsageEntryRef.INVALID;
             entryArray[index]._ref1._next = this._lastRefHead;
             if (this._lastRefHead.IsRef1)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref1Index]._ref1._prev = usageEntryRef;
             }
             else if (this._lastRefHead.IsRef2)
             {
                 this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref2Index]._ref2._prev = usageEntryRef;
             }
             else
             {
                 this._lastRefTail = usageEntryRef;
             }
             this._lastRefHead = usageEntryRef;
         }
     }
 }
 static UsageEntryRef()
 {
     INVALID = new UsageEntryRef(0, 0);
 }
 private void Reduce()
 {
     int num4;
     if ((this._cEntriesInUse >= this._minEntriesInUse) || this._blockReduce)
     {
         return;
     }
     int num = 0x3f;
     int num2 = this._freeEntryList._tail;
     int index = this._freeEntryList._head;
 Label_0032:
     num4 = this._pages[index]._pageNext;
     if (this._pages[index]._entries[0]._cFree > num)
     {
         this.MoveToListTail(index, ref this._freeEntryList);
     }
     else
     {
         this.MoveToListHead(index, ref this._freeEntryList);
     }
     if (index != num2)
     {
         index = num4;
         goto Label_0032;
     }
     while (this._freeEntryList._tail != -1)
     {
         UsageEntry[] entryArray = this._pages[this._freeEntryList._tail]._entries;
         int num5 = ((this._cPagesInUse * 0x7f) - entryArray[0]._cFree) - this._cEntriesInUse;
         if (num5 < (0x7f - entryArray[0]._cFree))
         {
             return;
         }
         for (int i = 1; i < entryArray.Length; i++)
         {
             if (entryArray[i]._cacheEntry != null)
             {
                 UsageEntryRef freeUsageEntry = this.GetFreeUsageEntry();
                 UsageEntryRef ref3 = new UsageEntryRef(freeUsageEntry.PageIndex, -freeUsageEntry.Ref1Index);
                 UsageEntryRef ref4 = new UsageEntryRef(this._freeEntryList._tail, i);
                 UsageEntryRef ref5 = new UsageEntryRef(ref4.PageIndex, -ref4.Ref1Index);
                 entryArray[i]._cacheEntry.UsageEntryRef = freeUsageEntry;
                 UsageEntry[] entryArray2 = this._pages[freeUsageEntry.PageIndex]._entries;
                 entryArray2[freeUsageEntry.Ref1Index] = entryArray[i];
                 entryArray[0]._cFree++;
                 UsageEntryRef ref6 = entryArray2[freeUsageEntry.Ref1Index]._ref1._prev;
                 UsageEntryRef ref7 = entryArray2[freeUsageEntry.Ref1Index]._ref1._next;
                 if (ref7 == ref5)
                 {
                     ref7 = ref3;
                 }
                 if (ref6.IsRef1)
                 {
                     this._pages[ref6.PageIndex]._entries[ref6.Ref1Index]._ref1._next = freeUsageEntry;
                 }
                 else if (ref6.IsRef2)
                 {
                     this._pages[ref6.PageIndex]._entries[ref6.Ref2Index]._ref2._next = freeUsageEntry;
                 }
                 else
                 {
                     this._lastRefHead = freeUsageEntry;
                 }
                 if (ref7.IsRef1)
                 {
                     this._pages[ref7.PageIndex]._entries[ref7.Ref1Index]._ref1._prev = freeUsageEntry;
                 }
                 else if (ref7.IsRef2)
                 {
                     this._pages[ref7.PageIndex]._entries[ref7.Ref2Index]._ref2._prev = freeUsageEntry;
                 }
                 else
                 {
                     this._lastRefTail = freeUsageEntry;
                 }
                 ref6 = entryArray2[freeUsageEntry.Ref1Index]._ref2._prev;
                 if (ref6 == ref4)
                 {
                     ref6 = freeUsageEntry;
                 }
                 ref7 = entryArray2[freeUsageEntry.Ref1Index]._ref2._next;
                 if (ref6.IsRef1)
                 {
                     this._pages[ref6.PageIndex]._entries[ref6.Ref1Index]._ref1._next = ref3;
                 }
                 else if (ref6.IsRef2)
                 {
                     this._pages[ref6.PageIndex]._entries[ref6.Ref2Index]._ref2._next = ref3;
                 }
                 else
                 {
                     this._lastRefHead = ref3;
                 }
                 if (ref7.IsRef1)
                 {
                     this._pages[ref7.PageIndex]._entries[ref7.Ref1Index]._ref1._prev = ref3;
                 }
                 else if (ref7.IsRef2)
                 {
                     this._pages[ref7.PageIndex]._entries[ref7.Ref2Index]._ref2._prev = ref3;
                 }
                 else
                 {
                     this._lastRefTail = ref3;
                 }
                 if (this._addRef2Head == ref5)
                 {
                     this._addRef2Head = ref3;
                 }
             }
         }
         this.RemovePage(this._freeEntryList._tail);
     }
     return;
 }
Пример #18
0
        internal int FlushUnderUsedItems(int maxFlush, bool force)
        {
            if (_cEntriesInUse == 0)
            {
                return(0);
            }

            Debug.Assert(maxFlush > 0, "maxFlush is not greater than 0, instead is " + maxFlush);
            Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0");

            UsageEntryRef inFlushHead = UsageEntryRef.INVALID;

            UsageEntryRef prev, prevNext;
            DateTime      utcDate;

            UsageEntry[]     entries;
            int              entryIndex;
            MemoryCacheEntry cacheEntry;
            int              flushed = 0;

            try
            {
                _cacheUsage.MemoryCacheStore.BlockInsert();

                lock (this)
                {
                    Debug.Assert(_blockReduce == false, "_blockReduce == false");

                    if (_cEntriesInUse == 0)
                    {
                        return(0);
                    }

                    DateTime utcNow = DateTime.UtcNow;

                    for (prev = _lastRefTail; _cEntriesInFlush < maxFlush && !prev.IsInvalid; prev = prevNext)
                    {
                        Debug.Assert(_cEntriesInUse > 0, "_cEntriesInUse > 0");

                        prevNext = (_pages[(prev.PageIndex)]._entries)[prev.Ref2Index]._ref2._prev;
                        while (prevNext.IsRef1)
                        {
                            prevNext = (_pages[(prevNext.PageIndex)]._entries)[prevNext.Ref1Index]._ref1._prev;
                        }

                        entries    = (_pages[(prev.PageIndex)]._entries);
                        entryIndex = prev.Ref2Index;

                        if (!force)
                        {
                            utcDate = entries[entryIndex]._utcDate;
                            Debug.Assert(utcDate != DateTime.MinValue, "utcDate != DateTime.MinValue");

                            if (utcNow - utcDate <= CacheUsage.NEWADD_INTERVAL && utcNow >= utcDate)
                            {
                                continue;
                            }
                        }

                        UsageEntryRef prev1 = (new UsageEntryRef((prev).PageIndex, (prev).Ref2Index));
                        cacheEntry = entries[entryIndex]._cacheEntry;
                        Debug.Assert(cacheEntry.UsageEntryRef == prev1, "cacheEntry.UsageEntryRef == prev1");
                        Dbg.Trace("CacheUsageFlushUnderUsedItem", "Flushing underused items, item=" + cacheEntry.Key + ", bucket=" + _bucket);

                        cacheEntry.UsageEntryRef = UsageEntryRef.INVALID;

                        RemoveEntryFromLastRefList(prev1);

                        entries[entryIndex]._ref1._next = inFlushHead;
                        inFlushHead = prev1;

                        flushed++;
                        _cEntriesInFlush++;
                    }

                    if (flushed == 0)
                    {
                        Dbg.Trace("CacheUsageFlushTotal", "Flush(" + maxFlush + "," + force + ") removed " + flushed +
                                  " underused items; Time=" + DateTime.Now.ToString("o", CultureInfo.InvariantCulture));

                        return(0);
                    }

                    _blockReduce = true;
                }
            }
            finally
            {
                _cacheUsage.MemoryCacheStore.UnblockInsert();
            }

            Debug.Assert(!inFlushHead.IsInvalid, "!inFlushHead.IsInvalid");

            MemoryCacheStore cacheStore = _cacheUsage.MemoryCacheStore;
            UsageEntryRef    current    = inFlushHead;
            UsageEntryRef    next;

            while (!current.IsInvalid)
            {
                entries    = (_pages[(current.PageIndex)]._entries);
                entryIndex = current.Ref1Index;

                next = entries[entryIndex]._ref1._next;

                cacheEntry = entries[entryIndex]._cacheEntry;
                entries[entryIndex]._cacheEntry = null;
                Debug.Assert(cacheEntry.UsageEntryRef.IsInvalid, "cacheEntry.UsageEntryRef.IsInvalid");
                cacheStore.Remove(cacheEntry, cacheEntry, CacheEntryRemovedReason.Evicted);

                current = next;
            }

            try
            {
                _cacheUsage.MemoryCacheStore.BlockInsert();

                lock (this)
                {
                    current = inFlushHead;
                    while (!current.IsInvalid)
                    {
                        entries    = (_pages[(current.PageIndex)]._entries);
                        entryIndex = current.Ref1Index;

                        next = entries[entryIndex]._ref1._next;

                        _cEntriesInFlush--;
                        AddUsageEntryToFreeList(current);

                        current = next;
                    }

                    Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0");

                    _blockReduce = false;
                    Reduce();

                    Dbg.Trace("CacheUsageFlushTotal", "Flush(" + maxFlush + "," + force + ") removed " + flushed +
                              " underused items; Time=" + DateTime.Now.ToString("o", CultureInfo.InvariantCulture));
                }
            }
            finally
            {
                _cacheUsage.MemoryCacheStore.UnblockInsert();
            }

            return(flushed);
        }
Пример #19
0
        internal void UpdateCacheEntry(MemoryCacheEntry cacheEntry)
        {
            lock (this)
            {
                UsageEntryRef entryRef = cacheEntry.UsageEntryRef;
                if (entryRef.IsInvalid)
                {
                    return;
                }

                UsageEntry[]  entries    = (_pages[(entryRef.PageIndex)]._entries);
                int           entryIndex = entryRef.Ref1Index;
                UsageEntryRef entryRef2  = (new UsageEntryRef((entryRef).PageIndex, -(entryRef).Ref1Index));

                UsageEntryRef prev = entries[entryIndex]._ref2._prev;
                UsageEntryRef next = entries[entryIndex]._ref2._next;

                { if ((prev).IsRef1)
                  {
                      (_pages[((prev).PageIndex)]._entries)[(prev).Ref1Index]._ref1._next = (next);
                  }
                  else if ((prev).IsRef2)
                  {
                      (_pages[((prev).PageIndex)]._entries)[(prev).Ref2Index]._ref2._next = (next);
                  }
                  else
                  {
                      _lastRefHead = (next);
                  } };
                { if ((next).IsRef1)
                  {
                      (_pages[((next).PageIndex)]._entries)[(next).Ref1Index]._ref1._prev = (prev);
                  }
                  else if ((next).IsRef2)
                  {
                      (_pages[((next).PageIndex)]._entries)[(next).Ref2Index]._ref2._prev = (prev);
                  }
                  else
                  {
                      _lastRefTail = (prev);
                  } };

                if (_addRef2Head == entryRef2)
                {
                    _addRef2Head = next;
                }

                entries[entryIndex]._ref2 = entries[entryIndex]._ref1;
                prev = entries[entryIndex]._ref2._prev;
                next = entries[entryIndex]._ref2._next;

                { if ((prev).IsRef1)
                  {
                      (_pages[((prev).PageIndex)]._entries)[(prev).Ref1Index]._ref1._next = (entryRef2);
                  }
                  else if ((prev).IsRef2)
                  {
                      (_pages[((prev).PageIndex)]._entries)[(prev).Ref2Index]._ref2._next = (entryRef2);
                  }
                  else
                  {
                      _lastRefHead = (entryRef2);
                  } };
                { if ((next).IsRef1)
                  {
                      (_pages[((next).PageIndex)]._entries)[(next).Ref1Index]._ref1._prev = (entryRef2);
                  }
                  else if ((next).IsRef2)
                  {
                      (_pages[((next).PageIndex)]._entries)[(next).Ref2Index]._ref2._prev = (entryRef2);
                  }
                  else
                  {
                      _lastRefTail = (entryRef2);
                  } };

                entries[entryIndex]._ref1._prev = UsageEntryRef.INVALID;
                entries[entryIndex]._ref1._next = _lastRefHead;

                { if ((_lastRefHead).IsRef1)
                  {
                      (_pages[((_lastRefHead).PageIndex)]._entries)[(_lastRefHead).Ref1Index]._ref1._prev = (entryRef);
                  }
                  else if ((_lastRefHead).IsRef2)
                  {
                      (_pages[((_lastRefHead).PageIndex)]._entries)[(_lastRefHead).Ref2Index]._ref2._prev = (entryRef);
                  }
                  else
                  {
                      _lastRefTail = (entryRef);
                  } };
                _lastRefHead = entryRef;

                Dbg.Trace("CacheUsageUpdate",
                          "Updated item=" + cacheEntry.Key +
                          ",_bucket=" + _bucket +
                          ",ref=" + entryRef);
            }
        }
Пример #20
0
        internal void AddCacheEntry(MemoryCacheEntry cacheEntry)
        {
            lock (this)
            {
                if (_freeEntryList._head == -1)
                {
                    Expand();
                }

                UsageEntryRef freeRef1 = GetFreeUsageEntry();
                UsageEntryRef freeRef2 = (new UsageEntryRef((freeRef1).PageIndex, -(freeRef1).Ref1Index));
                Debug.Assert(cacheEntry.UsageEntryRef.IsInvalid, "cacheEntry.UsageEntryRef.IsInvalid");
                cacheEntry.UsageEntryRef = freeRef1;

                UsageEntry[] entries    = (_pages[(freeRef1.PageIndex)]._entries);
                int          entryIndex = freeRef1.Ref1Index;
                entries[entryIndex]._cacheEntry = cacheEntry;
                entries[entryIndex]._utcDate    = DateTime.UtcNow;

                entries[entryIndex]._ref1._prev = UsageEntryRef.INVALID;
                entries[entryIndex]._ref2._next = _addRef2Head;
                if (_lastRefHead.IsInvalid)
                {
                    entries[entryIndex]._ref1._next = freeRef2;
                    entries[entryIndex]._ref2._prev = freeRef1;
                    _lastRefTail = freeRef2;
                }
                else
                {
                    entries[entryIndex]._ref1._next = _lastRefHead;
                    { if ((_lastRefHead).IsRef1)
                      {
                          (_pages[((_lastRefHead).PageIndex)]._entries)[(_lastRefHead).Ref1Index]._ref1._prev = (freeRef1);
                      }
                      else if ((_lastRefHead).IsRef2)
                      {
                          (_pages[((_lastRefHead).PageIndex)]._entries)[(_lastRefHead).Ref2Index]._ref2._prev = (freeRef1);
                      }
                      else
                      {
                          _lastRefTail = (freeRef1);
                      } };

                    UsageEntryRef next, prev;
                    if (_addRef2Head.IsInvalid)
                    {
                        prev = _lastRefTail;
                        next = UsageEntryRef.INVALID;
                    }
                    else
                    {
                        prev = (_pages[(_addRef2Head.PageIndex)]._entries)[_addRef2Head.Ref2Index]._ref2._prev;
                        next = _addRef2Head;
                    }

                    entries[entryIndex]._ref2._prev = prev;
                    { if ((prev).IsRef1)
                      {
                          (_pages[((prev).PageIndex)]._entries)[(prev).Ref1Index]._ref1._next = (freeRef2);
                      }
                      else if ((prev).IsRef2)
                      {
                          (_pages[((prev).PageIndex)]._entries)[(prev).Ref2Index]._ref2._next = (freeRef2);
                      }
                      else
                      {
                          _lastRefHead = (freeRef2);
                      } };
                    { if ((next).IsRef1)
                      {
                          (_pages[((next).PageIndex)]._entries)[(next).Ref1Index]._ref1._prev = (freeRef2);
                      }
                      else if ((next).IsRef2)
                      {
                          (_pages[((next).PageIndex)]._entries)[(next).Ref2Index]._ref2._prev = (freeRef2);
                      }
                      else
                      {
                          _lastRefTail = (freeRef2);
                      } };
                }

                _lastRefHead = freeRef1;
                _addRef2Head = freeRef2;

                _cEntriesInUse++;

                Dbg.Trace("CacheUsageAdd",
                          "Added item=" + cacheEntry.Key +
                          ",_bucket=" + _bucket +
                          ",ref=" + freeRef1);
            }
        }
Пример #21
0
        private void RemoveEntryFromLastRefList(UsageEntryRef entryRef)
        {
            Debug.Assert(entryRef.IsRef1, "entryRef.IsRef1");
            UsageEntry[] entries    = (_pages[(entryRef.PageIndex)]._entries);
            int          entryIndex = entryRef.Ref1Index;

            UsageEntryRef prev = entries[entryIndex]._ref1._prev;
            UsageEntryRef next = entries[entryIndex]._ref1._next;

            { if ((prev).IsRef1)
              {
                  (_pages[((prev).PageIndex)]._entries)[(prev).Ref1Index]._ref1._next = (next);
              }
              else if ((prev).IsRef2)
              {
                  (_pages[((prev).PageIndex)]._entries)[(prev).Ref2Index]._ref2._next = (next);
              }
              else
              {
                  _lastRefHead = (next);
              } };
            { if ((next).IsRef1)
              {
                  (_pages[((next).PageIndex)]._entries)[(next).Ref1Index]._ref1._prev = (prev);
              }
              else if ((next).IsRef2)
              {
                  (_pages[((next).PageIndex)]._entries)[(next).Ref2Index]._ref2._prev = (prev);
              }
              else
              {
                  _lastRefTail = (prev);
              } };

            prev = entries[entryIndex]._ref2._prev;
            next = entries[entryIndex]._ref2._next;

            UsageEntryRef entryRef2 = (new UsageEntryRef((entryRef).PageIndex, -(entryRef).Ref1Index));

            { if ((prev).IsRef1)
              {
                  (_pages[((prev).PageIndex)]._entries)[(prev).Ref1Index]._ref1._next = (next);
              }
              else if ((prev).IsRef2)
              {
                  (_pages[((prev).PageIndex)]._entries)[(prev).Ref2Index]._ref2._next = (next);
              }
              else
              {
                  _lastRefHead = (next);
              } };
            { if ((next).IsRef1)
              {
                  (_pages[((next).PageIndex)]._entries)[(next).Ref1Index]._ref1._prev = (prev);
              }
              else if ((next).IsRef2)
              {
                  (_pages[((next).PageIndex)]._entries)[(next).Ref2Index]._ref2._prev = (prev);
              }
              else
              {
                  _lastRefTail = (prev);
              } };

            if (_addRef2Head == entryRef2)
            {
                _addRef2Head = next;
            }
        }
 private void RemoveEntryFromLastRefList(UsageEntryRef entryRef)
 {
     UsageEntry[] entryArray = this._pages[entryRef.PageIndex]._entries;
     int index = entryRef.Ref1Index;
     UsageEntryRef ref2 = entryArray[index]._ref1._prev;
     UsageEntryRef ref3 = entryArray[index]._ref1._next;
     if (ref2.IsRef1)
     {
         this._pages[ref2.PageIndex]._entries[ref2.Ref1Index]._ref1._next = ref3;
     }
     else if (ref2.IsRef2)
     {
         this._pages[ref2.PageIndex]._entries[ref2.Ref2Index]._ref2._next = ref3;
     }
     else
     {
         this._lastRefHead = ref3;
     }
     if (ref3.IsRef1)
     {
         this._pages[ref3.PageIndex]._entries[ref3.Ref1Index]._ref1._prev = ref2;
     }
     else if (ref3.IsRef2)
     {
         this._pages[ref3.PageIndex]._entries[ref3.Ref2Index]._ref2._prev = ref2;
     }
     else
     {
         this._lastRefTail = ref2;
     }
     ref2 = entryArray[index]._ref2._prev;
     ref3 = entryArray[index]._ref2._next;
     UsageEntryRef ref4 = new UsageEntryRef(entryRef.PageIndex, -entryRef.Ref1Index);
     if (ref2.IsRef1)
     {
         this._pages[ref2.PageIndex]._entries[ref2.Ref1Index]._ref1._next = ref3;
     }
     else if (ref2.IsRef2)
     {
         this._pages[ref2.PageIndex]._entries[ref2.Ref2Index]._ref2._next = ref3;
     }
     else
     {
         this._lastRefHead = ref3;
     }
     if (ref3.IsRef1)
     {
         this._pages[ref3.PageIndex]._entries[ref3.Ref1Index]._ref1._prev = ref2;
     }
     else if (ref3.IsRef2)
     {
         this._pages[ref3.PageIndex]._entries[ref3.Ref2Index]._ref2._prev = ref2;
     }
     else
     {
         this._lastRefTail = ref2;
     }
     if (this._addRef2Head == ref4)
     {
         this._addRef2Head = ref3;
     }
 }
        internal int FlushUnderUsedItems(int maxFlush, bool force)
        {
            UsageEntry[]  entryArray;
            int           num;
            UsageEntryRef ref6;
            UsageEntryRef ref7;

            if (this._cEntriesInUse == 0)
            {
                return(0);
            }
            UsageEntryRef iNVALID = UsageEntryRef.INVALID;
            int           num2    = 0;

            try
            {
                this._cacheUsage.MemoryCacheStore.BlockInsert();
                lock (this)
                {
                    UsageEntryRef ref4;
                    if (this._cEntriesInUse == 0)
                    {
                        return(0);
                    }
                    DateTime utcNow = DateTime.UtcNow;
                    for (UsageEntryRef ref3 = this._lastRefTail; (this._cEntriesInFlush < maxFlush) && !ref3.IsInvalid; ref3 = ref4)
                    {
                        for (ref4 = this._pages[ref3.PageIndex]._entries[ref3.Ref2Index]._ref2._prev; ref4.IsRef1; ref4 = this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._prev)
                        {
                        }
                        entryArray = this._pages[ref3.PageIndex]._entries;
                        num        = ref3.Ref2Index;
                        if (!force)
                        {
                            DateTime time = entryArray[num]._utcDate;
                            if (((utcNow - time) <= CacheUsage.NEWADD_INTERVAL) && (utcNow >= time))
                            {
                                continue;
                            }
                        }
                        UsageEntryRef entryRef = new UsageEntryRef(ref3.PageIndex, ref3.Ref2Index);
                        entryArray[num]._cacheEntry.UsageEntryRef = UsageEntryRef.INVALID;
                        this.RemoveEntryFromLastRefList(entryRef);
                        entryArray[num]._ref1._next = iNVALID;
                        iNVALID = entryRef;
                        num2++;
                        this._cEntriesInFlush++;
                    }
                    if (num2 == 0)
                    {
                        return(0);
                    }
                    this._blockReduce = true;
                }
            }
            finally
            {
                this._cacheUsage.MemoryCacheStore.UnblockInsert();
            }
            MemoryCacheStore memoryCacheStore = this._cacheUsage.MemoryCacheStore;

            for (ref6 = iNVALID; !ref6.IsInvalid; ref6 = ref7)
            {
                entryArray = this._pages[ref6.PageIndex]._entries;
                num        = ref6.Ref1Index;
                ref7       = entryArray[num]._ref1._next;
                MemoryCacheEntry key = entryArray[num]._cacheEntry;
                entryArray[num]._cacheEntry = null;
                memoryCacheStore.Remove(key, key, CacheEntryRemovedReason.Evicted);
            }
            try
            {
                this._cacheUsage.MemoryCacheStore.BlockInsert();
                lock (this)
                {
                    for (ref6 = iNVALID; !ref6.IsInvalid; ref6 = ref7)
                    {
                        entryArray = this._pages[ref6.PageIndex]._entries;
                        num        = ref6.Ref1Index;
                        ref7       = entryArray[num]._ref1._next;
                        this._cEntriesInFlush--;
                        this.AddUsageEntryToFreeList(ref6);
                    }
                    this._blockReduce = false;
                    this.Reduce();
                }
            }
            finally
            {
                this._cacheUsage.MemoryCacheStore.UnblockInsert();
            }
            return(num2);
        }
        internal MemoryCacheEntry(String key,
                                  Object value,
                                  DateTimeOffset absExp, 
                                  TimeSpan slidingExp, 
                                  CacheItemPriority priority, 
                                  Collection<ChangeMonitor> dependencies,
                                  CacheEntryRemovedCallback removedCallback,
                                  MemoryCache cache) : base(key) {
            if (value == null) {
                throw new ArgumentNullException("value");
            }
            _utcCreated = DateTime.UtcNow;
            _value = value;

            _slidingExp = slidingExp;
            if (_slidingExp > TimeSpan.Zero) {
                _utcAbsExp = _utcCreated + _slidingExp;
            }
            else {
                _utcAbsExp = absExp.UtcDateTime;
            }

            _expiresEntryRef = ExpiresEntryRef.INVALID;
            _expiresBucket = 0xff;

            _usageEntryRef = UsageEntryRef.INVALID;
            if (priority == CacheItemPriority.NotRemovable) {
                _usageBucket = 0xff;
            }
            else {
                _usageBucket = 0;
            }

            _callback = removedCallback;

            if (dependencies != null) {
                _fields = new SeldomUsedFields();
                _fields._dependencies = dependencies;
                _fields._cache = cache;
            }
        }
 static UsageEntryRef()
 {
     INVALID = new UsageEntryRef(0, 0);
 }