diff --git a/src/Nino.Shared/IO/Buffer/ExtensibleBuffer.cs b/src/Nino.Shared/IO/Buffer/ExtensibleBuffer.cs index 4302438..9bd2e64 100644 --- a/src/Nino.Shared/IO/Buffer/ExtensibleBuffer.cs +++ b/src/Nino.Shared/IO/Buffer/ExtensibleBuffer.cs @@ -33,7 +33,7 @@ public sealed unsafe class ExtensibleBuffer where T : unmanaged /// /// Total length of the buffer /// - public int TotalLength { get; private set; } + public int Length { get; private set; } /// /// Init buffer @@ -47,12 +47,12 @@ public ExtensibleBuffer() : this(DefaultBufferSize) /// Init extensible buffer with a capacity /// /// - public ExtensibleBuffer([In] int size = DefaultBufferSize) + public ExtensibleBuffer(int size = DefaultBufferSize) { sizeOfT = (byte)sizeof(T); ExpandSize = size; Data = (T*)Marshal.AllocHGlobal(sizeOfT * ExpandSize); - TotalLength = ExpandSize; + Length = ExpandSize; GC.AddMemoryPressure(sizeOfT * ExpandSize); } @@ -60,14 +60,14 @@ public ExtensibleBuffer([In] int size = DefaultBufferSize) /// Get element at index /// /// - public T this[in int index] + public T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => *(Data + index); [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - EnsureCapacity(in index); + EnsureIndex(index); *(Data + index) = value; } } @@ -76,16 +76,34 @@ public T this[in int index] /// Ensure index exists /// /// - private void EnsureCapacity(in int index) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureIndex(int index) { - if (index < TotalLength) return; - GC.RemoveMemoryPressure(TotalLength * sizeOfT); - while (index >= TotalLength) + if (index < Length) return; + GC.RemoveMemoryPressure(Length * sizeOfT); + while (index >= Length) { - TotalLength += ExpandSize; + Length += ExpandSize; } Extend(); - GC.AddMemoryPressure(TotalLength * sizeOfT); + GC.AddMemoryPressure(Length * sizeOfT); + } + + /// + /// Ensure capacity is big enough + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureCapacity(int count) + { + if (count <= Length) return; + GC.RemoveMemoryPressure(Length * sizeOfT); + while (count > Length) + { + Length += ExpandSize; + } + Extend(); + GC.AddMemoryPressure(Length * sizeOfT); } /// @@ -94,7 +112,7 @@ private void EnsureCapacity(in int index) [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Extend() { - Data = (T*)Marshal.ReAllocHGlobal((IntPtr)Data, new IntPtr(TotalLength * sizeOfT)); + Data = (T*)Marshal.ReAllocHGlobal((IntPtr)Data, new IntPtr(Length * sizeOfT)); } /// @@ -103,7 +121,8 @@ private void Extend() /// /// /// - public T[] ToArray([In] int startIndex, [In] int length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T[] ToArray(int startIndex, int length) { T[] ret = new T[length]; CopyTo(ref ret, startIndex, length); @@ -116,11 +135,12 @@ public T[] ToArray([In] int startIndex, [In] int length) /// /// /// - public Span AsSpan([In] int startIndex, [In] int length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span AsSpan(int startIndex, int length) { var l = startIndex + length; //size check - EnsureCapacity(in l); + EnsureCapacity(l); return new Span(Data + startIndex, length); } @@ -129,7 +149,8 @@ public Span AsSpan([In] int startIndex, [In] int length) /// /// /// - public static implicit operator Span(ExtensibleBuffer buffer) => buffer.AsSpan(0, buffer.TotalLength); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Span(ExtensibleBuffer buffer) => buffer.AsSpan(0, buffer.Length); /// /// Copy data to extensible buffer @@ -139,7 +160,8 @@ public Span AsSpan([In] int startIndex, [In] int length) /// /// /// - public void CopyFrom(T[] src, [In] int srcIndex, [In] int dstIndex, [In] int length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyFrom(T[] src, int srcIndex, int dstIndex, int length) { fixed (T* ptr = src) { @@ -156,11 +178,12 @@ public void CopyFrom(T[] src, [In] int srcIndex, [In] int dstIndex, [In] int len /// /// /// - public void CopyFrom([In] T* src, [In] int srcIndex, [In] int dstIndex, [In] int length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyFrom(T* src, int srcIndex, int dstIndex, int length) { var l = dstIndex + length; //size check - EnsureCapacity(in l); + EnsureIndex(l); //copy Unsafe.CopyBlock(Data + dstIndex, src + srcIndex, (uint)length); } @@ -172,7 +195,8 @@ public void CopyFrom([In] T* src, [In] int srcIndex, [In] int dstIndex, [In] int /// /// /// - public void CopyTo(ref T[] dst, [In] int srcIndex, [In] int length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyTo(ref T[] dst, int srcIndex, int length) { fixed (T* ptr = dst) { @@ -187,11 +211,12 @@ public void CopyTo(ref T[] dst, [In] int srcIndex, [In] int length) /// /// /// - public void CopyTo([In] T* dst, [In] int srcIndex, [In] int length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyTo(T* dst, int srcIndex, int length) { var l = srcIndex + length; //size check - EnsureCapacity(in l); + EnsureIndex(l); //copy Unsafe.CopyBlock(dst, Data + srcIndex, (uint)length); } @@ -202,7 +227,7 @@ public void CopyTo([In] T* dst, [In] int srcIndex, [In] int length) ~ExtensibleBuffer() { Marshal.FreeHGlobal((IntPtr)Data); - GC.RemoveMemoryPressure(sizeOfT * TotalLength); + GC.RemoveMemoryPressure(sizeOfT * Length); } } } \ No newline at end of file