added RcRentedArray (#41)

This commit is contained in:
ikpil 2024-01-21 19:05:02 +09:00 committed by Ikpil
parent f1ecd37f4d
commit 675ca8ea4b
8 changed files with 124 additions and 68 deletions

View File

@ -0,0 +1,60 @@
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
namespace DotRecast.Core.Buffers
{
public static class RcRentedArray
{
public static RcRentedArray<T> RentDisposableArray<T>(int minimumLength)
{
var array = ArrayPool<T>.Shared.Rent(minimumLength);
return new RcRentedArray<T>(ArrayPool<T>.Shared, array, minimumLength);
}
}
public class RcRentedArray<T> : IDisposable
{
private ArrayPool<T> _owner;
private T[] _array;
private readonly RcAtomicInteger _disposed;
public int Length { get; }
internal RcRentedArray(ArrayPool<T> owner, T[] array, int length)
{
_owner = owner;
_array = array;
Length = length;
_disposed = new RcAtomicInteger(0);
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
return _array[index];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
_array[index] = value;
}
}
public void Dispose()
{
if (1 != _disposed.IncrementAndGet())
return;
_owner?.Return(_array, true);
_array = null;
_owner = null;
}
}
}

View File

@ -139,21 +139,12 @@ namespace DotRecast.Core.Collections
public T V126;
public T V127;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowExceptionIfIndexOutOfRange(int index)
{
if (0 > index || index >= Size)
{
throw new IndexOutOfRangeException($"{index}");
}
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
return index switch
{
@ -291,7 +282,7 @@ namespace DotRecast.Core.Collections
set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
switch (index)
{

View File

@ -27,22 +27,12 @@ namespace DotRecast.Core.Collections
public T V14;
public T V15;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowExceptionIfIndexOutOfRange(int index)
{
if (0 > index || index >= Size)
{
throw new IndexOutOfRangeException($"{index}");
}
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
return index switch
{
@ -68,7 +58,7 @@ namespace DotRecast.Core.Collections
set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
switch (index)
{

View File

@ -267,21 +267,12 @@ namespace DotRecast.Core.Collections
public T V254;
public T V255;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowExceptionIfIndexOutOfRange(int index)
{
if (0 > index || index >= Size)
{
throw new IndexOutOfRangeException($"{index}");
}
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
return index switch
{
@ -547,7 +538,7 @@ namespace DotRecast.Core.Collections
set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
switch (index)
{

View File

@ -43,21 +43,12 @@ namespace DotRecast.Core.Collections
public T V30;
public T V31;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowExceptionIfIndexOutOfRange(int index)
{
if (0 > index || index >= Size)
{
throw new IndexOutOfRangeException($"{index}");
}
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
return index switch
{
@ -99,7 +90,7 @@ namespace DotRecast.Core.Collections
set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
switch (index)
{

View File

@ -523,21 +523,12 @@ namespace DotRecast.Core.Collections
public T V510;
public T V511;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowExceptionIfIndexOutOfRange(int index)
{
if (0 > index || index >= Size)
{
throw new IndexOutOfRangeException($"{index}");
}
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
return index switch
{
@ -1060,7 +1051,7 @@ namespace DotRecast.Core.Collections
set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
switch (index)
{
@ -1576,7 +1567,6 @@ namespace DotRecast.Core.Collections
case 509: V509 = value; break;
case 510: V510 = value; break;
case 511: V511 = value; break;
}
}
}

View File

@ -75,21 +75,12 @@ namespace DotRecast.Core.Collections
public T V62;
public T V63;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowExceptionIfIndexOutOfRange(int index)
{
if (0 > index || index >= Size)
{
throw new IndexOutOfRangeException($"{index}");
}
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
return index switch
{
@ -163,7 +154,7 @@ namespace DotRecast.Core.Collections
set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
switch (index)
{

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using DotRecast.Core.Buffers;
using NUnit.Framework;
namespace DotRecast.Core.Test;
public class RcRentedArrayTest
{
public List<int> RandomValues(int length)
{
var rand = new RcRand();
// excepted values
var list = new List<int>();
for (int i = 0; i < length; ++i)
{
list.Add(rand.NextInt32());
}
return list;
}
[Test]
public void Test()
{
var rand = new RcRand();
for (int loop = 0; loop < 1024; ++loop)
{
int length = (int)(rand.Next() * 2048);
var values = RandomValues(length);
using var array = RcRentedArray.RentDisposableArray<float>(length);
for (int i = 0; i < array.Length; ++i)
{
array[i] = values[i];
}
for (int i = 0; i < array.Length; ++i)
{
Assert.That(array[i], Is.EqualTo(values[i]));
}
Assert.That(array[^1], Is.EqualTo(values[^1]));
Assert.Throws<IndexOutOfRangeException>(() => array[-1] = 0);
Assert.Throws<IndexOutOfRangeException>(() => array[array.Length + 1] = 0);
Assert.Throws<IndexOutOfRangeException>(() => _ = array[-1]);
Assert.Throws<IndexOutOfRangeException>(() => _ = array[array.Length + 1]);
}
}
}