Пример #1
0
        public void ExpandingWrite()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            //start within the source stream, then write past the end of it
            tran.Position = 240;
            writer.Write(Enumerable.Repeat((byte)99, 30).ToArray());
            Assert.AreEqual(270L, tran.Position);
            Assert.AreEqual(270L, tran.Length);

            //seek past the end of the source stream, then start writing
            tran.Position = 300;
            writer.Write(Enumerable.Repeat((byte)77, 30).ToArray());
            Assert.AreEqual(330L, tran.Position);
            Assert.AreEqual(330L, tran.Length);

            //read beyond the source stream but between patches
            tran.Position = 270;
            var data = reader.ReadBytes(30);

            Assert.AreEqual(300L, tran.Position);

            for (int i = 0; i < 30; i++)
            {
                Assert.AreEqual(byte.MinValue, data[i]);
            }

            //read beyond the source stream including patches
            tran.Position = 0;
            data          = reader.ReadBytes(330);
            Assert.AreEqual(330L, tran.Position);

            for (byte i = 0; i < 240; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (int i = 240; i < 270; i++)
            {
                Assert.AreEqual((byte)99, data[i]);
            }
            for (int i = 270; i < 300; i++)
            {
                Assert.AreEqual(byte.MinValue, data[i]);
            }
            for (int i = 300; i < 330; i++)
            {
                Assert.AreEqual((byte)77, data[i]);
            }
        }
Пример #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        public Storage(Stream stream, Stream transactionLogStream)
        {
            this.Statistics = new StorageStatistics(this);

            if (stream.Length == 0)
            {
                CreateStorage(stream);
            }

            this.transactionStream = transactionLogStream != null ? new TransactionStream(stream, transactionLogStream, blockSize) : null;
            this.MasterStream      = new MasterStream(transactionStream != null ? transactionStream : stream, false);

            OpenStorage();
        }
Пример #3
0
        public void Shrinking()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            Assert.AreEqual(byte.MaxValue, tran.Length);

            tran.Position = 0;
            var data = reader.ReadBytes(original.Length);

            Assert.AreEqual(byte.MaxValue, data.Length);

            for (byte i = 0; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.SetLength(100);
            Assert.AreEqual(100L, tran.Length);

            tran.Position = 0;
            data          = reader.ReadBytes(original.Length);
            Assert.AreEqual(100, data.Length);

            for (byte i = 0; i < 100; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.Position = 200;
            data          = reader.ReadBytes(50);
            Assert.AreEqual(0, data.Length);
            Assert.AreEqual(100L, tran.Length);
        }
Пример #4
0
        public virtual Response <T> PackTransactionStreamResponse <T>(RequestContext context, T response)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long toStartFrom = context.lastAppliedTransaction() + 1;
            long toStartFrom = context.LastAppliedTransaction() + 1;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long toEndAt = transactionIdStore.getLastCommittedTransactionId();
            long toEndAt = _transactionIdStore.LastCommittedTransactionId;
            TransactionStream transactions = visitor =>
            {
                // Check so that it's even worth thinking about extracting any transactions at all
                if (toStartFrom > BASE_TX_ID && toStartFrom <= toEndAt)
                {
                    ExtractTransactions(toStartFrom, FilterVisitor(visitor, toEndAt));
                }
            };

            return(new TransactionStreamResponse <T>(response, StoreId.get(), transactions, Org.Neo4j.com.ResourceReleaser_Fields.NoOp));
        }
