From 0d6c7191481c4ecc9f8861f67f92f01583966c32 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 4 Aug 2020 20:51:13 +0200 Subject: [PATCH] Implemented store and load methods --- ExaArray/ExaArray1D.cs | 65 +++++++++++++++++++++++++++++++- ExaArrayTests/ExaArray1DTests.cs | 59 +++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/ExaArray/ExaArray1D.cs b/ExaArray/ExaArray1D.cs index 94f9e23..c837fbf 100644 --- a/ExaArray/ExaArray1D.cs +++ b/ExaArray/ExaArray1D.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; namespace Exa { @@ -8,7 +11,8 @@ 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 partial class ExaArray1D + [Serializable] + public sealed partial class ExaArray1D : ISerializable { /// /// Unfortunately, this seems to be the maximal number of entries an @@ -218,5 +222,64 @@ namespace Exa for (ulong n = 0; n < this.Length; n++) yield return this[n]; } + + #region Store and load + + /// + /// Stores the exa array into a stream. + /// + /// + /// This method does not dispose the stream. + /// + public void Store(Stream outputStream) + { + var formatter = new BinaryFormatter(); + formatter.Serialize(outputStream, this); + } + + /// + /// Restores an exa array from the given stream. + /// + /// + /// This method does not dispose the stream. + /// + public static ExaArray1D Restore(Stream inputStream) + { + var formatter = new BinaryFormatter(); + return formatter.Deserialize(inputStream) as ExaArray1D; + } + + #endregion + + #region Serialization + + /// + /// This method serves for the serialization process. Do not call it manually. + /// + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("version", "v1"); + info.AddValue("strategy", this.OptimizationStrategy, typeof(Strategy)); + info.AddValue("length", this.Length); + info.AddValue("chunks", this.chunks, typeof(T[][])); + } + + private ExaArray1D(SerializationInfo info, StreamingContext context) + { + switch (info.GetString("version")) + { + case "v1": + this.Length = info.GetUInt64("length"); + this.chunks = info.GetValue("chunks", typeof(T[][])) as T[][]; + this.OptimizationStrategy = (Strategy) info.GetValue("strategy", typeof(Strategy)); + break; + } + + this.chunks[0] ??= new T[0]; + this.maxElements = this.OptimizationStrategy == Strategy.MAX_PERFORMANCE ? MAX_NUMBER_ELEMENTS_PERFORMANCE : MAX_NUMBER_ELEMENTS; + this.maxArrayCapacity = this.OptimizationStrategy == Strategy.MAX_PERFORMANCE ? MAX_CAPACITY_ARRAY_PERFORMANCE : MAX_CAPACITY_ARRAY; + } + + #endregion } } \ No newline at end of file diff --git a/ExaArrayTests/ExaArray1DTests.cs b/ExaArrayTests/ExaArray1DTests.cs index 11d02fd..57c75e0 100644 --- a/ExaArrayTests/ExaArray1DTests.cs +++ b/ExaArrayTests/ExaArray1DTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.IO; using System.Linq; using System.Threading.Tasks; using Exa; @@ -12,6 +13,7 @@ namespace ExaArrayTests [ExcludeFromCodeCoverage] public class ExaArray1DTests { + [Serializable] private class TestClass { public int Age { get; set; } @@ -734,5 +736,62 @@ namespace ExaArrayTests TestContext.WriteLine($"Performing 100M assignments took {t2Times.Average()} ms (average) by means of the max. performance strategy (min={t2Times.Min()} ms, max={t2Times.Max()} ms)"); } + + [Test] + [Category("cover")] + [Category("normal")] + public void StoreAndLoad01() + { + var exaA = new ExaArray1D(); + exaA.Extend(5_000_000); + exaA[4_483_124] = 0xff; + + var filename = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + using (var file = File.OpenWrite(filename)) + { + exaA.Store(file); + } + + using (var file = File.OpenRead(filename)) + { + var exaB = ExaArray1D.Restore(file); + + Assert.That(exaA.Length, Is.EqualTo(exaB.Length)); + Assert.That(exaA[4_483_124], Is.EqualTo(0xff)); + Assert.That(exaB[4_483_124], Is.EqualTo(0xff)); + } + + File.Delete(filename); + } + + [Test] + [Category("cover")] + [Category("normal")] + public void StoreAndLoad02() + { + var exaA = new ExaArray1D(); + exaA.Extend(100); + exaA[66] = new TestClass + { + Age = 55, + }; + + var filename = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + using (var file = File.OpenWrite(filename)) + { + exaA.Store(file); + } + + using (var file = File.OpenRead(filename)) + { + var exaB = ExaArray1D.Restore(file); + + Assert.That(exaA.Length, Is.EqualTo(exaB.Length)); + Assert.That(exaA[66].Age, Is.EqualTo(55)); + Assert.That(exaB[66].Age, Is.EqualTo(55)); + } + + File.Delete(filename); + } } } \ No newline at end of file