Fixed the max. number of elements
Thanks @Frassle on Github: https://github.com/dotnet/runtime/issues/12221#issuecomment-665553557
This commit is contained in:
parent
ee59d0de22
commit
9a7718b663
@ -5,7 +5,7 @@ namespace Exa
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents an one-dimensional array with the ability to grow up
|
/// This class represents an one-dimensional array with the ability to grow up
|
||||||
/// to 4.4 quintillion (4,410,000,000,000,000,000) or 4.4 exa elements.
|
/// to 4.6 quintillion (4,607,183,514,018,780,000) or 4.6 exa elements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The desired type to use, e.g. byte, int, etc.</typeparam>
|
/// <typeparam name="T">The desired type to use, e.g. byte, int, etc.</typeparam>
|
||||||
public sealed class ExaArray1D<T>
|
public sealed class ExaArray1D<T>
|
||||||
@ -15,12 +15,12 @@ namespace Exa
|
|||||||
/// C# array can hold e.g. of uint. Due to this limitation, this is
|
/// C# array can hold e.g. of uint. Due to this limitation, this is
|
||||||
/// also the maximum number of possible chunks.
|
/// also the maximum number of possible chunks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const int MAX_CAPACITY_ARRAY = 2_100_000_000;
|
private const uint MAX_CAPACITY_ARRAY = 2_146_435_071; // Thanks @Frassle on Github: https://github.com/dotnet/runtime/issues/12221#issuecomment-665553557
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The total number of possible elements.
|
/// The total number of possible elements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const ulong MAX_NUMBER_ELEMENTS = 4_410_000_000_000_000_000;
|
public const ulong MAX_NUMBER_ELEMENTS = 4_607_183_514_018_780_000;
|
||||||
|
|
||||||
// Chunk storage:
|
// Chunk storage:
|
||||||
private T[][] chunks = new T[1][];
|
private T[][] chunks = new T[1][];
|
||||||
@ -35,23 +35,23 @@ namespace Exa
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Please ensure, that neither the <c>extendBy</c> parameter nor the total number of
|
/// Please ensure, that neither the <c>extendBy</c> parameter nor the total number of
|
||||||
/// elements can exceed 4,410,000,000,000,000,000. Otherwise, an <c>ArgumentOutOfRangeException</c>
|
/// elements can exceed 4,607,183,514,018,780,000. Otherwise, an <c>ArgumentOutOfRangeException</c>
|
||||||
/// will be thrown. You can use the <see cref="MAX_NUMBER_ELEMENTS"/> constant to perform checks.
|
/// will be thrown. You can use the <see cref="MAX_NUMBER_ELEMENTS"/> constant to perform checks.
|
||||||
///
|
///
|
||||||
/// Performance: O(n) where n is the new total number of elements
|
/// Performance: O(n) where n is the new total number of elements
|
||||||
/// Memory: O(n+m) where <c>n</c> is the necessary memory for the previously elements, and <c>m</c>
|
/// Memory: O(n+m) where <c>n</c> is the necessary memory for the previously elements, and <c>m</c>
|
||||||
/// is the memory needed for the desired new capacity.
|
/// is the memory needed for the desired new capacity.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="extendBy">Extend this array by this number of elements. Cannot exceed 4,410,000,000,000,000,000.</param>
|
/// <param name="extendBy">Extend this array by this number of elements. Cannot exceed 4,607,183,514,018,780,000.</param>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">Throws, if either the total number of elements or the
|
/// <exception cref="ArgumentOutOfRangeException">Throws, if either the total number of elements or the
|
||||||
/// <c>extendBy</c> argument exceeds the limit of 4,410,000,000,000,000,000 elements.</exception>
|
/// <c>extendBy</c> argument exceeds the limit of 4,607,183,514,018,780,000 elements.</exception>
|
||||||
public void Extend(ulong extendBy = 1)
|
public void Extend(ulong extendBy = 1)
|
||||||
{
|
{
|
||||||
if(extendBy > MAX_NUMBER_ELEMENTS || this.Length + extendBy >= MAX_NUMBER_ELEMENTS)
|
if(extendBy > MAX_NUMBER_ELEMENTS || this.Length + extendBy >= MAX_NUMBER_ELEMENTS)
|
||||||
throw new ArgumentOutOfRangeException($"It is not possible to extend more than {MAX_NUMBER_ELEMENTS} elements.");
|
throw new ArgumentOutOfRangeException($"It is not possible to extend more than {MAX_NUMBER_ELEMENTS} elements.");
|
||||||
|
|
||||||
this.Length += extendBy;
|
this.Length += extendBy;
|
||||||
int availableInCurrentChunk = MAX_CAPACITY_ARRAY - this.chunks[^1]?.Length ?? 0;
|
var availableInCurrentChunk = MAX_CAPACITY_ARRAY - this.chunks[^1]?.Length ?? 0;
|
||||||
if (extendBy >= (ulong)availableInCurrentChunk)
|
if (extendBy >= (ulong)availableInCurrentChunk)
|
||||||
{
|
{
|
||||||
// Extend the current chunk to its max:
|
// Extend the current chunk to its max:
|
||||||
@ -68,8 +68,8 @@ namespace Exa
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int allocating = leftOver >= MAX_CAPACITY_ARRAY ? MAX_CAPACITY_ARRAY : (int)leftOver;
|
ulong allocating = leftOver >= MAX_CAPACITY_ARRAY ? MAX_CAPACITY_ARRAY : leftOver;
|
||||||
leftOver -= (ulong) allocating;
|
leftOver -= allocating;
|
||||||
|
|
||||||
// First, we allocate space for the new chunk:
|
// First, we allocate space for the new chunk:
|
||||||
var extendedOuter = new T[this.chunks.Length + 1][];
|
var extendedOuter = new T[this.chunks.Length + 1][];
|
||||||
@ -114,7 +114,7 @@ namespace Exa
|
|||||||
if(index >= MAX_NUMBER_ELEMENTS)
|
if(index >= MAX_NUMBER_ELEMENTS)
|
||||||
throw new IndexOutOfRangeException();
|
throw new IndexOutOfRangeException();
|
||||||
|
|
||||||
int chunkIndex = (int) (index / (ulong)MAX_CAPACITY_ARRAY);
|
int chunkIndex = (int) (index / MAX_CAPACITY_ARRAY);
|
||||||
int elementIndex = (int) (index - (ulong) chunkIndex * MAX_CAPACITY_ARRAY);
|
int elementIndex = (int) (index - (ulong) chunkIndex * MAX_CAPACITY_ARRAY);
|
||||||
return this.chunks[chunkIndex][elementIndex];
|
return this.chunks[chunkIndex][elementIndex];
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ namespace Exa
|
|||||||
if(index >= MAX_NUMBER_ELEMENTS)
|
if(index >= MAX_NUMBER_ELEMENTS)
|
||||||
throw new IndexOutOfRangeException();
|
throw new IndexOutOfRangeException();
|
||||||
|
|
||||||
int chunkIndex = (int) (index / (ulong)MAX_CAPACITY_ARRAY);
|
int chunkIndex = (int) (index / MAX_CAPACITY_ARRAY);
|
||||||
int elementIndex = (int) (index - (ulong) chunkIndex * MAX_CAPACITY_ARRAY);
|
int elementIndex = (int) (index - (ulong) chunkIndex * MAX_CAPACITY_ARRAY);
|
||||||
if (chunkIndex >= this.chunks.Length || elementIndex >= this.chunks[chunkIndex].Length)
|
if (chunkIndex >= this.chunks.Length || elementIndex >= this.chunks[chunkIndex].Length)
|
||||||
throw new IndexOutOfRangeException();
|
throw new IndexOutOfRangeException();
|
||||||
|
Loading…
Reference in New Issue
Block a user