This class allocates and pools unmanaged memory. Designed to be internally thread safe.
Be careful how this class is referenced. Deadlocks can occur when registering to event RequestCollection and when calling AllocatePage. See comments for these methods for considerations.
Inheritance: IDisposable
コード例 #1
0
        /// <summary>
        /// Creates a new instance of <see cref="PageReplacementAlgorithm"/>.
        /// </summary>
        /// <param name="pool">The memory pool that blocks will be allocated from.</param>
        public PageReplacementAlgorithm(MemoryPool pool)
        {
            if (pool.PageSize < 4096)
                throw new ArgumentOutOfRangeException("PageSize Must be greater than 4096", "pool");
            if (!BitMath.IsPowerOfTwo(pool.PageSize))
                throw new ArgumentException("PageSize Must be a power of 2", "pool");

            m_maxValidPosition = (int.MaxValue - 1) * (long)pool.PageSize; //Max position 

            m_syncRoot = new object();
            m_memoryPageSizeMask = pool.PageSize - 1;
            m_memoryPageSizeShiftBits = BitMath.CountBitsSet((uint)m_memoryPageSizeMask);
            m_pageList = new PageList(pool);
            m_arrayIndexLocks = new WeakList<PageLock>();
        }
コード例 #2
0
 /// <summary>
 /// Creates a <see cref="DiskMedium"/> from a <see cref="stream"/>. 
 /// This will read the existing header from the <see cref="stream"/>.
 /// </summary>
 /// <param name="stream">An open <see cref="FileStream"/> to use. The <see cref="DiskMedium"/>
 /// will assume ownership of this <see cref="FileStream"/>.</param>
 /// <param name="pool">The <see cref="MemoryPool"/> to allocate data from.</param>
 /// <param name="fileStructureBlockSize">the block size of the file structure. Usually 4kb.</param>
 /// <returns></returns>
 public static DiskMedium OpenFile(CustomFileStream stream, MemoryPool pool, int fileStructureBlockSize)
 {
     byte[] buffer = new byte[fileStructureBlockSize];
     stream.ReadRaw(0, buffer, fileStructureBlockSize);
     FileHeaderBlock header = FileHeaderBlock.Open(buffer);
     BufferedFile disk = new BufferedFile(stream, pool, header, isNewFile: false);
     return new DiskMedium(disk, header);
 }
コード例 #3
0
        /// <summary>
        /// Creates a <see cref="DiskMedium"/> from a <see cref="stream"/>. 
        /// This will initialize the <see cref="stream"/> as an empty file structure.
        /// </summary>
        /// <param name="stream">An open <see cref="FileStream"/> to use. The <see cref="DiskMedium"/>
        ///     will assume ownership of this <see cref="FileStream"/>.</param>
        /// <param name="pool">the <see cref="MemoryPool"/> to allocate data from</param>
        /// <param name="fileStructureBlockSize">the block size of the file structure. Usually 4kb.</param>
        /// <param name="flags">Flags to write to the file</param>
        /// <returns></returns>
        /// <remarks>
        /// This will not check if the file is truely a new file. If calling this with an existing
        /// archive file, it will overwrite the table of contents, corrupting the file.
        /// </remarks>
        public static DiskMedium CreateFile(CustomFileStream stream, MemoryPool pool, int fileStructureBlockSize, params Guid[] flags)
        {
            FileHeaderBlock header = FileHeaderBlock.CreateNew(fileStructureBlockSize, flags);

            BufferedFile disk = new BufferedFile(stream, pool, header, isNewFile: true);
            return new DiskMedium(disk, header);
        }
コード例 #4
0
 /// <summary>
 /// Creates a <see cref="DiskMedium"/> that is entirely based in memory.
 /// </summary>
 /// <param name="pool">the <see cref="MemoryPool"/> to allocate data from</param>
 /// <param name="fileStructureBlockSize">the block size of the file structure. Usually 4kb.</param>
 /// <param name="flags">Flags to write to the file</param>
 /// <returns></returns>
 public static DiskMedium CreateMemoryFile(MemoryPool pool, int fileStructureBlockSize, params Guid[] flags)
 {
     FileHeaderBlock header = FileHeaderBlock.CreateNew(fileStructureBlockSize, flags);
     MemoryPoolFile disk = new MemoryPoolFile(pool);
     return new DiskMedium(disk, header);
 }
コード例 #5
0
 /// <summary>
 /// Creates a new PageMetaDataList.
 /// </summary>
 /// <param name="memoryPool">The buffer pool to utilize if any unmanaged memory needs to be created.</param>
 public PageList(MemoryPool memoryPool)
 {
     m_memoryPool = memoryPool;
     m_listOfPages = new NullableLargeArray<InternalPageMetaData>();
     m_pageIndexLookupByPositionIndex = new SortedList<int, int>();
 }
