A set of fields that are passed to a BinaryStreamIoSessionBase.GetBlock method to get results.
 public override void GetBlock(BlockArguments args)
 {
     if (args.IsWriting && m_file.m_isReadOnly)
         throw new ReadOnlyException("File system is read only");
     args.SupportsWriting = !m_file.m_isReadOnly;
     m_file.GetBlock(args);
 }
예제 #2
0
 /// <summary>
 /// Creates a <see cref="BinaryStream"/> that is at position 0 of the provided stream.
 /// </summary>
 /// <param name="stream">The base stream to use.</param>
 /// <param name="leaveOpen">Determines if the underlying stream will automatically be
 /// disposed of when this class has it's dispose method called.</param>
 public BinaryStream(ISupportsBinaryStream stream, bool leaveOpen = true)
 {
     m_args        = new BlockArguments();
     m_leaveOpen   = leaveOpen;
     m_stream      = stream;
     FirstPosition = 0;
     Current       = null;
     First         = null;
     LastRead      = null;
     LastWrite     = null;
     if (stream.RemainingSupportedIoSessions < 1)
     {
         throw new Exception("Stream has run out of read sessions");
     }
     m_mainIoSession = stream.CreateIoSession();
     //if (stream.RemainingSupportedIoSessions >= 1)
     //    m_secondaryIoSession = stream.CreateIoSession();
 }
