/// <summary> /// Returns the pointer for the provided page index. /// </summary> /// <param name="pageIndex">the index of the page that has been looked up for the position.</param> /// <param name="incrementReferencedCount">the value to increment the referenced count.</param> /// <returns></returns> public IntPtr GetPointerToPage(int pageIndex, int incrementReferencedCount) { if (m_disposed) { throw new ObjectDisposedException(GetType().FullName); } InternalPageMetaData metaData = m_listOfPages.GetValue(pageIndex); if (incrementReferencedCount > 0) { long newValue = metaData.ReferencedCount + (long)incrementReferencedCount; if (newValue > int.MaxValue) { metaData.ReferencedCount = int.MaxValue; } else if (newValue < 0) { metaData.ReferencedCount = 0; } else { metaData.ReferencedCount = (int)newValue; } m_listOfPages.OverwriteValue(pageIndex, metaData); } return((IntPtr)metaData.LocationOfPage); }
/// <summary> /// Executes a collection cycle on the pages in this list. /// </summary> /// <param name="shiftLevel">the number of bits to shift the referenced counter by. /// Value may be zero but cannot be negative</param> /// <param name="excludedList">A set of values to exclude from the collection process</param> /// <param name="e">Arguments for the collection.</param> /// <returns>The number of pages returned to the memory pool</returns> /// <remarks>If the collection mode is Emergency or Critical, it will only release the required number of pages and no more</remarks> //ToDo: Since i'll be parsing the entire list, rebuilding a new sorted tree may be quicker than removing individual blocks and copying. //ToDo: Also, I should probably change the ShouldCollect callback to an IEnumerable<int>. public int DoCollection(int shiftLevel, HashSet <int> excludedList, CollectionEventArgs e) { if (m_disposed) { throw new ObjectDisposedException(GetType().FullName); } if (shiftLevel < 0) { throw new ArgumentOutOfRangeException("shiftLevel", "must be non negative"); } int collectionCount = 0; int maxCollectCount = -1; if (e.CollectionMode == MemoryPoolCollectionMode.Emergency || e.CollectionMode == MemoryPoolCollectionMode.Critical) { maxCollectCount = e.DesiredPageReleaseCount; } for (int x = 0; x < m_pageIndexLookupByPositionIndex.Count; x++) { int pageIndex = m_pageIndexLookupByPositionIndex.Values[x]; InternalPageMetaData block = m_listOfPages.GetValue(pageIndex); block.ReferencedCount >>= shiftLevel; m_listOfPages.OverwriteValue(pageIndex, block); if (block.ReferencedCount == 0) { if (maxCollectCount != collectionCount) { if (!excludedList.Contains(pageIndex)) { collectionCount++; m_pageIndexLookupByPositionIndex.RemoveAt(x); x--; m_listOfPages.SetNull(pageIndex); e.ReleasePage(block.MemoryPoolIndex); } } } } return(collectionCount); }