Пример #5
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public <PAYLOAD> Response<PAYLOAD> deserializeResponse(org.jboss.netty.handler.queue.BlockingReadHandler<org.jboss.netty.buffer.ChannelBuffer> reader, ByteBuffer input, long timeout, Deserializer<PAYLOAD> payloadDeserializer, ResourceReleaser channelReleaser, final org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader<org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel> entryReader) throws java.io.IOException
//JAVA TO C# CONVERTER WARNING: 'final' parameters are ignored unless the option to convert to C# 7.2 'in' parameters is selected:
        public virtual Response <PAYLOAD> DeserializeResponse <PAYLOAD>(BlockingReadHandler <ChannelBuffer> reader, ByteBuffer input, long timeout, Deserializer <PAYLOAD> payloadDeserializer, ResourceReleaser channelReleaser, LogEntryReader <ReadableClosablePositionAwareChannel> entryReader)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final DechunkingChannelBuffer dechunkingBuffer = new DechunkingChannelBuffer(reader, timeout, internalProtocolVersion, applicationProtocolVersion);
            DechunkingChannelBuffer dechunkingBuffer = new DechunkingChannelBuffer(reader, timeout, _internalProtocolVersion, _applicationProtocolVersion);

            PAYLOAD response = payloadDeserializer.Read(dechunkingBuffer, input);
            StoreId storeId  = ReadStoreId(dechunkingBuffer, input);

            // Response type is what previously was a byte saying how many data sources there were in the
            // coming transaction stream response. For backwards compatibility we keep it as a byte and we introduce
            // the transaction obligation response type as -1
            sbyte responseType = dechunkingBuffer.ReadByte();

            if (responseType == TransactionObligationResponse.RESPONSE_TYPE)
            {
                // It is a transaction obligation response
                long obligationTxId = dechunkingBuffer.ReadLong();
                return(new TransactionObligationResponse <PAYLOAD>(response, storeId, obligationTxId, channelReleaser));
            }

            // It's a transaction stream in this response
            TransactionStream transactions = visitor =>
            {
                NetworkReadableClosableChannel channel = new NetworkReadableClosableChannel(dechunkingBuffer);

                using (PhysicalTransactionCursor <ReadableClosablePositionAwareChannel> cursor = new PhysicalTransactionCursor <ReadableClosablePositionAwareChannel>(channel, entryReader))
                {
                    while (cursor.next() && !visitor.visit(cursor.get()))
                    {
                    }
                }
            };

            return(new TransactionStreamResponse <PAYLOAD>(response, storeId, transactions, channelReleaser));
        }
Пример #6
0
        public override Response <T> PackTransactionStreamResponse <T>(RequestContext context, T response)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final String packerIdentifier = Thread.currentThread().getName();
            string packerIdentifier = Thread.CurrentThread.Name;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long toStartFrom = mandatoryStartTransactionId;
            long toStartFrom = _mandatoryStartTransactionId;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long toEndAt = transactionIdStore.getLastCommittedTransactionId();
            long toEndAt = _transactionIdStore.LastCommittedTransactionId;
            TransactionStream transactions = visitor =>
            {
                // Check so that it's even worth thinking about extracting any transactions at all
                if (toStartFrom > BASE_TX_ID && toStartFrom <= toEndAt)
                {
                    _monitor.startStreamingTransactions(toStartFrom, packerIdentifier);
                    ExtractTransactions(toStartFrom, FilterVisitor(visitor, toEndAt));
                    _monitor.finishStreamingTransactions(toEndAt, packerIdentifier);
                }
            };

            return(new TransactionStreamResponse <T>(response, StoreId.get(), transactions, Org.Neo4j.com.ResourceReleaser_Fields.NoOp));
        }
Пример #7
0
 public TransactionStreamResponse(T response, StoreId storeId, TransactionStream transactions, ResourceReleaser releaser) : base(response, storeId, releaser)
 {
     this._transactions = transactions;
 }
