diff --git a/src/DotNext.IO/Buffers/BufferWriter.cs b/src/DotNext.IO/Buffers/BufferWriter.cs index e6eee57f7..3ea22c8a5 100644 --- a/src/DotNext.IO/Buffers/BufferWriter.cs +++ b/src/DotNext.IO/Buffers/BufferWriter.cs @@ -133,7 +133,7 @@ public static long Format(this IBufferWriter writer, T value, in Encodi where T : notnull, ISpanFormattable { // attempt to allocate char buffer on the stack - Span charBuffer = stackalloc char[MemoryRental.StackallocThreshold]; + Span charBuffer = stackalloc char[SpanOwner.StackallocThreshold]; if (!TryFormat(writer, value, charBuffer, in context, lengthFormat, format, provider, out var bytesWritten)) { for (var charBufferSize = charBuffer.Length << 1; ; charBufferSize = charBufferSize <= MaxBufferSize ? charBufferSize * 2 : throw new InsufficientMemoryException()) diff --git a/src/DotNext.IO/Buffers/EncodingInterpolatedStringHandler.cs b/src/DotNext.IO/Buffers/EncodingInterpolatedStringHandler.cs index c64322106..fe444144a 100644 --- a/src/DotNext.IO/Buffers/EncodingInterpolatedStringHandler.cs +++ b/src/DotNext.IO/Buffers/EncodingInterpolatedStringHandler.cs @@ -109,7 +109,7 @@ public void AppendFormatted(T value, string? format = null) case ISpanFormattable: for (bufferSize = 0; ; bufferSize = bufferSize <= MaxBufferSize ? bufferSize * 2 : throw new InsufficientMemoryException()) { - using var tempBuffer = bufferSize <= charBuffer.Length ? charBuffer : new MemoryRental(bufferSize, false); + using var tempBuffer = bufferSize <= charBuffer.Length ? charBuffer : new SpanOwner(bufferSize, false); // constrained call avoiding boxing for value types if (((ISpanFormattable)value).TryFormat(tempBuffer.Span, out charsWritten, format, provider)) @@ -140,7 +140,7 @@ private void AppendFormatted(ReadOnlySpan value, int alignment, bool leftA return; } - using var tempBuffer = alignment <= charBuffer.Length ? charBuffer.Slice(0, alignment) : new MemoryRental(alignment); + using var tempBuffer = alignment <= charBuffer.Length ? charBuffer.Slice(0, alignment) : new SpanOwner(alignment); var span = tempBuffer.Span; var filler = leftAlign ? span.Slice(value.Length, padding) @@ -230,7 +230,7 @@ public void AppendFormatted(T value, int alignment, string? format = null) case ISpanFormattable: for (bufferSize = alignment; ; bufferSize = bufferSize <= MaxBufferSize ? bufferSize * 2 : throw new InsufficientMemoryException()) { - using var tempBuffer = bufferSize <= charBuffer.Length ? charBuffer : new MemoryRental(bufferSize, false); + using var tempBuffer = bufferSize <= charBuffer.Length ? charBuffer : new SpanOwner(bufferSize, false); var span = tempBuffer.Span; if (((ISpanFormattable)value).TryFormat(span, out charsWritten, format, provider)) diff --git a/src/DotNext.IO/IO/DecodingTextReader.cs b/src/DotNext.IO/IO/DecodingTextReader.cs index 6682f6217..c3531d600 100644 --- a/src/DotNext.IO/IO/DecodingTextReader.cs +++ b/src/DotNext.IO/IO/DecodingTextReader.cs @@ -89,7 +89,7 @@ public override int Read(Span buffer) var newLineBufferPosition = 0; var newLine = Environment.NewLine.AsSpan(); - var result = new BufferWriterSlim(stackalloc char[MemoryRental.StackallocThreshold], allocator); + var result = new BufferWriterSlim(stackalloc char[SpanOwner.StackallocThreshold], allocator); try { do diff --git a/src/DotNext.IO/IO/IAsyncBinaryWriter.cs b/src/DotNext.IO/IO/IAsyncBinaryWriter.cs index 46fa7d9a1..1b89549d1 100644 --- a/src/DotNext.IO/IO/IAsyncBinaryWriter.cs +++ b/src/DotNext.IO/IO/IAsyncBinaryWriter.cs @@ -211,7 +211,7 @@ internal static async ValueTask FormatAsync(IAsyncBinaryWriter writer, T where T : notnull, IUtf8SpanFormattable { const int maxBufferSize = int.MaxValue / 2; - for (var bufferSize = MemoryRental.StackallocThreshold; ; bufferSize = bufferSize <= maxBufferSize ? bufferSize << 1 : throw new InternalBufferOverflowException()) + for (var bufferSize = SpanOwner.StackallocThreshold; ; bufferSize = bufferSize <= maxBufferSize ? bufferSize << 1 : throw new InternalBufferOverflowException()) { using var buffer = Memory.AllocateAtLeast(bufferSize); diff --git a/src/DotNext.IO/IO/Pipelines/PipeExtensions.Readers.cs b/src/DotNext.IO/IO/Pipelines/PipeExtensions.Readers.cs index 16ddc7e77..9f79680bd 100644 --- a/src/DotNext.IO/IO/Pipelines/PipeExtensions.Readers.cs +++ b/src/DotNext.IO/IO/Pipelines/PipeExtensions.Readers.cs @@ -264,9 +264,9 @@ static TResult Parse(PipeReader reader, TArg arg, ReadOnlySpanFunc.StackallocThreshold + using var destination = (uint)length <= (uint)SpanOwner.StackallocThreshold ? stackalloc byte[length] - : new MemoryRental(length); + : new SpanOwner(length); source.CopyTo(destination.Span, out length); return parser(destination.Span.Slice(0, length), arg); diff --git a/src/DotNext.IO/IO/StreamExtensions.Writers.cs b/src/DotNext.IO/IO/StreamExtensions.Writers.cs index e1cf23d5e..8abb3280a 100644 --- a/src/DotNext.IO/IO/StreamExtensions.Writers.cs +++ b/src/DotNext.IO/IO/StreamExtensions.Writers.cs @@ -160,7 +160,7 @@ public static async ValueTask FormatAsync(this Stream stream, T value, const int maxBufferSize = int.MaxValue / 2; - for (var charBufferSize = MemoryRental.StackallocThreshold; ; charBufferSize = charBufferSize <= maxBufferSize ? charBufferSize * 2 : throw new InsufficientMemoryException()) + for (var charBufferSize = SpanOwner.StackallocThreshold; ; charBufferSize = charBufferSize <= maxBufferSize ? charBufferSize * 2 : throw new InsufficientMemoryException()) { using var owner = allocator.AllocateAtLeast(charBufferSize); diff --git a/src/DotNext.Tests/Buffers/MemoryRentalTests.cs b/src/DotNext.Tests/Buffers/SpanOwnerTests.cs similarity index 78% rename from src/DotNext.Tests/Buffers/MemoryRentalTests.cs rename to src/DotNext.Tests/Buffers/SpanOwnerTests.cs index 2176673ec..a71a8f025 100644 --- a/src/DotNext.Tests/Buffers/MemoryRentalTests.cs +++ b/src/DotNext.Tests/Buffers/SpanOwnerTests.cs @@ -3,12 +3,12 @@ namespace DotNext.Buffers; -public sealed class MemoryRentalTests : Test +public sealed class SpanOwnerTests : Test { [Fact] public static unsafe void StackAllocationTest() { - using MemoryRental vector = stackalloc int[4]; + using SpanOwner vector = stackalloc int[4]; False(vector.IsEmpty); Equal(4, vector.Length); Equal(4, vector.Span.Length); @@ -22,7 +22,7 @@ public static unsafe void StackAllocationTest() Equal(40, vector.Span[3]); } - private static void MemoryAccess(in MemoryRental vector) + private static void MemoryAccess(in SpanOwner vector) { False(vector.IsEmpty); vector[0] = 10; @@ -38,7 +38,7 @@ private static void MemoryAccess(in MemoryRental vector) [Fact] public static void ArrayAllocation() { - using var vector = new MemoryRental(4); + using var vector = new SpanOwner(4); Equal(4, vector.Length); Equal(4, vector.Span.Length); MemoryAccess(vector); @@ -47,7 +47,7 @@ public static void ArrayAllocation() [Fact] public static void MemoryAllocation() { - using var vector = new MemoryRental(MemoryPool.Shared, 4); + using var vector = new SpanOwner(MemoryPool.Shared, 4); Equal(4, vector.Length); Equal(4, vector.Span.Length); MemoryAccess(vector); @@ -56,7 +56,7 @@ public static void MemoryAllocation() [Fact] public static void MemoryAllocationDefaultSize() { - using var vector = new MemoryRental(MemoryPool.Shared); + using var vector = new SpanOwner(MemoryPool.Shared); MemoryAccess(vector); } @@ -64,7 +64,7 @@ public static void MemoryAllocationDefaultSize() public static unsafe void WrapArray() { int[] array = { 10, 20 }; - using var rental = new MemoryRental(array); + using var rental = new SpanOwner(array); False(rental.IsEmpty); fixed (int* ptr = rental) { @@ -76,7 +76,7 @@ public static unsafe void WrapArray() [Fact] public static void Default() { - var rental = new MemoryRental(Array.Empty()); + var rental = new SpanOwner(Array.Empty()); True(rental.IsEmpty); Equal(0, rental.Length); True(rental.Span.IsEmpty); diff --git a/src/DotNext.Tests/SpanTests.cs b/src/DotNext.Tests/SpanTests.cs index ba98afd75..8e9a79717 100644 --- a/src/DotNext.Tests/SpanTests.cs +++ b/src/DotNext.Tests/SpanTests.cs @@ -464,7 +464,7 @@ public static void SplitSpanByLength() [Fact] public static void SwapElements() { - Span expected = RandomBytes(MemoryRental.StackallocThreshold * 4 + 2); + Span expected = RandomBytes(SpanOwner.StackallocThreshold * 4 + 2); Span actual = expected.ToArray(); var midpoint = actual.Length >> 1; actual.Slice(0, midpoint).Swap(actual.Slice(midpoint)); diff --git a/src/DotNext/Buffers/Binary/IBinaryFormattable.cs b/src/DotNext/Buffers/Binary/IBinaryFormattable.cs index be57437c9..d41b73346 100644 --- a/src/DotNext/Buffers/Binary/IBinaryFormattable.cs +++ b/src/DotNext/Buffers/Binary/IBinaryFormattable.cs @@ -92,9 +92,9 @@ public static TSelf Parse(in ReadOnlySequence source) [MethodImpl(MethodImplOptions.NoInlining)] static TSelf ParseSlow(in ReadOnlySequence input) { - using var buffer = (uint)TSelf.Size <= (uint)MemoryRental.StackallocThreshold + using var buffer = (uint)TSelf.Size <= (uint)SpanOwner.StackallocThreshold ? stackalloc byte[TSelf.Size] - : new MemoryRental(TSelf.Size); + : new SpanOwner(TSelf.Size); input.CopyTo(buffer.Span, out var writtenCount); return TSelf.Parse(buffer.Span.Slice(0, writtenCount)); diff --git a/src/DotNext/Buffers/MemoryRental.cs b/src/DotNext/Buffers/SpanOwner.cs similarity index 91% rename from src/DotNext/Buffers/MemoryRental.cs rename to src/DotNext/Buffers/SpanOwner.cs index 4d2c43d4b..b9b48f88b 100644 --- a/src/DotNext/Buffers/MemoryRental.cs +++ b/src/DotNext/Buffers/SpanOwner.cs @@ -20,12 +20,12 @@ namespace DotNext.Buffers; /// /// /// const int stackallocThreshold = 20; -/// var memory = size <=stackallocThreshold ? new MemoryRental<byte>(stackalloc byte[stackallocThreshold], size) : new MemoryRental<byte>(size); +/// var memory = size <=stackallocThreshold ? new SpanOwner<byte>(stackalloc byte[stackallocThreshold], size) : new SpanOwner<byte>(size); /// /// /// The type of the elements in the rented memory. [StructLayout(LayoutKind.Auto)] -public ref struct MemoryRental +public ref struct SpanOwner { /// /// Global recommended number of elements that can be allocated on the stack. @@ -46,7 +46,7 @@ public ref struct MemoryRental /// /// The span that references the memory to rent. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public MemoryRental(Span span) + public SpanOwner(Span span) { memory = span; owner = null; @@ -57,7 +57,7 @@ public MemoryRental(Span span) /// /// The span that references the memory to rent. /// The actual length of the data. - public MemoryRental(Span span, int length) + public SpanOwner(Span span, int length) : this(span.Slice(0, length)) { } @@ -70,7 +70,7 @@ public MemoryRental(Span span, int length) /// to return the buffer of length; otherwise, the returned buffer is at least of . /// is . /// is less than or equal to zero. - public MemoryRental(MemoryPool pool, int minBufferSize, bool exactSize = true) + public SpanOwner(MemoryPool pool, int minBufferSize, bool exactSize = true) { ArgumentNullException.ThrowIfNull(pool); ArgumentOutOfRangeException.ThrowIfNegativeOrZero(minBufferSize); @@ -87,7 +87,7 @@ public MemoryRental(MemoryPool pool, int minBufferSize, bool exactSize = true /// /// The memory pool. /// is . - public MemoryRental(MemoryPool pool) + public SpanOwner(MemoryPool pool) { ArgumentNullException.ThrowIfNull(pool); var owner = pool.Rent(); @@ -101,7 +101,7 @@ public MemoryRental(MemoryPool pool) /// The minimum size of the memory to rent. /// to return the buffer of length; otherwise, the returned buffer is at least of . /// is less than or equal to zero. - public MemoryRental(int minBufferSize, bool exactSize = true) + public SpanOwner(int minBufferSize, bool exactSize = true) { var owner = ArrayPool.Shared.Rent(minBufferSize); memory = exactSize ? new(owner, 0, minBufferSize) : new(owner); @@ -125,7 +125,7 @@ public MemoryRental(int minBufferSize, bool exactSize = true) /// /// The allocated memory to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator MemoryRental(Span span) + public static implicit operator SpanOwner(Span span) => new(span); /// diff --git a/src/DotNext/RandomExtensions.cs b/src/DotNext/RandomExtensions.cs index ef233b4f6..9a5a16dfc 100644 --- a/src/DotNext/RandomExtensions.cs +++ b/src/DotNext/RandomExtensions.cs @@ -7,7 +7,7 @@ namespace DotNext; using Numerics; -using UInt32LocalBuffer = Buffers.MemoryRental; +using UInt32LocalBuffer = Buffers.SpanOwner; /// /// Provides random data generation. diff --git a/src/DotNext/Span.cs b/src/DotNext/Span.cs index 222cf33fc..e4c4346e3 100644 --- a/src/DotNext/Span.cs +++ b/src/DotNext/Span.cs @@ -550,7 +550,7 @@ private static void SwapCore(Span x, Span y) { Debug.Assert(x.Length == y.Length); - var bufferSize = Math.Min(MemoryRental.StackallocThreshold, x.Length); + var bufferSize = Math.Min(SpanOwner.StackallocThreshold, x.Length); if (bufferSize is 0) { return; @@ -664,8 +664,8 @@ static void SwapCore(Span span, int start1, int length1, int start2, int leng Debug.Assert(sourceSmall.Length == destSmall.Length); // prepare buffer - MemoryRental buffer; - if (RuntimeHelpers.IsReferenceOrContainsReferences() || sourceLarge.Length > MemoryRental.StackallocThreshold) + SpanOwner buffer; + if (RuntimeHelpers.IsReferenceOrContainsReferences() || sourceLarge.Length > SpanOwner.StackallocThreshold) { buffer = new(sourceLarge.Length); } @@ -754,8 +754,8 @@ static void MoveCore(Span span, int sourceIndex, int destinationIndex, int le } // prepare buffer - MemoryRental buffer; - if (RuntimeHelpers.IsReferenceOrContainsReferences() || length > MemoryRental.StackallocThreshold) + SpanOwner buffer; + if (RuntimeHelpers.IsReferenceOrContainsReferences() || length > SpanOwner.StackallocThreshold) { buffer = new(length); } diff --git a/src/cluster/DotNext.Net.Cluster/Net/EndPointFormatter.cs b/src/cluster/DotNext.Net.Cluster/Net/EndPointFormatter.cs index 3ef548f5e..b3ab02c0e 100644 --- a/src/cluster/DotNext.Net.Cluster/Net/EndPointFormatter.cs +++ b/src/cluster/DotNext.Net.Cluster/Net/EndPointFormatter.cs @@ -170,9 +170,9 @@ private static UnixDomainSocketEndPoint DeserializeDomainSocket(ref SequenceRead { var length = reader.ReadLittleEndian(); - using var pathBuffer = (uint)length <= (uint)MemoryRental.StackallocThreshold + using var pathBuffer = (uint)length <= (uint)SpanOwner.StackallocThreshold ? stackalloc byte[length] - : new MemoryRental(length, true); + : new SpanOwner(length, true); reader.Read(pathBuffer.Span); return new(HostNameEncoding.GetString(pathBuffer.Span)); @@ -182,9 +182,9 @@ private static UriEndPoint DeserializeUri(ref SequenceReader reader) { var length = reader.ReadLittleEndian(); - using var pathBuffer = (uint)length <= (uint)MemoryRental.StackallocThreshold + using var pathBuffer = (uint)length <= (uint)SpanOwner.StackallocThreshold ? stackalloc byte[length] - : new MemoryRental(length, true); + : new SpanOwner(length, true); reader.Read(pathBuffer.Span); return new(new Uri(HostNameEncoding.GetString(pathBuffer.Span), UriKind.Absolute)); @@ -207,7 +207,7 @@ private static void DeserializeHost(ref SequenceReader reader, out string hostNa family = (AddressFamily)reader.ReadLittleEndian(); var length = reader.ReadLittleEndian(); - using var hostNameBuffer = (uint)length <= (uint)MemoryRental.StackallocThreshold ? stackalloc byte[length] : new MemoryRental(length, true); + using var hostNameBuffer = (uint)length <= (uint)SpanOwner.StackallocThreshold ? stackalloc byte[length] : new SpanOwner(length, true); reader.Read(hostNameBuffer.Span); hostName = HostNameEncoding.GetString(hostNameBuffer.Span); }