From 9a7718b663f3b342bef5e85b61117cba2af174fb Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Wed, 29 Jul 2020 18:36:05 +0200 Subject: [PATCH] Fixed the max. number of elements Thanks @Frassle on Github: https://github.com/dotnet/runtime/issues/12221#issuecomment-665553557 --- ExaArray/ExaArray1D.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ExaArray/ExaArray1D.cs b/ExaArray/ExaArray1D.cs index 67df0ed..051138f 100644 --- a/ExaArray/ExaArray1D.cs +++ b/ExaArray/ExaArray1D.cs @@ -5,7 +5,7 @@ namespace Exa { /// /// 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. /// /// The desired type to use, e.g. byte, int, etc. public sealed class ExaArray1D @@ -15,13 +15,13 @@ namespace Exa /// C# array can hold e.g. of uint. Due to this limitation, this is /// also the maximum number of possible chunks. /// - 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 /// /// The total number of possible elements. /// - 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: private T[][] chunks = new T[1][]; @@ -35,23 +35,23 @@ namespace Exa /// /// /// Please ensure, that neither the extendBy parameter nor the total number of - /// elements can exceed 4,410,000,000,000,000,000. Otherwise, an ArgumentOutOfRangeException + /// elements can exceed 4,607,183,514,018,780,000. Otherwise, an ArgumentOutOfRangeException /// will be thrown. You can use the constant to perform checks. /// /// Performance: O(n) where n is the new total number of elements /// Memory: O(n+m) where n is the necessary memory for the previously elements, and m /// is the memory needed for the desired new capacity. /// - /// Extend this array by this number of elements. Cannot exceed 4,410,000,000,000,000,000. + /// Extend this array by this number of elements. Cannot exceed 4,607,183,514,018,780,000. /// Throws, if either the total number of elements or the - /// extendBy argument exceeds the limit of 4,410,000,000,000,000,000 elements. + /// extendBy argument exceeds the limit of 4,607,183,514,018,780,000 elements. public void Extend(ulong extendBy = 1) { 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."); 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) { // Extend the current chunk to its max: @@ -68,8 +68,8 @@ namespace Exa do { - int allocating = leftOver >= MAX_CAPACITY_ARRAY ? MAX_CAPACITY_ARRAY : (int)leftOver; - leftOver -= (ulong) allocating; + ulong allocating = leftOver >= MAX_CAPACITY_ARRAY ? MAX_CAPACITY_ARRAY : leftOver; + leftOver -= allocating; // First, we allocate space for the new chunk: var extendedOuter = new T[this.chunks.Length + 1][]; @@ -114,7 +114,7 @@ namespace Exa if(index >= MAX_NUMBER_ELEMENTS) 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); return this.chunks[chunkIndex][elementIndex]; } @@ -124,7 +124,7 @@ namespace Exa if(index >= MAX_NUMBER_ELEMENTS) 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); if (chunkIndex >= this.chunks.Length || elementIndex >= this.chunks[chunkIndex].Length) throw new IndexOutOfRangeException();