Пример #8
0
        public void AlignedRead()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            var data = reader.ReadBytes(original.Length);

            for (byte i = 0; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.Position = 5;
            writer.Write(new byte[] { 9, 8, 7, 6, 5 });

            Assert.AreEqual(255L, tran.Length);
            Assert.AreEqual(10L, tran.Position);

            //aligned with a patch on both sides (same patch)
            tran.Position = 5;
            data          = reader.ReadBytes(5);
            Assert.AreEqual(5 + 5L, tran.Position);

            for (byte i = 0; i < 5; i++)
            {
                Assert.AreEqual((byte)(10 - (i + 1)), data[i]);
            }

            //aligned on the left
            tran.Position = 5;
            data          = reader.ReadBytes(10);
            Assert.AreEqual(5 + 10L, tran.Position);

            for (byte i = 0; i < 5; i++)
            {
                Assert.AreEqual((byte)(10 - (i + 1)), data[i]);
            }
            for (byte i = 5; i < 10; i++)
            {
                Assert.AreEqual((byte)(i + 5), data[i]);
            }

            //aligned on the right
            tran.Position = 0;
            data          = reader.ReadBytes(10);
            Assert.AreEqual(10L, tran.Position);

            for (byte i = 0; i < 5; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (byte i = 5; i < 10; i++)
            {
                Assert.AreEqual((byte)(10 - (i - 4)), data[i]);
            }

            tran.Position = 20;
            writer.Write(new byte[] { 24, 23, 22, 21, 20 });

            Assert.AreEqual(255L, tran.Length);
            Assert.AreEqual(25L, tran.Position);

            //aligned with a different patch on each side
            tran.Position = 5;
            data          = reader.ReadBytes(20);
            Assert.AreEqual(5 + 20L, tran.Position);

            for (byte i = 0; i < 5; i++)
            {
                Assert.AreEqual((byte)(10 - (i + 1)), data[i]);
            }
            for (byte i = 5; i < 15; i++)
            {
                Assert.AreEqual((byte)(i + 5), data[i]);
            }
            for (byte i = 15; i < 20; i++)
            {
                Assert.AreEqual((byte)(25 - (i - 14)), data[i]);
            }
        }
Пример #9
0
        public void ExpandingWrite2()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            // try to read past the end without expanding
            tran.Position = 200;
            var data = reader.ReadBytes(100);

            Assert.AreEqual(55, data.Length);
            Assert.AreEqual(255L, tran.Position);

            for (int i = 0; i < 55; i++)
            {
                Assert.AreEqual((byte)(200 + i), data[i]);
            }

            //seek past the end of the source stream, then start writing
            tran.Position = 300;
            writer.Write(Enumerable.Repeat((byte)99, 50).ToArray());
            Assert.AreEqual(350L, tran.Position);
            Assert.AreEqual(350L, tran.Length);

            // try to read past the end again
            tran.Position = 200;
            data          = reader.ReadBytes(100);
            Assert.AreEqual(100, data.Length);
            Assert.AreEqual(300L, tran.Position);

            for (int i = 0; i < 55; i++)
            {
                Assert.AreEqual((byte)(200 + i), data[i]);
            }
            for (int i = 55; i < 100; i++)
            {
                Assert.AreEqual(byte.MinValue, data[i]);
            }

            // start in virtual space, then try to read past the virtual end
            tran.Position = 275;
            data          = reader.ReadBytes(100);
            Assert.AreEqual(75, data.Length);
            Assert.AreEqual(350L, tran.Position);

            for (int i = 0; i < 25; i++)
            {
                Assert.AreEqual(byte.MinValue, data[i]);
            }
            for (int i = 25; i < 75; i++)
            {
                Assert.AreEqual((byte)99, data[i]);
            }
        }
