Skip to content

Commit

Permalink
added RcRentedArray (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
ikpil committed Jan 21, 2024
1 parent f1ecd37 commit 675ca8e
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 68 deletions.
60 changes: 60 additions & 0 deletions src/DotRecast.Core/Buffers/RcRentedArray.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
13 changes: 2 additions & 11 deletions src/DotRecast.Core/Collections/RcStackArray128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,21 +139,12 @@ public struct RcStackArray128<T>
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
{
Expand Down Expand Up @@ -291,7 +282,7 @@ public T this[int index]

set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);

switch (index)
{
Expand Down
14 changes: 2 additions & 12 deletions src/DotRecast.Core/Collections/RcStackArray16.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,12 @@ public struct RcStackArray16<T>
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
{
Expand All @@ -68,7 +58,7 @@ public T this[int index]

set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);

switch (index)
{
Expand Down
13 changes: 2 additions & 11 deletions src/DotRecast.Core/Collections/RcStackArray256.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,21 +267,12 @@ public struct RcStackArray256<T>
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
{
Expand Down Expand Up @@ -547,7 +538,7 @@ public T this[int index]

set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);

switch (index)
{
Expand Down
13 changes: 2 additions & 11 deletions src/DotRecast.Core/Collections/RcStackArray32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,12 @@ public struct RcStackArray32<T>
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
{
Expand Down Expand Up @@ -99,7 +90,7 @@ public T this[int index]

set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);

switch (index)
{
Expand Down
14 changes: 2 additions & 12 deletions src/DotRecast.Core/Collections/RcStackArray512.cs
Original file line number Diff line number Diff line change
Expand Up @@ -523,21 +523,12 @@ public struct RcStackArray512<T>
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
{
Expand Down Expand Up @@ -1060,7 +1051,7 @@ public T this[int index]

set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);

switch (index)
{
Expand Down Expand Up @@ -1576,7 +1567,6 @@ public T this[int index]
case 509: V509 = value; break;
case 510: V510 = value; break;
case 511: V511 = value; break;

}
}
}
Expand Down
13 changes: 2 additions & 11 deletions src/DotRecast.Core/Collections/RcStackArray64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,12 @@ public struct RcStackArray64<T>
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
{
Expand Down Expand Up @@ -163,7 +154,7 @@ public T this[int index]

set
{
ThrowExceptionIfIndexOutOfRange(index);
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);

switch (index)
{
Expand Down
52 changes: 52 additions & 0 deletions test/DotRecast.Core.Test/RcRentedArrayTest.cs
Original file line number Diff line number Diff line change
@@ -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]);
}
}
}

0 comments on commit 675ca8e

Please sign in to comment.