예제 #3
0
        /// <summary>
        /// Gets a block for the following Io session.
        /// </summary>
        public void GetBlock(BlockArguments args)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("MemoryStream");
            }
            if (args.Position < m_firstValidPosition)
            {
                throw new ArgumentOutOfRangeException("position", "position is before the beginning of the stream");
            }

            args.Length        = m_pageSize;
            args.FirstPosition = ((args.Position - m_firstAddressablePosition) & m_invertMask) + m_firstAddressablePosition;
            args.FirstPointer  = GetPage(args.Position - m_firstAddressablePosition);

            if (args.FirstPosition < m_firstValidPosition)
            {
                args.FirstPointer += (int)(m_firstValidPosition - args.FirstPosition);
                args.Length       -= (int)(m_firstValidPosition - args.FirstPosition);
                args.FirstPosition = m_firstValidPosition;
            }
        }
        /// <summary>
        /// Creates a new DiskIoSession that can be used to read from the disk subsystem.
        /// </summary>
        /// <param name="diskIo">owner of the disk</param>
        /// <param name="ioSession">the base ioSession to use for this io session</param>
        /// <param name="file">The file that will be read from this diskIoSession</param>
        public DiskIoSession(DiskIo diskIo, BinaryStreamIoSessionBase ioSession, FileHeaderBlock header, SubFileHeader file)
        {
            if (diskIo == null)
                throw new ArgumentNullException("diskIo");
            if (diskIo.IsDisposed)
                throw new ObjectDisposedException(diskIo.GetType().FullName);
            if (ioSession == null)
                throw new ArgumentNullException("ioSession");
            if (file == null)
                throw new ArgumentNullException("file");

            m_args = new BlockArguments();
            m_lastReadonlyBlock = diskIo.LastReadonlyBlock;
            m_diskMediumIoSession = ioSession;
            m_snapshotSequenceNumber = header.SnapshotSequenceNumber;
            m_fileIdNumber = file.FileIdNumber;
            m_isReadOnly = file.IsReadOnly | diskIo.IsReadOnly;
            m_blockSize = diskIo.BlockSize;
            m_diskIo = diskIo;
            IsValid = false;
            IsDisposed = false;
        }
        public void Test1()
        {
            MemoryPoolTest.TestMemoryLeak();
            MemoryPoolFile file = new MemoryPoolFile(Globals.MemoryPool);

            BinaryStreamIoSessionBase session = file.CreateIoSession();

            BlockArguments blockArguments = new BlockArguments();
            blockArguments.IsWriting = true;
            blockArguments.Position = 10000000;
            session.GetBlock(blockArguments);


            System.Console.WriteLine("Get Block\t" + StepTimer.Time(10, () =>
            {
                blockArguments.Position = 100000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 200000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 300000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 400000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 500000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 600000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 700000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 800000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 900000;
                session.GetBlock(blockArguments);
                blockArguments.Position = 1000000;
                session.GetBlock(blockArguments);
            }));
            file.Dispose();
            MemoryPoolTest.TestMemoryLeak();
        }
            public override void GetBlock(BlockArguments args)
            {
                int blockDataLength = m_blockDataLength;
                long pos = args.Position;
                if (IsDisposed || m_dataIoSession.IsDisposed)
                    throw new ObjectDisposedException(GetType().FullName);
                if (pos < 0)
                    throw new ArgumentOutOfRangeException("position", "cannot be negative");
                if (pos >= (long)blockDataLength * (uint.MaxValue - 1))
                    throw new ArgumentOutOfRangeException("position", "position reaches past the end of the file.");

                uint physicalBlockIndex;
                uint indexPosition;

                if (pos <= uint.MaxValue) //64-bit divide is 2 times slower
                    indexPosition = ((uint)pos / (uint)blockDataLength);
                else
                    indexPosition = (uint)((ulong)pos / (ulong)blockDataLength); //64-bit signed divide is twice as slow as 64-bit unsigned.

                args.FirstPosition = (long)indexPosition * blockDataLength;
                args.Length = blockDataLength;

                if (args.IsWriting)
                {
                    throw new Exception("File is read only");
                }
                else
                {
                    //Reading
                    if (indexPosition >= m_stream.m_subFile.DataBlockCount)
                        throw new ArgumentOutOfRangeException("position", "position reaches past the end of the file.");
                    physicalBlockIndex = m_stream.m_subFile.DirectBlock + indexPosition;

                    m_dataIoSession.Read(physicalBlockIndex, BlockType.DataBlock, indexPosition);
                    args.FirstPointer = (IntPtr)m_dataIoSession.Pointer;
                    args.SupportsWriting = false;
                }
            }
 /// <summary>
 /// Gets a block for the following Io session.
 /// </summary>
 /// <param name="args">the <see cref="BlockArguments"/> to use to read and write to a block</param>
 public override void GetBlock(BlockArguments args)
 {
     if (IsDisposed)
         throw new ObjectDisposedException(GetType().FullName);
     m_stream.GetBlock(this, args);
 }
 public override void GetBlock(BlockArguments args)
 {
     args.SupportsWriting = true;
     m_stream.GetBlock(args);
 }
        public override void GetBlock(BlockArguments args)
        {
            if (args == null)
                throw new ArgumentNullException("args");

            long pos = args.Position;
            if (IsDisposed)
                throw new ObjectDisposedException(GetType().FullName);
            if (pos < 0)
                throw new ArgumentOutOfRangeException("position", "cannot be negative");
            if (pos >= (long)m_blockDataLength * (uint.MaxValue - 1))
                throw new ArgumentOutOfRangeException("position", "position reaches past the end of the file.");

            uint physicalBlockIndex;
            uint indexPosition;

            if (pos <= uint.MaxValue) //64-bit divide is 2 times slower
                indexPosition = ((uint)pos / (uint)m_blockDataLength);
            else
                indexPosition = (uint)((ulong)pos / (ulong)m_blockDataLength); //64-bit signed divide is twice as slow as 64-bit unsigned.

            args.FirstPosition = (long)indexPosition * m_blockDataLength;
            args.Length = m_blockDataLength;

            physicalBlockIndex = m_subFile.DirectBlock + indexPosition;

            Read(physicalBlockIndex, indexPosition);

            args.FirstPointer = m_memory.Address;
            args.SupportsWriting = true;
        }
        /// <summary>
        /// Gets a block for the following Io session.
        /// </summary>
        public void GetBlock(BlockArguments args)
        {
            if (m_disposed)
                throw new ObjectDisposedException("MemoryStream");
            if (args.Position < m_firstValidPosition)
                throw new ArgumentOutOfRangeException("position", "position is before the beginning of the stream");

            args.Length = m_pageSize;
            args.FirstPosition = ((args.Position - m_firstAddressablePosition) & m_invertMask) + m_firstAddressablePosition;
            args.FirstPointer = GetPage(args.Position - m_firstAddressablePosition);

            if (args.FirstPosition < m_firstValidPosition)
            {
                args.FirstPointer += (int)(m_firstValidPosition - args.FirstPosition);
                args.Length -= (int)(m_firstValidPosition - args.FirstPosition);
                args.FirstPosition = m_firstValidPosition;
            }
        }
 /// <summary>
 /// Creates a <see cref="BinaryStream"/> that is at position 0 of the provided stream.
 /// </summary>
 /// <param name="stream">The base stream to use.</param>
 /// <param name="leaveOpen">Determines if the underlying stream will automatically be 
 /// disposed of when this class has it's dispose method called.</param>
 public BinaryStream(ISupportsBinaryStream stream, bool leaveOpen = true)
 {
     m_args = new BlockArguments();
     m_leaveOpen = leaveOpen;
     m_stream = stream;
     FirstPosition = 0;
     Current = null;
     First = null;
     LastRead = null;
     LastWrite = null;
     if (stream.RemainingSupportedIoSessions < 1)
         throw new Exception("Stream has run out of read sessions");
     m_mainIoSession = stream.CreateIoSession();
     //if (stream.RemainingSupportedIoSessions >= 1)
     //    m_secondaryIoSession = stream.CreateIoSession();
 }
            public override void GetBlock(BlockArguments args)
            {
                int blockDataLength = m_blockDataLength;
                long pos = args.Position;
                if (IsDisposed || m_ioSessions.IsDisposed)
                    throw new ObjectDisposedException(GetType().FullName);
                if (pos < 0)
                    throw new ArgumentOutOfRangeException("position", "cannot be negative");
                if (pos >= (long)blockDataLength * (uint.MaxValue - 1))
                    throw new ArgumentOutOfRangeException("position", "position reaches past the end of the file.");

                uint physicalBlockIndex;
                uint indexPosition;

                if (pos <= uint.MaxValue) //64-bit divide is 2 times slower
                    indexPosition = ((uint)pos / (uint)blockDataLength);
                else
                    indexPosition = (uint)((ulong)pos / (ulong)blockDataLength); //64-bit signed divide is twice as slow as 64-bit unsigned.

                args.FirstPosition = (long)indexPosition * blockDataLength;
                args.Length = blockDataLength;

                if (args.IsWriting)
                {
                    //Writing
                    if (m_isReadOnly)
                        throw new Exception("File is read only");
                    bool wasShadowPaged;
                    physicalBlockIndex = m_pager.VirtualToShadowPagePhysical(indexPosition, out wasShadowPaged);

                    if (wasShadowPaged)
                        m_stream.ClearIndexNodeCache(this, m_parser);

                    if (physicalBlockIndex == 0)
                        throw new Exception("Failure to shadow copy the page.");

                    DataIoSession.WriteToExistingBlock(physicalBlockIndex, BlockType.DataBlock, indexPosition);
                    args.FirstPointer = (IntPtr)DataIoSession.Pointer;
                    args.SupportsWriting = true;
                }
                else
                {
                    //Reading
                    physicalBlockIndex = m_parser.VirtualToPhysical(indexPosition);
                    if (physicalBlockIndex <= 0)
                        throw new Exception("Page does not exist");

                    DataIoSession.Read(physicalBlockIndex, BlockType.DataBlock, indexPosition);
                    args.FirstPointer = (IntPtr)DataIoSession.Pointer;
                    args.SupportsWriting = !m_isReadOnly && physicalBlockIndex > m_lastEditedBlock;
                }
            }
