public void MultispanFormatterBasics() { var data = new Multispan <byte>(); var formatter = new MultispanFormatter(data, 10, FormattingData.InvariantUtf8); formatter.Append(new string('x', 10)); formatter.Append(new string('x', 8)); formatter.Append(new string('x', 8)); formatter.Append(new string('x', 5)); formatter.Append(new string('x', 5)); data = formatter.Multispan; var bytesWritten = data.TotalItemCount(); Assert.Equal(36, bytesWritten); var array = new byte[bytesWritten]; data.CopyTo(array); foreach (byte b in array) { Assert.Equal((byte)'x', b); } }
public void ReadOnlySpanEnumeration() { ReadOnlySpan <byte> span; { Multispan <byte> collection = ToMultispan("A"); Assert.Equal(1, collection.Count); Position position = Position.First; Assert.True(collection.TryGet(ref position, out span, advance: true)); Assert.True(position.Equals(Position.AfterLast)); Assert.Equal(span[0], (byte)'A'); collection.Dispose(); } { Multispan <byte> collection = ToMultispan("A", "B"); Assert.Equal(2, collection.Count); Position position = Position.First; Assert.True(collection.TryGet(ref position, out span, advance: true)); Assert.Equal(span[0], (byte)'A'); Assert.True(collection.TryGet(ref position, out span, advance: true)); Assert.Equal(span[0], (byte)'B'); Assert.True(position.Equals(Position.AfterLast)); collection.Dispose(); } }
public void BasicsWork() { var ints = new Multispan<int>(); Assert.Equal(0, ints.Count); int index1 = ints.AppendNewSegment(10); Assert.Equal(1, ints.Count); Assert.Equal(0, index1); Span<int> segment1 = ints[index1]; Assert.True(segment1.Length >= 10); int index2 = ints.AppendNewSegment(1000); Assert.Equal(2, ints.Count); Assert.Equal(1, index2); Span<int> segment2 = ints[index2]; Assert.True(segment2.Length >= 1000); var totalSize = segment1.Length + segment2.Length; var computedSize = ints.TotalItemCount(); Assert.Equal(totalSize, computedSize); ints.ResizeSegment(0, 20); ints.ResizeSegment(1, 100); segment1 = ints[0]; segment2 = ints[1]; Assert.True(segment1.Length >= 20); Assert.True(segment2.Length >= 100); ints.Dispose(); Assert.Equal(0, ints.Count); }
public void MultispanFormatterBasics() { var data = new Multispan <byte>(); data.AppendNewSegment(10); data.AppendNewSegment(10); data.AppendNewSegment(10); data.AppendNewSegment(10); var formatter = new SequenceFormatter(data, EncodingData.InvariantUtf8); formatter.Append(new string('x', 10)); formatter.Append(new string('x', 8)); formatter.Append(new string('x', 8)); formatter.Append(new string('x', 5)); formatter.Append(new string('x', 5)); var bytesWritten = formatter.TotalWritten; Assert.Equal(36, bytesWritten); foreach (var slice in data) { for (int i = 0; i < slice.Length; i++) { if (bytesWritten == 0) { return; } Assert.Equal((byte)'x', slice[i]); bytesWritten--; } } }
public void SequenceWorks() { var ms = new Multispan <byte>(); Initialize(ref ms); var values = new byte[] { 1, 2, 7 }; ms[0].Set(values); ms[1].Set(values); ms[2].Set(values); var sum = ms.Do((all) => { int acumulator = 0; foreach (var i in all) { acumulator += i; } return(acumulator); }); Assert.Equal(30, sum); int capturedSum = 0; ms.Do((all) => { foreach (var i in all) { capturedSum += i; } }); Assert.Equal(30, capturedSum); }
public void SpanForeach() { { Multispan <byte> collection = ToMultispan("A"); Assert.Equal(1, collection.Count); foreach (var item in collection) { Assert.Equal(item[0], (byte)'A'); } collection.Dispose(); } { Multispan <byte> collection = ToMultispan("A", "B"); Assert.Equal(2, collection.Count); int itemIndex = 0; foreach (var item in collection) { switch (itemIndex++) { case 0: Assert.Equal(item[0], (byte)'A'); break; case 1: Assert.Equal(item[0], (byte)'B'); break; default: throw new Exception("expected two items in the collection"); } } collection.Dispose(); } }
public MultispanFormatter(Multispan<byte> buffer, int segmentSize, FormattingData formattingData) { _formattingData = formattingData; _segmentSize = segmentSize; _buffer = buffer; int index = _buffer.AppendNewSegment(_segmentSize); // TODO: is this the right thing to do? Should Multispan be resilient to empty segment list? _lastFull = _buffer.Last; _buffer.ResizeSegment(index, 0); }
public MultispanFormatter(Multispan <byte> buffer, int segmentSize, EncodingData encoding) { _encoding = encoding; _segmentSize = segmentSize; _buffer = buffer; int index = _buffer.AppendNewSegment(_segmentSize); // TODO: is this the right thing to do? Should Multispan be resilient to empty segment list? _lastFull = _buffer.Last; _buffer.ResizeSegment(index, 0); }
public void Slicing(int sliceIndex, int expectedTotalItems) { var ms = new Multispan<byte>(); Initialize(ref ms); var slice = ms.Slice(sliceIndex); Assert.Equal(expectedTotalItems, slice.TotalItemCount()); ms.Dispose(); }
public static uint ParseUInt32(this Multispan <byte> bytes) { int consumed; uint value; if (!bytes.TryParseUInt32(EncodingData.InvariantUtf8, out value, out consumed)) { throw new ArgumentException(); } return(value); }
private static void Initialize(ref Multispan<byte> ms) { Assert.Equal(0, ms.TotalItemCount()); ms.AppendNewSegment(10); ms.ResizeSegment(0, 10); ms.AppendNewSegment(20); ms.ResizeSegment(1, 20); ms.AppendNewSegment(30); ms.ResizeSegment(2, 30); Assert.Equal(60, ms.TotalItemCount()); }
public void Slicing(int sliceIndex, int expectedTotalItems) { var ms = new Multispan <byte>(); Initialize(ref ms); var slice = ms.Slice(sliceIndex); Assert.Equal(expectedTotalItems, slice.TotalItemCount()); ms.Dispose(); }
private static void Initialize(ref Multispan <byte> ms) { Assert.Equal(0, ms.TotalItemCount()); ms.AppendNewSegment(10); ms.ResizeSegment(0, 10); ms.AppendNewSegment(20); ms.ResizeSegment(1, 20); ms.AppendNewSegment(30); ms.ResizeSegment(2, 30); Assert.Equal(60, ms.TotalItemCount()); }
public static Multispan <byte> ToMultispan(params string[] sections) { var result = new Multispan <byte>(); for (int i = 0; i < sections.Length; i++) { var bytes = new Utf8String(sections[i]).Bytes.CreateArray(); result.AppendNewSegment(bytes.Length); result.Last.Set(bytes); result.ResizeSegment(i, bytes.Length); } return(result); }
public static Multispan <byte> ToMultispan(params string[] sections) { var result = new Multispan <byte>(); for (int i = 0; i < sections.Length; i++) { var bytes = Encoding.UTF8.GetBytes(sections[i]); result.AppendNewSegment(bytes.Length); result.Last.Set(bytes); result.ResizeSegment(i, bytes.Length); } return(result); }
/// <summary> /// Removes items from the instance. /// </summary> /// <param name="itemCount">Number of items to remove</param> /// <returns></returns> /// <remarks>DO NOT dispose the original and then slice. Either the original or the sliced instance can be disposed, but not both.</remarks> public Multispan <T> Slice(int itemCount) { var result = new Multispan <T>(); var first = GetAt(0); // if the only thing needing slicing is the head if (first.Count > itemCount) { result._head = _head.Slice(itemCount); EnsureTailCapacity(ref result, _count - 1); result._count = _count; Array.Copy(_tail, result._tail, _count - 1); return(result); } // head will be removed; this computes how many tail segments need to be removed // and how many items from the first segment that is not removed var itemsLeftToRemove = itemCount - first.Count; int tailSegmentsToRemove = 1; // one is moved to the head for (int tailIndex = 0; tailIndex < _count - 1; tailIndex++) { if (itemsLeftToRemove == 0) { break; } var segment = _tail[tailIndex]; if (segment.Count >= itemsLeftToRemove) { break; } else { tailSegmentsToRemove++; itemsLeftToRemove -= segment.Count; } } result._head = _tail[tailSegmentsToRemove - 1].Slice(itemsLeftToRemove); result._count = _count - tailSegmentsToRemove; if (result._count == 1) { return(result); // we don't need tail; this multispan has just head } EnsureTailCapacity(ref result, result._count - 1); Array.Copy(_tail, tailSegmentsToRemove, result._tail, 0, result._count - 1); return(result); }
public void SingleSpanMultispanBasics() { var ints = new Multispan<int>(); Assert.Equal(0, ints.Count); int index1 = ints.AppendNewSegment(10); Assert.Equal(1, ints.Count); Assert.Equal(0, index1); Span<int> segment1 = ints[index1]; Assert.True(segment1.Length >= 10); var sliced = ints.Slice(1); ints.Dispose(); Assert.Equal(0, ints.Count); }
private static void EnsureTailCapacity <T>(ref Multispan <T> ms, int count) { int desired = (ms._tail == null) ? 4 : ms._tail.Length * 2; while (desired < count) { desired = desired * 2; } var newSegments = ArrayPool <ArraySegment <T> > .Shared.Rent(desired); if (ms._tail != null) { ms._tail.CopyTo(newSegments, 0); ArrayPool <ArraySegment <T> > .Shared.Return(ms._tail); } ms._tail = newSegments; }
public void SingleSpanMultispanBasics() { var ints = new Multispan <int>(); Assert.Equal(0, ints.Count); int index1 = ints.AppendNewSegment(10); Assert.Equal(1, ints.Count); Assert.Equal(0, index1); Span <int> segment1 = ints[index1]; Assert.True(segment1.Length >= 10); var sliced = ints.Slice(1); ints.Dispose(); Assert.Equal(0, ints.Count); }
public void MultispanFormatterBasics() { var data = new Multispan<byte>(); var formatter = new MultispanFormatter(data, 10, FormattingData.InvariantUtf8); formatter.Append(new string('x', 10)); formatter.Append(new string('x', 8)); formatter.Append(new string('x', 8)); formatter.Append(new string('x', 5)); formatter.Append(new string('x', 5)); data = formatter.Multispan; var bytesWritten = data.TotalItemCount(); Assert.Equal(36, bytesWritten); var array = new byte[bytesWritten]; data.CopyTo(array); foreach(byte b in array) { Assert.Equal((byte)'x', b); } }
public void SequenceWorks() { var ms = new Multispan<byte>(); Initialize(ref ms); var values = new byte[] { 1, 2, 7 }; ms[0].Set(values); ms[1].Set(values); ms[2].Set(values); var sum = ms.Do((all) => { int acumulator = 0; foreach (var i in all) acumulator += i; return acumulator; }); Assert.Equal(30, sum); int capturedSum = 0; ms.Do((all) => { foreach (var i in all) capturedSum += i; }); Assert.Equal(30, capturedSum); }
public void BasicsWork() { var ints = new Multispan <int>(); Assert.Equal(0, ints.Count); int index1 = ints.AppendNewSegment(10); Assert.Equal(1, ints.Count); Assert.Equal(0, index1); Span <int> segment1 = ints[index1]; Assert.True(segment1.Length >= 10); int index2 = ints.AppendNewSegment(1000); Assert.Equal(2, ints.Count); Assert.Equal(1, index2); Span <int> segment2 = ints[index2]; Assert.True(segment2.Length >= 1000); var totalSize = segment1.Length + segment2.Length; var computedSize = ints.TotalItemCount(); Assert.Equal(totalSize, computedSize); ints.ResizeSegment(0, 20); ints.ResizeSegment(1, 100); segment1 = ints[0]; segment2 = ints[1]; Assert.True(segment1.Length >= 20); Assert.True(segment2.Length >= 100); ints.Dispose(); Assert.Equal(0, ints.Count); }
public void MultispanEnumeration() { { Multispan <byte> collection = ToMultispan("A"); Assert.Equal(1, collection.Count); Position position = Position.BeforeFirst; var item = collection.TryGetItem(ref position); Assert.True(position.IsEnd); Assert.Equal(item[0], (byte)'A'); collection.Dispose(); } { Multispan <byte> collection = ToMultispan("A", "B"); Assert.Equal(2, collection.Count); Position position = Position.BeforeFirst; var item1 = collection.TryGetItem(ref position); Assert.True(position.IsValid); Assert.Equal(item1[0], (byte)'A'); var item2 = collection.TryGetItem(ref position); Assert.Equal(item2[0], (byte)'B'); Assert.True(position.IsEnd); collection.Dispose(); } }
internal Enumerator(Multispan <T> buffer) { _buffer = buffer; _index = -1; }
public static Multispan<byte> ToMultispan(params string[] sections) { var result = new Multispan<byte>(); for (int i = 0; i < sections.Length; i++) { var bytes = Encoding.UTF8.GetBytes(sections[i]); result.AppendNewSegment(bytes.Length); result.Last.Set(bytes); result.ResizeSegment(i, bytes.Length); } return result; }