コード例 #6
0
 /// <summary>
 /// Creates a <see cref="BinaryStream"/> that is in memory only.
 /// </summary>
 public BinaryStream(MemoryPool pool)
     : this(new MemoryPoolStream(pool), false)
 {
     if (!BitConverter.IsLittleEndian)
         throw new Exception("Only designed to run on a little endian processor.");
 }
コード例 #7
0
 /// <summary>
 /// Create a new <see cref="MemoryPoolStream"/>
 /// </summary>
 public MemoryPoolStream(MemoryPool pool)
     : base(pool)
 {
     m_blockSize = pool.PageSize;
 }
コード例 #8
0
 static Globals()
 {
     MemoryPool = new MemoryPool(65536);
 }
コード例 #9
0
 public static DiskIo OpenFile(string fileName, MemoryPool pool, bool isReadOnly)
 {
     int fileStructureBlockSize;
     CustomFileStream fileStream = CustomFileStream.OpenFile(fileName, pool.PageSize, out fileStructureBlockSize, isReadOnly, true);
     DiskMedium disk = DiskMedium.OpenFile(fileStream, pool, fileStructureBlockSize);
     return new DiskIo(disk, isReadOnly);
 }
コード例 #10
0
 public static DiskIo CreateFile(string fileName, MemoryPool pool, int fileStructureBlockSize, params Guid[] flags)
 {
     //Exclusive opening to prevent duplicate opening.
     CustomFileStream fileStream = CustomFileStream.CreateFile(fileName, pool.PageSize, fileStructureBlockSize);
     DiskMedium disk = DiskMedium.CreateFile(fileStream, pool, fileStructureBlockSize, flags);
     return new DiskIo(disk, false);
 }
コード例 #11
0
 public static DiskIo CreateMemoryFile(MemoryPool pool, int fileStructureBlockSize, params Guid[] flags)
 {
     DiskMedium disk = DiskMedium.CreateMemoryFile(pool, fileStructureBlockSize, flags);
     return new DiskIo(disk, false);
 }
コード例 #12
0
 /// <summary>
 /// Create a new <see cref="MemoryPoolStream"/>
 /// </summary>
 public MemoryPoolStream(MemoryPool pool)
     : base(pool)
 {
     m_blockSize = pool.PageSize;
 }
コード例 #13
0
 /// <summary>
 /// Releases the unmanaged resources used by the <see cref="MemoryFile"/> object and optionally releases the managed resources.
 /// </summary>
 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
 private void Dispose(bool disposing)
 {
     if (!m_disposed)
     {
         try
         {
             if (!m_pool.IsDisposed)
             {
                 m_pool.ReleasePages(m_settings.GetAllPageIndexes());
             }
         }
         finally
         {
             m_pool = null;
             m_settings = null;
             m_disposed = true;
         }
     }
 }
コード例 #14
0
 /// <summary>
 /// Create a new <see cref="MemoryPoolStreamCore"/>
 /// </summary>
 public MemoryPoolStreamCore(MemoryPool pool)
 {
     m_pool = pool;
     m_shiftLength = pool.PageShiftBits;
     m_pageSize = pool.PageSize;
     m_invertMask = ~(long)(pool.PageSize - 1);
     m_settings = new Settings();
     m_syncRoot = new object();
 }
コード例 #15
0
        /// <summary>
        /// Creates a file backed memory stream.
        /// </summary>
        /// <param name="stream">The <see cref="CustomFileStream"/> to buffer</param>
        /// <param name="pool">The <see cref="MemoryPool"/> to allocate memory from</param>
        /// <param name="header">The <see cref="FileHeaderBlock"/> to be managed when modifications occur</param>
        /// <param name="isNewFile">Tells if this is a newly created file. This will make sure that the 
        /// first 10 pages have the header data copied to it.</param>
        public BufferedFile(CustomFileStream stream, MemoryPool pool, FileHeaderBlock header, bool isNewFile)
        {
            m_fileStructureBlockSize = header.BlockSize;
            m_diskBlockSize = pool.PageSize;
            m_lengthOfHeader = header.BlockSize * header.HeaderBlockCount;
            m_writeBuffer = new MemoryPoolStreamCore(pool);
            m_pool = pool;
            m_queue = stream;
            m_syncRoot = new object();
            m_pageReplacementAlgorithm = new PageReplacementAlgorithm(pool);
            pool.RequestCollection += m_pool_RequestCollection;

            if (isNewFile)
            {
                byte[] headerBytes = header.GetBytes();
                for (int x = 0; x < header.HeaderBlockCount; x++)
                {
                    m_queue.WriteRaw(0, headerBytes, headerBytes.Length);
                }
            }
            m_lengthOfCommittedData = (header.LastAllocatedBlock + 1) * (long)header.BlockSize;
            m_writeBuffer.ConfigureAlignment(m_lengthOfCommittedData, pool.PageSize);
        }
コード例 #16
0
 /// <summary>
 /// Create a new <see cref="MemoryPoolFile"/>
 /// </summary>
 public MemoryPoolFile(MemoryPool pool)
     : base(pool)
 {
     m_ioSession = new IoSession(this);
     m_isReadOnly = false;
 }