Пример #10
0
        public void NonAlignedWrite()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            //separate patch
            tran.Position = 10;
            writer.Write(Enumerable.Repeat((byte)8, 10).ToArray());
            Assert.AreEqual(10 + 10L, tran.Position);

            tran.Position = 10;
            var data = reader.ReadBytes(10);

            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)8, data[i]);
            }

            //write completely within the patch
            tran.Position = 12;
            writer.Write(Enumerable.Repeat((byte)0, 6).ToArray());
            Assert.AreEqual(12 + 6L, tran.Position);

            tran.Position = 10;
            data          = reader.ReadBytes(10);
            for (byte i = 0; i < 2; i++)
            {
                Assert.AreEqual((byte)8, data[i]);
            }
            for (byte i = 2; i < 8; i++)
            {
                Assert.AreEqual((byte)0, data[i]);
            }
            for (byte i = 8; i < 10; i++)
            {
                Assert.AreEqual((byte)8, data[i]);
            }

            //first patch
            tran.Position = 40;
            writer.Write(Enumerable.Repeat((byte)1, 10).ToArray());
            Assert.AreEqual(40 + 10L, tran.Position);

            tran.Position = 40;
            data          = reader.ReadBytes(10);
            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)1, data[i]);
            }

            //second patch
            tran.Position = 50;
            writer.Write(Enumerable.Repeat((byte)2, 10).ToArray());
            Assert.AreEqual(50 + 10L, tran.Position);

            tran.Position = 40;
            data          = reader.ReadBytes(20);
            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)1, data[i]);
            }
            for (byte i = 10; i < 20; i++)
            {
                Assert.AreEqual((byte)2, data[i]);
            }

            //write into the first patch
            tran.Position = 35;
            writer.Write(Enumerable.Repeat((byte)3, 10).ToArray());
            Assert.AreEqual(35 + 10L, tran.Position);

            tran.Position = 35;
            data          = reader.ReadBytes(25);
            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)3, data[i]);
            }
            for (byte i = 10; i < 15; i++)
            {
                Assert.AreEqual((byte)1, data[i]);
            }
            for (byte i = 15; i < 25; i++)
            {
                Assert.AreEqual((byte)2, data[i]);
            }

            //write out of the second patch
            tran.Position = 55;
            writer.Write(Enumerable.Repeat((byte)4, 10).ToArray());
            Assert.AreEqual(55 + 10L, tran.Position);

            tran.Position = 35;
            data          = reader.ReadBytes(30);
            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)3, data[i]);
            }
            for (byte i = 10; i < 15; i++)
            {
                Assert.AreEqual((byte)1, data[i]);
            }
            for (byte i = 15; i < 20; i++)
            {
                Assert.AreEqual((byte)2, data[i]);
            }
            for (byte i = 20; i < 30; i++)
            {
                Assert.AreEqual((byte)4, data[i]);
            }

            //write over the end of one patch and start of another
            tran.Position = 45;
            writer.Write(Enumerable.Repeat((byte)99, 10).ToArray());
            Assert.AreEqual(45 + 10L, tran.Position);

            tran.Position = 35;
            data          = reader.ReadBytes(30);
            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)3, data[i]);
            }
            for (byte i = 10; i < 20; i++)
            {
                Assert.AreEqual((byte)99, data[i]);
            }
            for (byte i = 20; i < 30; i++)
            {
                Assert.AreEqual((byte)4, data[i]);
            }

            Assert.AreEqual(255L, tran.Length);
        }
Пример #11
0
        public void AlignedWrite()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            //first patch
            tran.Position = 30;
            writer.Write(Enumerable.Repeat((byte)55, 10).ToArray());
            Assert.AreEqual(30 + 10L, tran.Position);

            tran.Position = 30;
            var data = reader.ReadBytes(10);

            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)55, data[i]);
            }

            //second patch
            tran.Position = 50;
            writer.Write(Enumerable.Repeat((byte)99, 10).ToArray());
            Assert.AreEqual(50 + 10L, tran.Position);

            tran.Position = 50;
            data          = reader.ReadBytes(10);
            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)99, data[i]);
            }

            //write over the same bytes as the first patch
            tran.Position = 30;
            writer.Write(Enumerable.Repeat((byte)5, 10).ToArray());

            tran.Position = 30;
            data          = reader.ReadBytes(10);
            for (byte i = 0; i < 10; i++)
            {
                Assert.AreEqual((byte)5, data[i]);
            }

            //write from the start of the first patch to the end of the second patch
            tran.Position = 30;
            writer.Write(Enumerable.Repeat((byte)42, 30).ToArray());

            tran.Position = 30;
            data          = reader.ReadBytes(30);
            for (byte i = 0; i < 30; i++)
            {
                Assert.AreEqual((byte)42, data[i]);
            }

            Assert.AreEqual(255L, tran.Length);
        }
