diff --git a/ExaArray/ExaArray1D.Factories.cs b/ExaArray/ExaArray1D.Factories.cs new file mode 100644 index 0000000..2fe257e --- /dev/null +++ b/ExaArray/ExaArray1D.Factories.cs @@ -0,0 +1,35 @@ +using System; + +namespace Exa +{ + public partial class ExaArray1D + { + /// + /// Creates a new ExaArray1D from another. + /// + /// + /// When T is a value type, data gets copied as values. When T is a reference type, the pointers + /// to the original objects are copied. Thus, this factory method does not create a deep copy. + /// + /// Performance: O(n) + /// + /// The instance from which the new instance is to be created. + /// The new instance + public static ExaArray1D CreateFrom(ExaArray1D other) + { + var next = new ExaArray1D(other.OptimizationStrategy) + { + Length = other.Length, + chunks = new T[other.chunks.Length][] + }; + + for (var n = 0; n < other.chunks.Length; n++) + { + next.chunks[n] = new T[other.chunks[n].Length]; + Array.Copy(other.chunks[n], next.chunks[n], other.chunks[n].Length); + } + + return next; + } + } +} \ No newline at end of file diff --git a/ExaArray/ExaArray1D.cs b/ExaArray/ExaArray1D.cs index 091e954..51e002b 100644 --- a/ExaArray/ExaArray1D.cs +++ b/ExaArray/ExaArray1D.cs @@ -8,7 +8,7 @@ namespace Exa /// 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 + public sealed partial class ExaArray1D { /// /// Unfortunately, this seems to be the maximal number of entries an diff --git a/ExaArrayTests/ExaArray1DTests.cs b/ExaArrayTests/ExaArray1DTests.cs index 4b27aee..873aedc 100644 --- a/ExaArrayTests/ExaArray1DTests.cs +++ b/ExaArrayTests/ExaArray1DTests.cs @@ -180,7 +180,7 @@ namespace ExaArrayTests } [Test] - [Category("normal")] + [Category("intensive")] public void CountingHugeSize01() { var exaA = new ExaArray1D(); @@ -194,6 +194,114 @@ namespace ExaArrayTests }); } + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFrom001() + { + var exPerf = new ExaArray1D(Strategy.MAX_PERFORMANCE); + exPerf.Extend(2); + exPerf[0] = 0x01; + exPerf[1] = 0x02; + + var next = ExaArray1D.CreateFrom(exPerf); + Assert.That(next.Length, Is.EqualTo(exPerf.Length)); + Assert.That(next.OptimizationStrategy, Is.EqualTo(exPerf.OptimizationStrategy)); + Assert.That(next.Items(), Is.EquivalentTo(exPerf.Items())); + + exPerf = null; + next = null; + + var exElem = new ExaArray1D(Strategy.MAX_ELEMENTS); + exElem.Extend(2); + exElem[0] = 0x03; + exElem[1] = 0x04; + + next = ExaArray1D.CreateFrom(exElem); + Assert.That(next.Length, Is.EqualTo(exElem.Length)); + Assert.That(next.OptimizationStrategy, Is.EqualTo(exElem.OptimizationStrategy)); + Assert.That(next.Items(), Is.EquivalentTo(exElem.Items())); + } + + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFrom002Objects() + { + var exPerf = new ExaArray1D(Strategy.MAX_PERFORMANCE); + exPerf.Extend(2); + exPerf[0] = new object(); + exPerf[1] = new object(); + + var next = ExaArray1D.CreateFrom(exPerf); + Assert.That(next.Length, Is.EqualTo(exPerf.Length)); + Assert.That(next.OptimizationStrategy, Is.EqualTo(exPerf.OptimizationStrategy)); + Assert.That(next[0], Is.SameAs(exPerf[0])); + Assert.That(next[1], Is.SameAs(exPerf[1])); + Assert.That(next[0], Is.Not.SameAs(next[1])); + + exPerf = null; + next = null; + + var exElem = new ExaArray1D(Strategy.MAX_ELEMENTS); + exElem.Extend(2); + exElem[0] = new object(); + exElem[1] = new object(); + + next = ExaArray1D.CreateFrom(exElem); + Assert.That(next.Length, Is.EqualTo(exElem.Length)); + Assert.That(next.OptimizationStrategy, Is.EqualTo(exElem.OptimizationStrategy)); + Assert.That(next[0], Is.SameAs(exElem[0])); + Assert.That(next[1], Is.SameAs(exElem[1])); + Assert.That(next[0], Is.Not.SameAs(next[1])); + } + + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFrom003() + { + var exPerf = new ExaArray1D(Strategy.MAX_PERFORMANCE); + exPerf.Extend(5_000_000_000); // more than one chunk + + var next = ExaArray1D.CreateFrom(exPerf); + Assert.That(next.Length, Is.EqualTo(exPerf.Length)); + Assert.DoesNotThrow(() => + { + next[4_999_999_999] = 0xab; + }); + + exPerf = null; + next = null; + + var exElem = new ExaArray1D(Strategy.MAX_ELEMENTS); + exElem.Extend(5_000_000_000); + + next = ExaArray1D.CreateFrom(exElem); + Assert.That(next.Length, Is.EqualTo(exElem.Length)); + Assert.DoesNotThrow(() => + { + next[4_999_999_999] = 0xab; + }); + } + + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFrom004() + { + var exPerf = new ExaArray1D(Strategy.MAX_PERFORMANCE); + var next = ExaArray1D.CreateFrom(exPerf); + Assert.That(next.Length, Is.EqualTo(0)); + + exPerf = null; + next = null; + + var exElem = new ExaArray1D(Strategy.MAX_ELEMENTS); + next = ExaArray1D.CreateFrom(exElem); + Assert.That(next.Length, Is.EqualTo(0)); + } + [Test] [Category("intensive")] public void Adding5Billion01()