From ed9143f240a3856fdddfae347b26ee64fd1eaa7f Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 3 Aug 2020 20:06:19 +0200 Subject: [PATCH] WIP: Added first 2d implementation --- ExaArray/ExaArray2D.cs | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 ExaArray/ExaArray2D.cs diff --git a/ExaArray/ExaArray2D.cs b/ExaArray/ExaArray2D.cs new file mode 100644 index 0000000..248dda0 --- /dev/null +++ b/ExaArray/ExaArray2D.cs @@ -0,0 +1,76 @@ +using System; + +namespace Exa +{ + /// + /// The two-dimensional exa-scale array. Can grow up to 18,446,744,073,709,551,615 elements in total. + /// + public sealed class ExaArray2D + { + /// + /// The total number of possible elements. + /// + public const ulong MAX_NUMBER_ELEMENTS = ulong.MaxValue; + + private ulong sumLengthOrdinates = 0; + + // Chunk storage: + private ExaArray1D> chunks = new ExaArray1D>(Strategy.MAX_PERFORMANCE); + + /// + /// Returns the current total number of elements across all dimensions. + /// + /// + /// Performance: O(1) + /// + public ulong Length => this.sumLengthOrdinates; + + /// + /// Gets or sets an element of the array. + /// + /// + /// Getting a value: When asking for elements which are not yet allocated, returns default(T). Performance: O(1). + /// + /// Setting a value: The underlying data structure gets extended on demand as necessary. The array can and will grow + /// on demand per index. For example, the abscissa index 5 might have allocated memory for 15 elements while abscissa + /// index 16 have allocated memory for 1,000 elements. + /// + /// Performance, when the memory is already allocated: O(1) + /// Performance to extend on demand: O(n) + /// + /// On the abscissa, you extend up to 1,152,921,504,606,850,000 entries. Across all dimensions, you can have 18,446,744,073,709,551,615 + /// elements on total. + /// + /// Throws, when you tried to extend more than 1,152,921,504,606,850,000 elements on the abscissa + /// or you tried to extend to more than 18,446,744,073,709,551,615 elements in total. + public T this[ulong indexAbscissa, ulong indexOrdinate] + { + get + { + if (indexAbscissa >= this.chunks.Length - 1 || indexOrdinate >= this.chunks[indexAbscissa]?.Length) + return default(T); + + return this.chunks[indexAbscissa][indexOrdinate]; + } + + set + { + if(indexAbscissa >= this.chunks.Length - 1) + this.chunks.Extend(indexAbscissa - this.chunks.Length + 1); + + this.chunks[indexAbscissa] ??= new ExaArray1D(Strategy.MAX_PERFORMANCE); + if(indexOrdinate >= this.chunks[indexAbscissa].Length - 1) + { + var extendBy = indexOrdinate - this.chunks[indexAbscissa].Length + 1; + if(extendBy > MAX_NUMBER_ELEMENTS - this.sumLengthOrdinates) + throw new ArgumentOutOfRangeException($"It is not possible to extend more than {MAX_NUMBER_ELEMENTS} total elements across all dimensions."); + + this.chunks[indexAbscissa].Extend(extendBy); + this.sumLengthOrdinates += extendBy; + } + + this.chunks[indexAbscissa][indexOrdinate] = value; + } + } + } +} \ No newline at end of file