private void Expand() { if (this._freePageList._head == -1) { int length; if (this._pages == null) { length = 0; } else { length = this._pages.Length; } int num2 = length * 2; ExpiresPage[] pageArray = new ExpiresPage[Math.Min(Math.Max(length + 10, num2), length + 340)]; for (int j = 0; j < length; j++) { pageArray[j] = this._pages[j]; } for (int k = length; k < pageArray.Length; k++) { pageArray[k]._pagePrev = k - 1; pageArray[k]._pageNext = k + 1; } pageArray[length]._pagePrev = -1; pageArray[pageArray.Length - 1]._pageNext = -1; this._freePageList._head = length; this._freePageList._tail = pageArray.Length - 1; this._pages = pageArray; } int pageIndex = this.RemoveFromListHead(ref this._freePageList); this.AddToListHead(pageIndex, ref this._freeEntryList); ExpiresEntry[] entryArray = new ExpiresEntry[0x80]; entryArray[0]._cFree = 0x7f; for (int i = 0; i < (entryArray.Length - 1); i++) { entryArray[i]._next = new ExpiresEntryRef(pageIndex, i + 1); } entryArray[entryArray.Length - 1]._next = ExpiresEntryRef.INVALID; this._pages[pageIndex]._entries = entryArray; this._cPagesInUse++; this.UpdateMinEntries(); }
void Expand() { Debug.Assert(_freeHead == -1, "_freeHead == -1"); Debug.Assert(_freeTail == -1, "_freeTail == -1"); Debug.Assert(_cFree == 0, "_cFree == 0"); Debug.Assert(_cFreeLast == 0, "_cFreeLast == 0"); // allocate new buffer int oldSize = Size; int newSize = Math.Max(oldSize * 2, MIN_ENTRIES); ExpiresEntry[] entries = new ExpiresEntry[newSize]; // copy old contents int i, c; c = oldSize; for (i = 0; i < c; i++) { entries[i] = _entries[i]; } // init free list i = oldSize; c = newSize - oldSize - 1; while (c-- > 0) { entries[i].next = i + 1; i++; } entries[i].next = -1; _freeHead = oldSize; _freeTail = i; _cFreeLast = newSize / 2; _cFree = newSize - oldSize; _entries = entries; }
/// <summary> /// Expands the bucket linked array list. /// </summary> private void Expand () { _lock.AcquireWriterLock(-1); try { int oldsize = _intSize; _intSize *= 2; // Copy items to the new list. ExpiresEntry[] newlist = new ExpiresEntry[_intSize]; _arrEntries.CopyTo(newlist, 0); // Set last element to point to the next new empty element _intNext = oldsize; newlist[oldsize - 1]._intNext = oldsize; // Initialize positions for the rest of new elements. for (int i = oldsize; i < _intSize; i++) { newlist[i]._intNext = i + 1; } // Last item signals the expansion of the list. newlist[_intSize - 1]._intNext = -1; // Replace the existing list. _arrEntries = newlist; } finally { _lock.ReleaseWriterLock(); } }
void RemoveEntryAtIndex(CacheEntry cacheEntry, int index) { Debug.Assert(cacheEntry == _entries[index].cacheEntry, "cacheEntry == _entries[index].cacheEntry"); int length = _entries.Length; int lengthdiv2 = length / 2; Debug.Assert((lengthdiv2 & 0x1) == 0, "(lengthdiv2 & 0x1) == 0"); // update the cache entry cacheEntry.ExpiresIndex = -1; cacheEntry.ExpiresBucket = 0xff; // update the expires entry _entries[index].cacheEntry = null; _entries[index].utcExpires = DateTime.MinValue; // add index to free list // if entry is in first half, add to head, else add to tail if (_freeHead == -1) { _freeHead = _freeTail = index; _entries[index].next = -1; } else if (index < lengthdiv2) { _entries[index].next = _freeHead; _freeHead = index; } else { _entries[_freeTail].next = index; _entries[index].next = -1; _freeTail = index; } // update counts _cInUse--; _cFree++; if (index >= lengthdiv2) { _cFreeLast++; } // check whether we should realloc _entries // only realloc if 2nd half is empty Debug.Assert(_cFreeLast <= lengthdiv2); if (_cInUse == 0) { _entries = null; _freeHead = -1; _freeTail = -1; _cFree = 0; _cFreeLast = 0; } else if (_cFreeLast == lengthdiv2 && _cInUse * 2 <= lengthdiv2 && MIN_ENTRIES <= lengthdiv2) { int newSize = lengthdiv2; Debug.Assert(_freeHead >= 0 && _freeHead < newSize, "_freeHead >= 0 && _freeHead < newSize"); // alloc and copy to new array ExpiresEntry[] entries = new ExpiresEntry[newSize]; _freeHead = -1; _freeTail = -1; _cFree = 0; // copy the two halves, and count _cFreeLast during the second half int i = 0, c = 0; for (int halves = 1; halves <= 2; halves++) { _cFreeLast = 0; c += newSize / 2; for (; i < c; i++) { entries[i] = _entries[i]; if (entries[i].cacheEntry == null) { _cFree++; _cFreeLast++; // update the free list if (_freeHead == -1) { _freeHead = i; } else { entries[_freeTail].next = i; } _freeTail = i; } } } Debug.Assert(_freeHead != -1, "_freeHead should not be -1"); Debug.Assert(_freeTail != -1, "_freeTail should not be -1"); // terminate the free list entries[_freeTail].next = -1; #if DBG for (; i < length; i++) { Debug.Assert(_entries[i].cacheEntry == null, "_entries[i].cacheEntry == null"); } #endif _entries = entries; Debug.Trace("CacheExpiresContract", "Contracted from " + length + " to newSize"); } }