Skip to content

Commit

Permalink
[fix] #96
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonXuDeveloper committed Sep 11, 2023
1 parent 9f05aec commit 72f6822
Showing 1 changed file with 48 additions and 23 deletions.
71 changes: 48 additions & 23 deletions src/Nino.Shared/IO/Buffer/ExtensibleBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public sealed unsafe class ExtensibleBuffer<T> where T : unmanaged
/// <summary>
/// Total length of the buffer
/// </summary>
public int TotalLength { get; private set; }
public int Length { get; private set; }

/// <summary>
/// Init buffer
Expand All @@ -47,27 +47,27 @@ public ExtensibleBuffer() : this(DefaultBufferSize)
/// Init extensible buffer with a capacity
/// </summary>
/// <param name="size"></param>
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);
}

/// <summary>
/// Get element at index
/// </summary>
/// <param name="index"></param>
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;
}
}
Expand All @@ -76,16 +76,34 @@ public T this[in int index]
/// Ensure index exists
/// </summary>
/// <param name="index"></param>
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);
}

/// <summary>
/// Ensure capacity is big enough
/// </summary>
/// <param name="count"></param>
[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);
}

/// <summary>
Expand All @@ -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));
}

/// <summary>
Expand All @@ -103,7 +121,8 @@ private void Extend()
/// <param name="startIndex"></param>
/// <param name="length"></param>
/// <returns></returns>
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);
Expand All @@ -116,11 +135,12 @@ public T[] ToArray([In] int startIndex, [In] int length)
/// <param name="startIndex"></param>
/// <param name="length"></param>
/// <returns></returns>
public Span<T> AsSpan([In] int startIndex, [In] int length)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span<T> AsSpan(int startIndex, int length)
{
var l = startIndex + length;
//size check
EnsureCapacity(in l);
EnsureCapacity(l);
return new Span<T>(Data + startIndex, length);
}

Expand All @@ -129,7 +149,8 @@ public Span<T> AsSpan([In] int startIndex, [In] int length)
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public static implicit operator Span<T>(ExtensibleBuffer<T> buffer) => buffer.AsSpan(0, buffer.TotalLength);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Span<T>(ExtensibleBuffer<T> buffer) => buffer.AsSpan(0, buffer.Length);

/// <summary>
/// Copy data to extensible buffer
Expand All @@ -139,7 +160,8 @@ public Span<T> AsSpan([In] int startIndex, [In] int length)
/// <param name="dstIndex"></param>
/// <param name="length"></param>
/// <exception cref="InvalidOperationException"></exception>
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)
{
Expand All @@ -156,11 +178,12 @@ public void CopyFrom(T[] src, [In] int srcIndex, [In] int dstIndex, [In] int len
/// <param name="dstIndex"></param>
/// <param name="length"></param>
/// <exception cref="InvalidOperationException"></exception>
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);
}
Expand All @@ -172,7 +195,8 @@ public void CopyFrom([In] T* src, [In] int srcIndex, [In] int dstIndex, [In] int
/// <param name="srcIndex"></param>
/// <param name="length"></param>
/// <exception cref="OverflowException"></exception>
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)
{
Expand All @@ -187,11 +211,12 @@ public void CopyTo(ref T[] dst, [In] int srcIndex, [In] int length)
/// <param name="srcIndex"></param>
/// <param name="length"></param>
/// <exception cref="OverflowException"></exception>
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);
}
Expand All @@ -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);
}
}
}

0 comments on commit 72f6822

Please sign in to comment.