예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }