public void ReadWriteSequentialWithoutSegmentOverflow() { const int segmentSize = 13; var source = Enumerable.Range(0, 1000).Select(n => unchecked ((byte)n)).ToArray(); var target = new byte[source.Length]; var buffer = new ReadWriteBuffer(segmentSize); for (int i = 0; i < 100; i++) { var rnd = new Random(i); Array.Clear(target, 0, target.Length); int sourcePosition = 0; int targetPosition = 0; int readWriteFactor = i % 3 + 2; while (sourcePosition != source.Length) { var read = rnd.Next(readWriteFactor) == 0; if (read) { var availableBytes = buffer.Read(); if (!availableBytes.IsEmpty) { var availableLen = Math.Min((int)availableBytes.Length, Math.Min(rnd.Next(segmentSize * 3) + 1, target.Length - targetPosition)); var targetSlice = new Span <byte>(target).Slice(targetPosition, availableLen); availableBytes.Slice(0, availableLen).CopyTo(targetSlice); targetPosition += availableLen; buffer.ConfirmRead(availableLen); continue; } } var len = Math.Min(source.Length - sourcePosition, rnd.Next(segmentSize * 3) + 1); while (len != 0) { var memory = buffer.GetMemory(); var currentLen = Math.Min(len, memory.Length); new ReadOnlySpan <byte>(source).Slice(sourcePosition, currentLen).CopyTo(memory.Span.Slice(0, currentLen)); buffer.ConfirmWrite(currentLen); sourcePosition += currentLen; len -= currentLen; } buffer.Flush(); } var lastBlock = buffer.Read(); Assert.Equal(target.Length - targetPosition, lastBlock.Length); lastBlock.CopyTo(new Span <byte>(target, targetPosition, target.Length - targetPosition)); Assert.Equal(source, target); buffer.ConfirmRead((int)lastBlock.Length); } }
public void WriteBlocks() { var source = Enumerable.Range(0, 1000).Select(n => unchecked ((byte)n)).ToArray(); for (int i = 0; i < 10; i++) { var buffer = new ReadWriteBuffer(7); var rnd = new Random(i); var position = 0; while (position < source.Length) { var blockSize = Math.Min(rnd.Next(1, 18), source.Length - position); var memory = buffer.GetMemory(blockSize); new ReadOnlySpan <byte>(source, position, blockSize).CopyTo(memory.Span); buffer.ConfirmWrite(blockSize); position += blockSize; } var empty = buffer.Read(); Assert.True(empty.IsEmpty); buffer.Flush(); var firstPart = buffer.Read(); var array = firstPart.Slice(0, 500).ToArray(); buffer.ConfirmRead(array.Length); Assert.Equal(source.Take(500), array); var secondPart = buffer.Read(); secondPart.CopyTo(array); buffer.ConfirmRead(array.Length); Assert.Equal(source.Skip(500), array); empty = buffer.Read(); Assert.True(empty.IsEmpty); } }
public async ValueTask Flush(bool async, CancellationToken cancellationToken) { if (_currentCompression != CompressionAlgorithm.None) { throw new ClickHouseException(ClickHouseErrorCodes.InternalError, "Internal error. The stream can't be flushed because it's compression is not completed."); } _buffer.Flush(); var readResult = _buffer.Read(); if (readResult.IsEmpty) { return; } foreach (var buffer in readResult) { if (async) { await _stream.WriteAsync(buffer, cancellationToken); } else { _stream.Write(buffer.Span); } } _buffer.ConfirmRead((int)readResult.Length); if (async) { await _stream.FlushAsync(cancellationToken); } else { _stream.Flush(); } }
public void WriteExactThreeBlocks() { var source = Enumerable.Range(0, 7 * 3).Select(n => (byte)n).ToArray(); var buffer = new ReadWriteBuffer(7); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { var block = buffer.GetMemory(7); new Span <byte>(source, j * 7, 7).CopyTo(block.Span); buffer.ConfirmWrite(7); } buffer.Flush(); var result = buffer.Read().ToArray(); Assert.Equal(source, result); buffer.ConfirmRead(result.Length); var empty = buffer.Read(); Assert.True(empty.IsEmpty); } }