Provides a dynamically sizing sequence of unmanaged data.
Inheritance: IDisposable
        /// <summary>
        /// Writes all of the dirty blocks passed onto the disk subsystem. Also computes the checksum for the data.
        /// </summary>
        /// <param name="currentEndOfCommitPosition">the last valid byte of the file system where this data will be appended to.</param>
        /// <param name="stream">the source of the data to dump to the disk</param>
        /// <param name="length">The number by bytes to write to the file system.</param>
        /// <param name="waitForWriteToDisk">True to wait for a complete commit to disk before returning from this function.</param>
        public void Write(long currentEndOfCommitPosition, MemoryPoolStreamCore stream, long length, bool waitForWriteToDisk)
        {
            byte[] buffer = m_bufferQueue.Dequeue();
            long endPosition = currentEndOfCommitPosition + length;
            long currentPosition = currentEndOfCommitPosition;
            while (currentPosition < endPosition)
            {
                IntPtr ptr;
                int streamLength;
                stream.ReadBlock(currentPosition, out ptr, out streamLength);
                int subLength = (int)Math.Min(streamLength, endPosition - currentPosition);
                Footer.ComputeChecksumAndClearFooter(ptr, m_fileStructureBlockSize, subLength);
                Marshal.Copy(ptr, buffer, 0, subLength);
                WriteRaw(currentPosition, buffer, subLength);

                currentPosition += subLength;
            }
            m_bufferQueue.Enqueue(buffer);

            if (waitForWriteToDisk)
            {
                FlushFileBuffers();
            }
            else
            {
                using (m_isUsingStream.EnterReadLock())
                {
                    m_stream.Flush(false);
                }
            }
        }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            if (!m_disposed)
            {
                try
                {
                    m_disposed = true;
                    //Unregistering from this event gaurentees that a collection will no longer
                    //be called since this class utilizes custom code to garentee this.
                    m_pool.RequestCollection -= m_pool_RequestCollection;

                    lock (m_syncRoot)
                    {
                        if (m_pageReplacementAlgorithm != null)
                            m_pageReplacementAlgorithm.Dispose();
                        if (m_queue != null)
                            m_queue.Dispose();
                        if (m_writeBuffer != null)
                            m_writeBuffer.Dispose();
                    }
                }
                finally
                {
                    m_queue = null;
                    m_disposed = true;
                    m_pageReplacementAlgorithm = null;
                    m_writeBuffer = null;
                    m_queue = null;
                    GC.SuppressFinalize(this);
                }
            }
        }
 /// <summary>
 /// Releases the buffered data contained in the buffer pool.
 /// This is acomplished by disposing of the writer and recreating it.
 /// </summary>
 private void ReleaseWriteBufferSpace()
 {
     m_writeBuffer.Dispose();
     m_writeBuffer = new MemoryPoolStreamCore(m_pool);
     m_writeBuffer.ConfigureAlignment(m_lengthOfCommittedData, m_pool.PageSize);
 }
        /// <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);
        }