/// <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); }
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)); }
/// <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)); }
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)); }
/// <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> /// 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); }