예제 #13
0
 /// <summary>
 /// Gets a block for the following Io session.
 /// </summary>
 /// <param name="args">The block request that needs to be fulfilled by this IoSession.</param>
 public abstract void GetBlock(BlockArguments args);
 public override void GetBlock(BlockArguments args)
 {
     args.SupportsWriting = true;
     m_stream.GetBlock(args);
 }
        /// <summary>
        /// Populates the pointer data inside <see cref="args"/> for the desired block as specified in <see cref="args"/>.
        /// This function will block if needing to retrieve data from the disk.
        /// </summary>
        /// <param name="pageLock">The reusable lock information about what this block is currently using.</param>
        /// <param name="args">Contains what block needs to be read and when this function returns, 
        /// it will contain the proper pointer information for this block.</param>
        private void GetBlock(PageReplacementAlgorithm.PageLock pageLock, BlockArguments args)
        {
            pageLock.Clear();
            //Determines where the block is located.
            if (args.Position >= m_lengthOfCommittedData)
            {
                //If the block is in the uncommitted space, it is stored in the 
                //MemoryPoolStreamCore.
                args.SupportsWriting = true;
                m_writeBuffer.GetBlock(args);
            }
            else if (args.Position < m_lengthOfHeader)
            {
                //If the block is in the header, error because this area of the file is not designed to be accessed.
                throw new ArgumentOutOfRangeException("args", "Cannot use this function to modify the file header.");
            }
            else
            {
                //If it is between the file header and uncommitted space, 
                //it is in the committed space, which this space by design is never to be modified. 
                if (args.IsWriting)
                    throw new ArgumentException("Cannot write to committed data space", "args");
                args.SupportsWriting = false;
                args.Length = m_diskBlockSize;
                //rounds to the beginning of the block to be looked up.
                args.FirstPosition = args.Position & ~(long)m_pool.PageMask;

                GetBlockFromCommittedSpace(pageLock, args.FirstPosition, out args.FirstPointer);

                //Make sure the block does not go beyond the end of the uncommitted space.
                if (args.FirstPosition + args.Length > m_lengthOfCommittedData)
                    args.Length = (int)(m_lengthOfCommittedData - args.FirstPosition);
            }
        }
 /// <summary>
 /// Gets a block for the following Io session.
 /// </summary>
 /// <param name="args">The block request that needs to be fulfilled by this IoSession.</param>
 public abstract void GetBlock(BlockArguments args);