A functional wrapper around a FileStream specific to how the TransactionalFileStructure uses the FileStream.
Inheritance: IDisposable
Beispiel #1
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)
            {
                try
                {
                    m_queue.Open();
                    byte[] headerBytes = header.GetBytes();
                    for (int x = 0; x < header.HeaderBlockCount; x++)
                    {
                        m_queue.WriteRaw(0, headerBytes, headerBytes.Length);
                    }
                }
                finally
                {
                    m_queue.Close();
                }
            }
            m_lengthOfCommittedData = (header.LastAllocatedBlock + 1) * header.BlockSize;
            m_writeBuffer.ConfigureAlignment(m_lengthOfCommittedData, pool.PageSize);
        }
Beispiel #2
0
        public static DiskIo OpenFile(string fileName, MemoryPool pool, bool isReadOnly)
        {
            CustomFileStream fileStream = CustomFileStream.OpenFile(fileName, pool.PageSize, out int fileStructureBlockSize, isReadOnly, true);
            DiskMedium       disk       = DiskMedium.OpenFile(fileStream, pool, fileStructureBlockSize);

            return(new DiskIo(disk, isReadOnly));
        }
Beispiel #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));
        }
Beispiel #4
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));
        }
Beispiel #5
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));
        }
Beispiel #6
0
        /// <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>
 /// 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);
 }
        /// <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);
        }
        /// <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>
        /// 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);
        }