Пример #12
0
        public void ContainedWrite()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            tran.Position = 40;
            writer.Write(Enumerable.Repeat((byte)99, 20).ToArray());
            Assert.AreEqual(40 + 20L, tran.Position);

            tran.Position = 0;
            var data = reader.ReadBytes(original.Length);

            for (byte i = 0; i < 40; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (byte i = 40; i < 60; i++)
            {
                Assert.AreEqual((byte)99, data[i]);
            }
            for (byte i = 60; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.Position = 30;
            writer.Write(Enumerable.Repeat((byte)77, 40).ToArray());
            Assert.AreEqual(30 + 40L, tran.Position);

            tran.Position = 0;
            data          = reader.ReadBytes(original.Length);
            for (byte i = 0; i < 30; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (byte i = 30; i < 70; i++)
            {
                Assert.AreEqual((byte)77, data[i]);
            }
            for (byte i = 70; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.Position = 0;
            writer.Write(new byte[original.Length]);
            Assert.AreEqual(original.Length, tran.Position);

            tran.Position = 0;
            data          = reader.ReadBytes(original.Length);
            for (byte i = byte.MinValue; i < byte.MaxValue; i++)
            {
                Assert.AreEqual(byte.MinValue, data[i]);
            }

            Assert.AreEqual(255L, tran.Length);
        }
Пример #13
0
        public void NonAlignedRead()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            var data = reader.ReadBytes(original.Length);

            for (byte i = 0; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.Position = 5;
            writer.Write(new byte[] { 9, 8, 7, 6, 5 });

            Assert.AreEqual(255L, tran.Length);
            Assert.AreEqual(10L, tran.Position);

            //starts and ends within the same patch
            tran.Position = 6;
            data          = reader.ReadBytes(3);
            Assert.AreEqual(6 + 3L, tran.Position);

            for (byte i = 0; i < 3; i++)
            {
                Assert.AreEqual((byte)(8 - i), data[i]);
            }

            //starts inside a patch
            tran.Position = 7;
            data          = reader.ReadBytes(8);
            Assert.AreEqual(7 + 8L, tran.Position);

            for (byte i = 0; i < 3; i++)
            {
                Assert.AreEqual((byte)(10 - (i + 3)), data[i]);
            }
            for (byte i = 3; i < 8; i++)
            {
                Assert.AreEqual((byte)(i + 7), data[i]);
            }

            //ends inside a patch
            tran.Position = 0;
            data          = reader.ReadBytes(8);
            Assert.AreEqual(8L, tran.Position);

            for (byte i = 0; i < 5; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (byte i = 5; i < 8; i++)
            {
                Assert.AreEqual((byte)(10 - (i - 4)), data[i]);
            }

            tran.Position = 20;
            writer.Write(new byte[] { 24, 23, 22, 21, 20 });

            Assert.AreEqual(255L, tran.Length);
            Assert.AreEqual(25L, tran.Position);

            //starts in one patch and ends in another
            tran.Position = 7;
            data          = reader.ReadBytes(16);
            Assert.AreEqual(7 + 16L, tran.Position);

            for (byte i = 0; i < 3; i++)
            {
                Assert.AreEqual((byte)(10 - (i + 3)), data[i]);
            }
            for (byte i = 3; i < 13; i++)
            {
                Assert.AreEqual((byte)(i + 7), data[i]);
            }
            for (byte i = 13; i < 16; i++)
            {
                Assert.AreEqual((byte)(25 - (i - 12)), data[i]);
            }
        }
Пример #14
0
        public void ContainedRead()
        {
            var original = new byte[byte.MaxValue];

            for (byte i = 0; i < original.Length; i++)
            {
                original[i] = i;
            }

            var ms   = new MemoryStream(original);
            var tran = new TransactionStream(ms);

            var reader = new EndianReader(tran);
            var writer = new EndianWriter(tran);

            var data = reader.ReadBytes(original.Length);

            Assert.AreEqual(original.Length, tran.Position);

            for (byte i = 0; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.Position = 5;
            writer.Write(new byte[] { 9, 8, 7, 6, 5 });

            Assert.AreEqual(255L, tran.Length);
            Assert.AreEqual(10L, tran.Position);

            //contains a single patch in the middle
            tran.Position = 0;
            data          = reader.ReadBytes(original.Length);
            Assert.AreEqual(original.Length, tran.Position);

            for (byte i = 0; i < 5; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (byte i = 5; i < 10; i++)
            {
                Assert.AreEqual((byte)(10 - (i - 4)), data[i]);
            }
            for (byte i = 10; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }

            tran.Position = 20;
            writer.Write(new byte[] { 24, 23, 22, 21, 20 });

            Assert.AreEqual(255L, tran.Length);
            Assert.AreEqual(25L, tran.Position);

            //contains multiple patches in the middle
            tran.Position = 0;
            data          = reader.ReadBytes(original.Length);
            Assert.AreEqual(original.Length, tran.Position);

            for (byte i = 0; i < 5; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (byte i = 5; i < 10; i++)
            {
                Assert.AreEqual((byte)(10 - (i - 4)), data[i]);
            }
            for (byte i = 10; i < 20; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
            for (byte i = 20; i < 25; i++)
            {
                Assert.AreEqual((byte)(25 - (i - 19)), data[i]);
            }
            for (byte i = 25; i < original.Length; i++)
            {
                Assert.AreEqual(i, data[i]);
            }
        }