diff --git a/Px.Utils.TestingApp/Commands/DataReadBenchmark.cs b/Px.Utils.TestingApp/Commands/DataReadBenchmark.cs index 0d6ca1e..2e7e30a 100644 --- a/Px.Utils.TestingApp/Commands/DataReadBenchmark.cs +++ b/Px.Utils.TestingApp/Commands/DataReadBenchmark.cs @@ -21,7 +21,7 @@ internal sealed class DataReadBenchmark : FileBenchmark internal override string Description => "Benchmarks the data reading capabilities of the PxFileStreamDataReader."; - private DataIndexer? Indexer { get; set; } + private IMatrixMap? Target { get; set; } private int _numberOfCells = 1000000; @@ -53,81 +53,81 @@ protected override void OneTimeBenchmarkSetup() private void RunReadDoubleDataValuesBenchmarks() { if(MetaData is null) throw new InvalidOperationException(metadataNotFoundMessage); - Indexer = GenerateBenchmarkIndexer(MetaData, _numberOfCells); + Target = GenerateBenchmarkTargetMap(MetaData, _numberOfCells); - DoubleDataValue[] buffer = new DoubleDataValue[Indexer.DataLength]; + DoubleDataValue[] buffer = new DoubleDataValue[Target.GetSize()]; using Stream stream = new FileStream(TestFilePath, FileMode.Open, FileAccess.Read); using PxFileStreamDataReader reader = new(stream); - reader.ReadDoubleDataValues(buffer, 0, Indexer); + reader.ReadDoubleDataValues(buffer, 0, Target, MetaData); } private void RunReadDecimalDataValuesBenchmarks() { if (MetaData is null) throw new InvalidOperationException(metadataNotFoundMessage); - Indexer = GenerateBenchmarkIndexer(MetaData, _numberOfCells); + Target = GenerateBenchmarkTargetMap(MetaData, _numberOfCells); - DecimalDataValue[] buffer = new DecimalDataValue[Indexer.DataLength]; + DecimalDataValue[] buffer = new DecimalDataValue[Target.GetSize()]; using Stream stream = new FileStream(TestFilePath, FileMode.Open, FileAccess.Read); using PxFileStreamDataReader reader = new(stream); - reader.ReadDecimalDataValues(buffer, 0, Indexer); + reader.ReadDecimalDataValues(buffer, 0, Target, MetaData); } private void RunReadUnsafeDoubleBenchmarks() { if (MetaData is null) throw new InvalidOperationException(metadataNotFoundMessage); - Indexer = GenerateBenchmarkIndexer(MetaData, _numberOfCells); + Target = GenerateBenchmarkTargetMap(MetaData, _numberOfCells); - double[] buffer = new double[Indexer.DataLength]; + double[] buffer = new double[Target.GetSize()]; double[] missingValueEncodings = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]; using Stream stream = new FileStream(TestFilePath, FileMode.Open, FileAccess.Read); using PxFileStreamDataReader reader = new(stream); - reader.ReadUnsafeDoubles(buffer, 0, Indexer, missingValueEncodings); + reader.ReadUnsafeDoubles(buffer, 0, Target, MetaData, missingValueEncodings); } private async Task RunReadDoubleDataValuesBenchmarksAsync() { if (MetaData is null) throw new InvalidOperationException(metadataNotFoundMessage); - Indexer = GenerateBenchmarkIndexer(MetaData, _numberOfCells); + Target = GenerateBenchmarkTargetMap(MetaData, _numberOfCells); - DoubleDataValue[] buffer = new DoubleDataValue[Indexer.DataLength]; + DoubleDataValue[] buffer = new DoubleDataValue[Target.GetSize()]; using Stream stream = new FileStream(TestFilePath, FileMode.Open, FileAccess.Read); using PxFileStreamDataReader reader = new(stream); - await reader.ReadDoubleDataValuesAsync(buffer, 0, Indexer); + await reader.ReadDoubleDataValuesAsync(buffer, 0, Target, MetaData); } private async Task RunReadDecimalDataValuesBenchmarksAsync() { if (MetaData is null) throw new InvalidOperationException(metadataNotFoundMessage); - Indexer = GenerateBenchmarkIndexer(MetaData, _numberOfCells); + Target = GenerateBenchmarkTargetMap(MetaData, _numberOfCells); - DecimalDataValue[] buffer = new DecimalDataValue[Indexer.DataLength]; + DecimalDataValue[] buffer = new DecimalDataValue[Target.GetSize()]; using Stream stream = new FileStream(TestFilePath, FileMode.Open, FileAccess.Read); using PxFileStreamDataReader reader = new(stream); - await reader.ReadDecimalDataValuesAsync(buffer, 0, Indexer); + await reader.ReadDecimalDataValuesAsync(buffer, 0, Target, MetaData); } private async Task RunReadUnsafeDoubleBenchmarksAsync() { if (MetaData is null) throw new InvalidOperationException(metadataNotFoundMessage); - Indexer = GenerateBenchmarkIndexer(MetaData, _numberOfCells); + Target = GenerateBenchmarkTargetMap(MetaData, _numberOfCells); - double[] buffer = new double[Indexer.DataLength]; + double[] buffer = new double[Target.GetSize()]; double[] missingValueEncodings = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]; using Stream stream = new FileStream(TestFilePath, FileMode.Open, FileAccess.Read); using PxFileStreamDataReader reader = new(stream); - await reader.ReadUnsafeDoublesAsync(buffer, 0, Indexer, missingValueEncodings); + await reader.ReadUnsafeDoublesAsync(buffer, 0, Target, MetaData, missingValueEncodings); } protected override void SetRunParameters() @@ -143,12 +143,12 @@ protected override void SetRunParameters() } } - private static DataIndexer GenerateBenchmarkIndexer(IMatrixMap map, int targetSize) + private static IMatrixMap GenerateBenchmarkTargetMap(IMatrixMap complete, int targetSize) { - int size = map.GetSize(); - if (size < targetSize) return new DataIndexer(map, map); + int size = complete.GetSize(); + if (size < targetSize) return complete; - List sortedDimensions = [.. map.DimensionMaps]; + List sortedDimensions = [.. complete.DimensionMaps]; while (size > targetSize) { sortedDimensions = [.. sortedDimensions.OrderByDescending(x => x.ValueCodes.Count)]; @@ -157,7 +157,7 @@ private static DataIndexer GenerateBenchmarkIndexer(IMatrixMap map, int targetSi size = sortedDimensions.Aggregate(1, (acc, x) => acc * x.ValueCodes.Count); } - List dimList = map.DimensionMaps + List dimList = complete.DimensionMaps .Select(dim => dim.Code) .Select(dimCode => new DimensionMap( dimCode, @@ -165,7 +165,7 @@ [.. sortedDimensions.First(dim => dim.Code == dimCode).ValueCodes])) .Cast() .ToList(); - return new DataIndexer(map, new MatrixMap(dimList)); + return new MatrixMap(dimList); } } } diff --git a/Px.Utils.UnitTests/ModelBuilderTests/MatrixMetadataBuilderTests.cs b/Px.Utils.UnitTests/ModelBuilderTests/MatrixMetadataBuilderTests.cs index 345fbf2..f33415f 100644 --- a/Px.Utils.UnitTests/ModelBuilderTests/MatrixMetadataBuilderTests.cs +++ b/Px.Utils.UnitTests/ModelBuilderTests/MatrixMetadataBuilderTests.cs @@ -8,10 +8,8 @@ using Px.Utils.PxFile; using Px.Utils.UnitTests.ModelBuilderTests.Fixtures; using System.Globalization; -using Px.Utils.PxFile; -using Px.Utils.UnitTests.ModelBuilderTests.Fixtures; -namespace ModelBuilderTests +namespace Px.Utils.UnitTests.ModelBuilderTests { [TestClass] public class MatrixMetadataBuilderTests @@ -19,7 +17,7 @@ public class MatrixMetadataBuilderTests private MatrixMetadata Actual_3Lang { get; } = new MatrixMetadataBuilder().Build(PxFileMetaEntries_Robust_3_Languages.Entries); private MatrixMetadata Actual_1Lang { get; } = new MatrixMetadataBuilder().Build(PxFileMetaEntries_Robust_1_Language.Entries); private MatrixMetadata Actual_Recommended_3Lang { get; } = new MatrixMetadataBuilder().Build(PxFileMetaEntries_Recommended_3_Langs.Entries); - private MatrixMetadata Actual_1Lang_With_Table_Level_Units_And_Precision { get; } = + private MatrixMetadata Actual_1Lang_With_Table_Level_Units_And_Precision { get; } = new MatrixMetadataBuilder().Build(PxFileMetaEntries_Robust_1_Language_With_Table_Level_Units_And_Precision.Entries); [TestMethod] @@ -29,7 +27,7 @@ public void IEnumerableBuildTest() MatrixMetadata meta = builder.Build(PxFileMetaEntries_Robust_3_Languages.Entries); Assert.IsNotNull(meta); } - + [TestMethod] public void DictionaryBuildTest() { @@ -70,7 +68,7 @@ public void SingleLangTableLevelMetaLanguageTests() [DataRow("20240131 08:00", "NEXT-UPDATE")] public void MultiLangTableLevelAdditionalNotTranslatedStringParametersTest(string expected, string keyWord) { - if(Actual_3Lang.AdditionalProperties[keyWord] is StringProperty asp) + if (Actual_3Lang.AdditionalProperties[keyWord] is StringProperty asp) { Assert.AreEqual(expected, asp.Value); } @@ -84,7 +82,7 @@ public void MultiLangTableLevelAdditionalNotTranslatedStringParametersTest(strin [DataRow(true, "OFFICIAL-STATISTICS")] public void MultiLangTableLevelAdditionalBoolParametersTest(bool expected, string keyWord) { - if(Actual_3Lang.AdditionalProperties[keyWord] is BooleanProperty abp) + if (Actual_3Lang.AdditionalProperties[keyWord] is BooleanProperty abp) { Assert.AreEqual(expected, abp.Value); } @@ -102,7 +100,7 @@ public void MultiLangTableLevelAdditionalBoolParametersTest(bool expected, strin [DataRow("20240131 08:00", "NEXT-UPDATE")] public void SingleLangTableLevelAdditionalNotTranslatedParametersTest(string expected, string keyWord) { - if(Actual_1Lang.AdditionalProperties[keyWord] is StringProperty asp) + if (Actual_1Lang.AdditionalProperties[keyWord] is StringProperty asp) { Assert.AreEqual(expected, asp.Value); } @@ -116,7 +114,7 @@ public void SingleLangTableLevelAdditionalNotTranslatedParametersTest(string exp [DataRow(true, "OFFICIAL-STATISTICS")] public void SingleLangTableLevelAdditionalNotTranslatedParametersTest(bool expected, string keyWord) { - if(Actual_1Lang.AdditionalProperties[keyWord] is BooleanProperty abp) + if (Actual_1Lang.AdditionalProperties[keyWord] is BooleanProperty abp) { Assert.AreEqual(expected, abp.Value); } @@ -149,7 +147,7 @@ public void MultiLangTableLevelAdditionalTranslatedParametersTest(string fi, str [DataRow("test_note_fi", "NOTE")] public void SingleLangTableLevelAdditionalTranslatedParametersTest(string input, string keyWord) { - if(Actual_1Lang.AdditionalProperties[keyWord] is StringProperty msp) + if (Actual_1Lang.AdditionalProperties[keyWord] is StringProperty msp) { Assert.AreEqual(input, msp.Value); } @@ -220,11 +218,11 @@ public void SingleLangWithTableLevelUnitsAndPrecisionBuildTest() new("fi", "%"), new("fi", "lukumäärä") ]; - for(int i = 0; i < contentDimension.Values.Count; i++) + for (int i = 0; i < contentDimension.Values.Count; i++) { Assert.AreEqual(expectedUnits[i], contentDimension.Values[i].Unit); } - for(int i = 0; i < contentDimension.Values.Count; i++) + for (int i = 0; i < contentDimension.Values.Count; i++) { Assert.AreEqual(1, contentDimension.Values[i].Precision); } @@ -408,7 +406,7 @@ public void MultiLangDefaultDimensionValueTest() { Dimension? building_type_dim = Actual_3Lang.Dimensions.Find(d => d.Code == "Talotyyppi"); Assert.IsNotNull(building_type_dim); - if(building_type_dim.AdditionalProperties["ELIMINATION"] is MultilanguageStringProperty msp) + if (building_type_dim.AdditionalProperties["ELIMINATION"] is MultilanguageStringProperty msp) { MultilanguageString expected = new([new("fi", "Talotyypit yhteensä"), new("sv", "Hustyp totalt"), new("en", "Building types total")]); Assert.AreEqual(expected, msp.Value); @@ -424,7 +422,7 @@ public void SingleLangDefaultDimensionValueTest() { Dimension? building_type_dim = Actual_1Lang.Dimensions.Find(d => d.Code == "Talotyyppi"); Assert.IsNotNull(building_type_dim); - if(building_type_dim.AdditionalProperties["ELIMINATION"] is StringProperty msp) + if (building_type_dim.AdditionalProperties["ELIMINATION"] is StringProperty msp) { Assert.AreEqual("Talotyypit yhteensä", msp.Value); } diff --git a/Px.Utils.UnitTests/ModelTests/ExtensionTests/MatrixMapExtensionTests.cs b/Px.Utils.UnitTests/ModelTests/ExtensionTests/MatrixMapExtensionTests.cs new file mode 100644 index 0000000..b8d77d9 --- /dev/null +++ b/Px.Utils.UnitTests/ModelTests/ExtensionTests/MatrixMapExtensionTests.cs @@ -0,0 +1,219 @@ +using Px.Utils.Models.Metadata; +using Px.Utils.Models.Metadata.ExtensionMethods; + +namespace Px.Utils.UnitTests.ModelTests.ExtensionTests +{ + [TestClass] + public class MatrixMapExtensionTests + { + [TestMethod] + public void WhenCalledWithItselfShouldReturnTrue() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + // Act and Assert + Assert.IsTrue(map.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithSubmapShouldReturnTrue() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["aa11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33"]), + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsTrue(subMap.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithSubmapWithoutfirstValuesShouldReturnTrue() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["bb11", "cc11"]), + new DimensionMap("22", ["bb22"]), + new DimensionMap("33", ["bb33", "cc33", "dd33"]), + + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsTrue(subMap.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithSizeOneSubmapShouldReturnTrue() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["cc11"]), + new DimensionMap("22", ["bb22"]), + new DimensionMap("33", ["cc33"]), + + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsTrue(subMap.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithDifferentDimensionOrderShouldReturnFalse() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + new DimensionMap("22", ["aa22", "bb22"]), + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsFalse(subMap.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithDifferentValuesShouldReturnFalse() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33", "ee33"]), + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsFalse(subMap.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithDifferentNumberOfDimensionsShouldReturnFalse() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsFalse(subMap.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithDifferenValueOrderShouldReturnFalse() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "cc33", "bb33"]), + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsFalse(subMap.IsSubmapOf(map)); + } + + [TestMethod] + public void WhenCalledWithNotMatchingValueCodesShouldReturnFalse() + { + // Arrange + List dimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["aa22", "bb22"]), + new DimensionMap("33", ["aa33", "bb33", "cc33", "dd33"]), + ]; + + MatrixMap map = new(dimensions); + + List subDimensions = [ + new DimensionMap("11", ["aa11", "bb11", "cc11"]), + new DimensionMap("22", ["foo", "bb22"]), + new DimensionMap("33", ["aa33", "bar"]), + ]; + + MatrixMap subMap = new(subDimensions); + + // Act and Assert + Assert.IsFalse(subMap.IsSubmapOf(map)); + } + + } +} diff --git a/Px.Utils.UnitTests/PxFileTests/DataTests/DataIndexerTests.cs b/Px.Utils.UnitTests/PxFileTests/DataTests/DataIndexerTests.cs index 79be19f..2f1520b 100644 --- a/Px.Utils.UnitTests/PxFileTests/DataTests/DataIndexerTests.cs +++ b/Px.Utils.UnitTests/PxFileTests/DataTests/DataIndexerTests.cs @@ -174,5 +174,32 @@ public void ThreeDimensions3val2val5valMultidimensionalReorderingTestWithDimOrde } while (generator.Next()); } + + [TestMethod] + public void MismatchingValueCodesShouldCauseArgumentException() + { + MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([3, 2, 5]); + MatrixMap matrixMap = new( + [ + new DimensionMap("var0", ["var0_val2", "var0_val1"]), + new DimensionMap("var1", ["var2_val0", "var1_val1"]), + new DimensionMap("var2", ["var2_val4", "var2_val3"]) + ]); + + Assert.ThrowsException(() => new DataIndexer(testMeta, matrixMap)); + } + + [TestMethod] + public void MissingDimensionShouldCauseArgumentException() + { + MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([3, 2, 5]); + MatrixMap matrixMap = new( + [ + new DimensionMap("var0", ["var0_val2", "var0_val1"]), + new DimensionMap("var1", ["var1_val0", "var1_val1"]) + ]); + + Assert.ThrowsException(() => new DataIndexer(testMeta, matrixMap)); + } } } diff --git a/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/AsyncDataReaderTests.cs b/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/AsyncDataReaderTests.cs index c9efbd6..c185846 100644 --- a/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/AsyncDataReaderTests.cs +++ b/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/AsyncDataReaderTests.cs @@ -26,14 +26,13 @@ public async Task ReadDoubleDataValuesAsyncValidIntegersReturnsCorrectDoubleData // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); double[] expexted = [ @@ -59,14 +58,13 @@ public async Task ReadDoubleDataValuesAsyncValidIntegersWithSmallBufferReturnsCo // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); double[] expexted = [ @@ -92,14 +90,13 @@ public async Task ReadDoubleDataValuesAsyncValidIntegersAndMissingReturnsCorrect // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert DoubleDataValue[] expexted = @@ -131,14 +128,13 @@ public async Task ReadDoubleDataValuesAsyncWithCancellationTokenValidIntegersRet // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), - new DimensionMap("var2", ["var1_val0"]) + new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer, cToken); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta, cToken); double[] expexted = [0.00, 2.00, 4.00, 6.00, 8.00, canary]; // The canary in the expected checks against overwrites @@ -156,19 +152,18 @@ public async Task CancelReadDoubleDataValuesAsyncValidIntegersIsCancelled() DoubleDataValue[] targetBuffer = new DoubleDataValue[5]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var1_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); using CancellationTokenSource cts = new(); await cts.CancelAsync(); CancellationToken cToken = cts.Token; - async Task call() => await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer, cToken); + async Task call() => await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta, cToken); await Assert.ThrowsExceptionAsync(call); } @@ -186,14 +181,13 @@ public async Task ReadDecimalDataValuesAsyncWithCancellationTokenValidIntegersRe // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, indexer, cToken); + await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, targetMap, testMeta, cToken); decimal[] expexted = [ @@ -215,19 +209,18 @@ public async Task CancelReadAddDecimalDataValuesAsyncValidIntegersIsCancelled() // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); using CancellationTokenSource cts = new(); await cts.CancelAsync(); CancellationToken cToken = cts.Token; - async Task call() => await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, indexer, cToken); + async Task call() => await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, targetMap, testMeta, cToken); await Assert.ThrowsExceptionAsync(call); } @@ -245,14 +238,13 @@ public async Task ReadUnsafeDoubleValuesAsyncWithCancellationTokenValidIntegersR // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, indexer, missingMarkers, cToken); + await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, targetMap, testMeta, missingMarkers, cToken); double[] expexted = [ @@ -274,20 +266,19 @@ public async Task CancelReadUnsafeDoubleValuesAsyncValidIntegersIsCancelled() double[] targetBuffer = new double[20]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); using CancellationTokenSource cts = new(); await cts.CancelAsync(); CancellationToken cToken = cts.Token; // Act and Assert - async Task call() => await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, indexer, missingMarkers, cToken); + async Task call() => await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, targetMap, testMeta, missingMarkers, cToken); await Assert.ThrowsExceptionAsync(call); } @@ -304,14 +295,13 @@ public async Task ReadEveryOtherDoubleDataValueFrom1stRowAsyncValidIntegersRetur // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), - new DimensionMap("var2", ["var1_val0"]) + new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); double[] expexted = [0.00, 2.00, 4.00, 6.00, 8.00, canary]; @@ -332,14 +322,13 @@ public async Task ReadEveryOtherDoubleDataValueFrom2ndRowAsyncValidIntegersRetur // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), - new DimensionMap("var2", ["var1_val0"]) + new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = [10.00, 12.00, 14.00, 16.00, 18.00]; @@ -357,14 +346,13 @@ public async Task ReadDoubleDataValuesAsyncValidDecimalsReturnsCorrectDoubleData // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = @@ -387,14 +375,13 @@ public async Task ReadEveryOtherDoubleDataValueFrom1stRowAsyncValidDecimalsRetur // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), - new DimensionMap("var2", ["var1_val0"]) + new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = [0.00, 0.02, 0.04, 0.06, 0.08]; @@ -412,14 +399,13 @@ public async Task ReadEveryOtherDoubleDataValueFrom2ndRowAsyncValidDecimalsRetur // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), - new DimensionMap("var2", ["var1_val0"]) + new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = [0.10, 0.12, 0.14, 0.16, 0.18]; @@ -437,14 +423,13 @@ public async Task EveryValueOnSeparateRowsAsyncValidDecimalsReturnsCorrectDouble // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = @@ -467,14 +452,13 @@ public async Task ReadAddDecimalDataValuesAsyncValidIntegersReturnsCorrectDecima // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert decimal[] expexted = @@ -497,14 +481,13 @@ public async Task ReadDecimalDataValuesAsyncValidDecimalsReturnsCorrectDecimalDa // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, indexer); + await reader.ReadDecimalDataValuesAsync(targetBuffer, 0, targetMap, testMeta); // Assert decimal[] expexted = @@ -527,14 +510,13 @@ public async Task ReadUnsafeDoubleValuesAsyncValidIntegersReturnsCorrectDoubleDa // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, indexer, missingMarkers); + await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, targetMap, testMeta, missingMarkers); // Assert double[] expexted = @@ -557,14 +539,13 @@ public async Task ReadUnsafeDoubleValuesAsyncValidDecimalsReturnsCorrectDoubleDa // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0", "var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, indexer, missingMarkers); + await reader.ReadUnsafeDoublesAsync(targetBuffer, 0, targetMap, testMeta, missingMarkers); // Assert double[] expexted = @@ -575,7 +556,5 @@ public async Task ReadUnsafeDoubleValuesAsyncValidDecimalsReturnsCorrectDoubleDa CollectionAssert.AreEqual(expexted, targetBuffer); } - - } } diff --git a/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/DataReaderTests.cs b/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/DataReaderTests.cs index a300f50..9c69665 100644 --- a/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/DataReaderTests.cs +++ b/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/DataReaderTests.cs @@ -32,8 +32,7 @@ public void ReadDoubleDataValuesValidIntegersReturnsCorrectDoubleDataValues() new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap); // Assert double[] expexted = @@ -65,8 +64,7 @@ public void ReadDoubleDataValuesValidIntegersWithSmallBufferReturnsCorrectDouble new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap); // Assert double[] expexted = @@ -98,8 +96,7 @@ public void ReadDoubleDataValuesValidIntegersAndMissingReturnsCorrectDoubleDataV new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap); // Assert DoubleDataValue[] expexted = @@ -128,14 +125,13 @@ public void ReadEveryOtherDoubleDataValueFrom1stRowValidIntegersReturnsCorrectDo // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = [0.00, 2.00, 4.00, 6.00, 8.00, canary]; @@ -155,14 +151,13 @@ public void ReadEveryOtherDoubleDataValueFrom2ndRowValidIntegersReturnsCorrectDo // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = [10.00, 12.00, 14.00, 16.00, 18.00]; @@ -186,8 +181,7 @@ public void ReadDoubleDataValuesValidDecimalsReturnsCorrectDoubleDataValues() new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap); // Assert double[] expexted = @@ -210,14 +204,13 @@ public void ReadEveryOtherDoubleDataValueFrom1stRowValidDecimalsReturnsCorrectDo // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = [0.00, 0.02, 0.04, 0.06, 0.08]; @@ -235,14 +228,13 @@ public void ReadEveryOtherDoubleDataValueFrom2ndRowValidDecimalsReturnsCorrectDo // Act MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 5, 2]); - MatrixMap matrixMap = new( + MatrixMap targetMap = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap, testMeta); // Assert double[] expexted = [0.10, 0.12, 0.14, 0.16, 0.18]; @@ -266,8 +258,7 @@ public void EveryValueOnSeparateRowsValidDecimalsReturnsCorrectDoubleDataValues( new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer); + reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap); // Assert double[] expexted = @@ -296,8 +287,7 @@ public void ReadDecimalDataValuesValidIntegersReturnsCorrectDoubleDataValues() new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDecimalDataValues(targetBuffer, 0, indexer); + reader.ReadDecimalDataValues(targetBuffer, 0, testMeta, matrixMap); // Assert decimal[] expexted = @@ -326,8 +316,7 @@ public void ReadDecimalDataValuesValidDecimalsReturnsCorrectDoubleDataValues() new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadDecimalDataValues(targetBuffer, 0, indexer); + reader.ReadDecimalDataValues(targetBuffer, 0, testMeta, matrixMap); // Assert decimal[] expexted = @@ -356,8 +345,7 @@ public void ReadUnsafeDoubleValuesValidIntegersReturnsCorrectDoubleDataValues() new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadUnsafeDoubles(targetBuffer, 0, indexer, missingMarkers); + reader.ReadUnsafeDoubles(targetBuffer, 0, testMeta, matrixMap, missingMarkers); // Assert double[] expexted = @@ -386,8 +374,7 @@ public void ReadUnsafeDoubleValuesValidDecimalsReturnsCorrectDoubleDataValues() new DimensionMap("var1", ["var1_val0", "var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer = new(testMeta, matrixMap); - reader.ReadUnsafeDoubles(targetBuffer, 0, indexer, missingMarkers); + reader.ReadUnsafeDoubles(targetBuffer, 0, testMeta, matrixMap, missingMarkers); // Assert double[] expexted = @@ -398,5 +385,49 @@ public void ReadUnsafeDoubleValuesValidDecimalsReturnsCorrectDoubleDataValues() CollectionAssert.AreEqual(expexted, targetBuffer); } + + [TestMethod] + public void ReadDoubleDataValuesInWrongOrderThrowsArgumentException() + { + // Arrange + byte[] data = Encoding.UTF8.GetBytes(DataReaderFixtures.MINIMAL_UTF8_20DATAVALUES); + using Stream stream = new MemoryStream(data); + using PxFileStreamDataReader reader = new(stream); + DoubleDataValue[] targetBuffer = new DoubleDataValue[20]; + + // Act + MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); + MatrixMap matrixMap = new( + [ + new DimensionMap("var0", ["var0_val1", "var0_val0"]), + new DimensionMap("var1", ["var1_val0", "var1_val1"]), + new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) + ]); + + // Assert + Assert.ThrowsException(() => reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap)); + } + + [TestMethod] + public void ReadDoubleDataDimensionsInWrongOrderThrowsArgumentException() + { + // Arrange + byte[] data = Encoding.UTF8.GetBytes(DataReaderFixtures.MINIMAL_UTF8_20DATAVALUES); + using Stream stream = new MemoryStream(data); + using PxFileStreamDataReader reader = new(stream); + DoubleDataValue[] targetBuffer = new DoubleDataValue[20]; + + // Act + MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]); + MatrixMap matrixMap = new( + [ + new DimensionMap("var0", ["var0_val0", "var0_val1"]), + new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]), + new DimensionMap("var1", ["var1_val0", "var1_val1"]) + ]); + + // Assert + Assert.ThrowsException(() => reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap)); + } } } diff --git a/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/MultiPartReadingTests.cs b/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/MultiPartReadingTests.cs index d91319b..56cb944 100644 --- a/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/MultiPartReadingTests.cs +++ b/Px.Utils.UnitTests/PxFileTests/DataTests/PxFileStreamDataReaderTests/MultiPartReadingTests.cs @@ -1,11 +1,10 @@ using Px.Utils.Models.Metadata; using Px.Utils.PxFile.Data; -using Px.Utils.UnitTests; using PxFileTests.Fixtures; using Px.Utils.Models.Data.DataValue; using System.Text; -namespace PxFileTests.DataTests.PxFileStreamDataReaderTests +namespace Px.Utils.UnitTests.PxFileTests.DataTests.PxFileStreamDataReaderTests { [TestClass] public class MultiPartReadingTests @@ -23,28 +22,26 @@ public void ReadDoubleDataValuesOneRowAtTimeReturnsCorrectDoubleDataValues() int[] testDimLengths_2_5_2 = [2, 5, 2]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata(testDimLengths_2_5_2); - MatrixMap matrixMap0 = new( + MatrixMap targetMap0 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0", "var2_val1"]) ]); - DataIndexer indexer0 = new(testMeta, matrixMap0); double[] expected0 = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer0); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap0, testMeta); CollectionAssert.AreEqual(expected0, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap1 = new( + MatrixMap targetMap1 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0", "var2_val1"]) ]); - DataIndexer indexer1 = new(testMeta, matrixMap1); double[] expected1 = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer1); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap1, testMeta); CollectionAssert.AreEqual(expected1, targetBuffer.Select(v => v.UnsafeValue).ToArray()); } @@ -60,28 +57,26 @@ public void ReadDoubleDataValuesOneRowAtTimeWithSmallBufferReturnsCorrectDoubleD // Act and Assert int[] testDimLengths_2_5_2 = [2, 5, 2]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata(testDimLengths_2_5_2); - MatrixMap matrixMap0 = new( + MatrixMap targetMap0 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0", "var2_val1"]) ]); - DataIndexer indexer0 = new(testMeta, matrixMap0); double[] expected0 = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer0); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap0, testMeta); CollectionAssert.AreEqual(expected0, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap1 = new( + MatrixMap targetMap1 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0", "var2_val1"]) ]); - DataIndexer indexer1 = new(testMeta, matrixMap1); double[] expected1 = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer1); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap1, testMeta); CollectionAssert.AreEqual(expected1, targetBuffer.Select(v => v.UnsafeValue).ToArray()); } @@ -98,37 +93,34 @@ public void ReadDoubleDataValuesHalfRowAtTimeReturnsCorrectDoubleDataValues() int[] testDimLengths_2_2_5 = [2, 2, 5]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata(testDimLengths_2_2_5); - MatrixMap matrixMap0 = new( + MatrixMap targetMap0 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer0 = new(testMeta, matrixMap0); double[] expected0 = [0.0, 1.0, 2.0, 3.0, 4.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer0); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap0, testMeta); CollectionAssert.AreEqual(expected0, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap1 = new( + MatrixMap targetMap1 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer1 = new(testMeta, matrixMap1); double[] expected1 = [5.0, 6.0, 7.0, 8.0, 9.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer1); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap1, testMeta); CollectionAssert.AreEqual(expected1, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap2 = new( + MatrixMap targetMap2 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer2 = new(testMeta, matrixMap2); double[] expected2 = [10.0, 11.0, 12.0, 13.0, 14.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer2); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap2, testMeta); CollectionAssert.AreEqual(expected2, targetBuffer.Select(v => v.UnsafeValue).ToArray()); MatrixMap matrixMap3 = new( @@ -137,9 +129,8 @@ public void ReadDoubleDataValuesHalfRowAtTimeReturnsCorrectDoubleDataValues() new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer3 = new(testMeta, matrixMap3); double[] expected3 = [15.0, 16.0, 17.0, 18.0, 19.0]; - reader.ReadDoubleDataValues(targetBuffer, 0, indexer3); + reader.ReadDoubleDataValues(targetBuffer, 0, matrixMap3, testMeta); CollectionAssert.AreEqual(expected3, targetBuffer.Select(v => v.UnsafeValue).ToArray()); } @@ -156,64 +147,58 @@ public void ReadDoubleDataValuesOneColAtTimeReturnsCorrectDoubleDataValues() // Act and Assert int[] testDimLengths_2_2_5 = [2, 2, 5]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata(testDimLengths_2_2_5); - MatrixMap matrixMap0 = new( + MatrixMap targetMap0 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer0 = new(testMeta, matrixMap0); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer0); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap0, testMeta); Assert.AreEqual(0.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap1 = new( + MatrixMap targetMap1 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val1"]) ]); - DataIndexer indexer1 = new(testMeta, matrixMap1); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer1); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap1, testMeta); Assert.AreEqual(1.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap2 = new( + MatrixMap targetMap2 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val4"]) ]); - DataIndexer indexer2 = new(testMeta, matrixMap2); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer2); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap2, testMeta); Assert.AreEqual(9.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap3 = new( + MatrixMap targetMap3 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer3 = new(testMeta, matrixMap3); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer3); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap3, testMeta); Assert.AreEqual(10.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap4 = new( + MatrixMap targetMap4 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val1"]) ]); - DataIndexer indexer4 = new(testMeta, matrixMap4); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer4); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap4, testMeta); Assert.AreEqual(11.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap5 = new( + MatrixMap targetMap5 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val4"]) ]); - DataIndexer indexer5 = new(testMeta, matrixMap5); - reader.ReadDoubleDataValues(targetBuffer, 0, indexer5); + reader.ReadDoubleDataValues(targetBuffer, 0, targetMap5, testMeta); Assert.AreEqual(19.0, targetBuffer[0].UnsafeValue); } @@ -230,28 +215,26 @@ public async Task ReadDoubleDataValuesAsycOneRowAtTimeReturnsCorrectDoubleDataVa int[] testDimLengths_2_5_2 = [2, 5, 2]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata(testDimLengths_2_5_2); - MatrixMap matrixMap0 = new( + MatrixMap targetMap0 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0", "var2_val1"]) ]); - DataIndexer indexer0 = new(testMeta, matrixMap0); double[] expected0 = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]; - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer0); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap0, testMeta); CollectionAssert.AreEqual(expected0, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap1 = new( + MatrixMap targetMap1 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0", "var1_val1", "var1_val2", "var1_val3", "var1_val4"]), new DimensionMap("var2", ["var2_val0", "var2_val1"]) ]); - DataIndexer indexer1 = new(testMeta, matrixMap1); double[] expected1 = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0]; - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer1); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap1, testMeta); CollectionAssert.AreEqual(expected1, targetBuffer.Select(v => v.UnsafeValue).ToArray()); } @@ -268,51 +251,47 @@ public async Task ReadDoubleDataValuesAsnycHalfRowAtTimeReturnsCorrectDoubleData int[] testDimLengths_2_2_5 = [2, 2, 5]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata(testDimLengths_2_2_5); - MatrixMap matrixMap0 = new( + MatrixMap targetMap0 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer0 = new(testMeta, matrixMap0); double[] expected0 = [0.0, 1.0, 2.0, 3.0, 4.0]; - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer0); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap0, testMeta); CollectionAssert.AreEqual(expected0, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap1 = new( + MatrixMap targetMap1 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer1 = new(testMeta, matrixMap1); double[] expected1 = [5.0, 6.0, 7.0, 8.0, 9.0]; - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer1); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap1, testMeta); CollectionAssert.AreEqual(expected1, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap2 = new( + MatrixMap targetMap2 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer2 = new(testMeta, matrixMap2); double[] expected2 = [10.0, 11.0, 12.0, 13.0, 14.0]; - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer2); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap2, testMeta); CollectionAssert.AreEqual(expected2, targetBuffer.Select(v => v.UnsafeValue).ToArray()); - MatrixMap matrixMap3 = new( + MatrixMap targetMap3 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"]) ]); - DataIndexer indexer3 = new(testMeta, matrixMap3); double[] expected3 = [15.0, 16.0, 17.0, 18.0, 19.0]; - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer3); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap3, testMeta); CollectionAssert.AreEqual(expected3, targetBuffer.Select(v => v.UnsafeValue).ToArray()); } @@ -329,64 +308,58 @@ public async Task ReadDoubleDataValuesAsnycOneColAtTimeReturnsCorrectDoubleDataV int[] testDimLengths_2_2_5 = [2, 2, 5]; MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata(testDimLengths_2_2_5); - MatrixMap matrixMap0 = new( + MatrixMap targetMap0 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer0 = new(testMeta, matrixMap0); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer0); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap0, testMeta); Assert.AreEqual(0.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap1 = new( + MatrixMap targetMap1 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val1"]) ]); - DataIndexer indexer1 = new(testMeta, matrixMap1); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer1); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap1, testMeta); Assert.AreEqual(1.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap2 = new( + MatrixMap targetMap2 = new( [ new DimensionMap("var0", ["var0_val0"]), new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val4"]) ]); - DataIndexer indexer2 = new(testMeta, matrixMap2); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer2); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap2, testMeta); Assert.AreEqual(9.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap3 = new( + MatrixMap targetMap3 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val0"]) ]); - DataIndexer indexer3 = new(testMeta, matrixMap3); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer3); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap3, testMeta); Assert.AreEqual(10.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap4 = new( + MatrixMap targetMap4 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val0"]), new DimensionMap("var2", ["var2_val1"]) ]); - DataIndexer indexer4 = new(testMeta, matrixMap4); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer4); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap4, testMeta); Assert.AreEqual(11.0, targetBuffer[0].UnsafeValue); - MatrixMap matrixMap5 = new( + MatrixMap targetMap5 = new( [ new DimensionMap("var0", ["var0_val1"]), new DimensionMap("var1", ["var1_val1"]), new DimensionMap("var2", ["var2_val4"]) ]); - DataIndexer indexer5 = new(testMeta, matrixMap5); - await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, indexer5); + await reader.ReadDoubleDataValuesAsync(targetBuffer, 0, targetMap5, testMeta); Assert.AreEqual(19.0, targetBuffer[0].UnsafeValue); } } diff --git a/Px.Utils/Models/Metadata/ExtensionMethods/MatrixMapExtensions.cs b/Px.Utils/Models/Metadata/ExtensionMethods/MatrixMapExtensions.cs index 2fe5376..5b1b614 100644 --- a/Px.Utils/Models/Metadata/ExtensionMethods/MatrixMapExtensions.cs +++ b/Px.Utils/Models/Metadata/ExtensionMethods/MatrixMapExtensions.cs @@ -34,5 +34,35 @@ public static IMatrixMap CollapseDimension(this IMatrixMap matrixMap, string dim } return new MatrixMap(newDimensionMaps); } + + /// + /// Checks if the other map contains the same dimensions and values as this map in the same order. + /// The other map can contain values that are not found in this map. + /// + /// True if all of the values are found in the correct order. + public static bool IsSubmapOf(this IMatrixMap thisMap, IMatrixMap other) + { + if(thisMap.DimensionMaps.Count != other.DimensionMaps.Count) return false; + for (int i = 0; i < thisMap.DimensionMaps.Count; i++) + { + if (other.DimensionMaps[i].Code != thisMap.DimensionMaps[i].Code) return false; + int sourceIndex = 0; + for (int j = 0; j < thisMap.DimensionMaps[i].ValueCodes.Count; j++) + { + bool found = false; + for(int k = sourceIndex; k < other.DimensionMaps[i].ValueCodes.Count; k++) + { + if (other.DimensionMaps[i].ValueCodes[k] == thisMap.DimensionMaps[i].ValueCodes[j]) + { + sourceIndex = k + 1; + found = true; + break; + } + } + if(!found) return false; + } + } + return true; + } } } diff --git a/Px.Utils/PxFile/Data/DataIndexer.cs b/Px.Utils/PxFile/Data/DataIndexer.cs index 323471b..c466914 100644 --- a/Px.Utils/PxFile/Data/DataIndexer.cs +++ b/Px.Utils/PxFile/Data/DataIndexer.cs @@ -29,6 +29,11 @@ public sealed class DataIndexer /// Produces the indexes of the items decribed by this map. public DataIndexer(IMatrixMap completeMetaMap, IMatrixMap targetMap) { + if (completeMetaMap.DimensionMaps.Count != targetMap.DimensionMaps.Count) + { + throw new ArgumentException("The number of dimensions in the complete metadata map and the target map must be the same."); + } + int[] dimensionSizes = completeMetaMap.DimensionMaps.Select(d => d.ValueCodes.Count).ToArray(); _coordinates = new int[targetMap.DimensionMaps.Count][]; _dimOrder = GetDimensionOrder(completeMetaMap, targetMap); @@ -37,15 +42,23 @@ public DataIndexer(IMatrixMap completeMetaMap, IMatrixMap targetMap) int dimIndex = _dimOrder[targetIndex]; IDimensionMap dimension = completeMetaMap.DimensionMaps.First(d => d.Code == targetMap.DimensionMaps[targetIndex].Code); _coordinates[dimIndex] = new int[targetMap.DimensionMaps[targetIndex].ValueCodes.Count]; - for (int mapIndex = 0; mapIndex < targetMap.DimensionMaps[targetIndex].ValueCodes.Count; mapIndex++) + IDimensionMap targetDimMap = targetMap.DimensionMaps[targetIndex]; + for (int mapIndex = 0; mapIndex < targetDimMap.ValueCodes.Count; mapIndex++) { + bool found = false; for (int valIndex = 0; valIndex < dimension.ValueCodes.Count; valIndex++) { - if (dimension.ValueCodes[valIndex] == targetMap.DimensionMaps[targetIndex].ValueCodes[mapIndex]) + if (dimension.ValueCodes[valIndex] == targetDimMap.ValueCodes[mapIndex]) { _coordinates[dimIndex][mapIndex] = valIndex; + found = true; } } + if(!found) + { + string msg = $"The value code '{targetDimMap.ValueCodes[mapIndex]}' was not found in the dimension '{targetDimMap.Code}' of the complete metadata map."; + throw new ArgumentException(msg); + } } } diff --git a/Px.Utils/PxFile/Data/IPxFileStreamDataReader.cs b/Px.Utils/PxFile/Data/IPxFileStreamDataReader.cs index 2e1d7dd..f4a4cbc 100644 --- a/Px.Utils/PxFile/Data/IPxFileStreamDataReader.cs +++ b/Px.Utils/PxFile/Data/IPxFileStreamDataReader.cs @@ -1,4 +1,5 @@ using Px.Utils.Models.Data.DataValue; +using Px.Utils.Models.Metadata; namespace Px.Utils.PxFile.Data { @@ -9,34 +10,38 @@ public interface IPxFileStreamDataReader /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. /// An array of values that represent missing data. - public void ReadUnsafeDoubles(double[] buffer, int offset, DataIndexer indexer, double[] missingValueEncodings); + public void ReadUnsafeDoubles(double[] buffer, int offset, IMatrixMap target, IMatrixMap complete, double[] missingValueEncodings); /// /// Reads a specified set of data values into a buffer as instances. /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public void ReadDoubleDataValues(DoubleDataValue[] buffer, int offset, DataIndexer indexer); + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. + public void ReadDoubleDataValues(DoubleDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete); /// /// Reads a specified set of data values into a buffer as instances. /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public void ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, DataIndexer indexer); + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. + public void ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete); /// /// Asynchronously reads a specified set of data values into a buffer as s. /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. /// An array of values that represent missing data. - public Task ReadUnsafeDoublesAsync(double[] buffer, int offset, DataIndexer indexer, double[] missingValueEncodings); + public Task ReadUnsafeDoublesAsync(double[] buffer, int offset, IMatrixMap target, IMatrixMap complete, double[] missingValueEncodings); /// /// Asynchronously reads a specified set of data values into a buffer as s. @@ -44,18 +49,20 @@ public interface IPxFileStreamDataReader /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. /// An array of double values that represent missing data. /// A to observe while waiting for the task to complete. - public Task ReadUnsafeDoublesAsync(double[] buffer, int offset, DataIndexer indexer, double[] missingValueEncodings, CancellationToken cancellationToken); + public Task ReadUnsafeDoublesAsync(double[] buffer, int offset, IMatrixMap target, IMatrixMap complete, double[] missingValueEncodings, CancellationToken cancellationToken); /// /// Asynchronously reads a specified set of data values into a buffer as instances. /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, DataIndexer indexer); + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. + public Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete); /// /// Asynchronously reads a specified set of data values into a buffer as instances. @@ -63,17 +70,19 @@ public interface IPxFileStreamDataReader /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. /// A CancellationToken to observe while waiting for the task to complete. - public Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, DataIndexer indexer, CancellationToken cancellationToken); + public Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete, CancellationToken cancellationToken); /// /// Asynchronously reads a specified set of data values into a buffer as instances. /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, DataIndexer indexer); + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. + public Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete); /// /// Asynchronously reads a specified set of data values into a buffer as instances. @@ -81,8 +90,9 @@ public interface IPxFileStreamDataReader /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// The target matrix map to read the data from. + /// The complete matrix map to read the data from. /// A CancellationToken to observe while waiting for the task to complete. - public Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, DataIndexer indexer, CancellationToken cancellationToken); + public Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete, CancellationToken cancellationToken); } } diff --git a/Px.Utils/PxFile/Data/PxFileStreamDataReader.cs b/Px.Utils/PxFile/Data/PxFileStreamDataReader.cs index e7f5cf1..279322a 100644 --- a/Px.Utils/PxFile/Data/PxFileStreamDataReader.cs +++ b/Px.Utils/PxFile/Data/PxFileStreamDataReader.cs @@ -1,4 +1,6 @@ using Px.Utils.Models.Data.DataValue; +using Px.Utils.Models.Metadata; +using Px.Utils.Models.Metadata.ExtensionMethods; namespace Px.Utils.PxFile.Data { @@ -55,7 +57,8 @@ public PxFileStreamDataReader(Stream stream, long dataStart, PxFileSyntaxConf? c /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. /// /// An array of values that represent missing data in the PX file in the following order: /// [0] "-" @@ -66,11 +69,12 @@ public PxFileStreamDataReader(Stream stream, long dataStart, PxFileSyntaxConf? c /// [5] "....." /// [6] "......" /// - public void ReadUnsafeDoubles(double[] buffer, int offset, DataIndexer indexer, double[] missingValueEncodings) + /// Thrown when the target map is not a submap of the complete map." + public void ReadUnsafeDoubles(double[] buffer, int offset, IMatrixMap target, IMatrixMap complete, double[] missingValueEncodings) { SetReaderPositionIfZero(); - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, Parser); - + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, Parser); + double Parser(char[] parseBuffer, int len) { return DataValueParsers.FastParseUnsafeDoubleDangerous(parseBuffer, len, missingValueEncodings); @@ -84,11 +88,13 @@ double Parser(char[] parseBuffer, int len) /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public void ReadDoubleDataValues(DoubleDataValue[] buffer, int offset, DataIndexer indexer) + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. + /// Thrown when the target map is not a submap of the complete map."" + public void ReadDoubleDataValues(DoubleDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete) { SetReaderPositionIfZero(); - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, DataValueParsers.FastParseDoubleDataValueDangerous); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, DataValueParsers.FastParseDoubleDataValueDangerous); } /// @@ -98,11 +104,13 @@ public void ReadDoubleDataValues(DoubleDataValue[] buffer, int offset, DataIndex /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public void ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, DataIndexer indexer) + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. + /// Thrown when the target map is not a submap of the complete map. + public void ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete) { SetReaderPositionIfZero(); - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, DataValueParsers.FastParseDecimalDataValueDangerous); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, DataValueParsers.FastParseDecimalDataValueDangerous); } #endregion @@ -116,7 +124,8 @@ public void ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, DataInd /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. /// /// An array of values that represent missing data in the PX file in the following order: /// [0] "-" @@ -127,11 +136,12 @@ public void ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, DataInd /// [5] "....." /// [6] "......" /// - public async Task ReadUnsafeDoublesAsync(double[] buffer, int offset, DataIndexer indexer, double[] missingValueEncodings) + /// Thrown when the target map is not a submap of the complete map." + public async Task ReadUnsafeDoublesAsync(double[] buffer, int offset, IMatrixMap target, IMatrixMap complete, double[] missingValueEncodings) { await SetReaderPositionIfZeroAsync(); await Task.Factory.StartNew(() => - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, Parser)); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, Parser)); double Parser(char[] parseBuffer, int len) { @@ -147,7 +157,8 @@ double Parser(char[] parseBuffer, int len) /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. /// /// An array of values that represent missing data in the PX file in the following order: /// [0] "-" @@ -159,11 +170,12 @@ double Parser(char[] parseBuffer, int len) /// [6] "......" /// /// A to observe while waiting for the task to complete. - public async Task ReadUnsafeDoublesAsync(double[] buffer, int offset, DataIndexer indexer, double[] missingValueEncodings, CancellationToken cancellationToken) + /// Thrown when the target map is not a submap of the complete map." + public async Task ReadUnsafeDoublesAsync(double[] buffer, int offset, IMatrixMap target, IMatrixMap complete, double[] missingValueEncodings, CancellationToken cancellationToken) { await SetReaderPositionIfZeroAsync(cancellationToken); await Task.Factory.StartNew(() => - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, Parser, cancellationToken), cancellationToken); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, Parser, cancellationToken), cancellationToken); double Parser(char[] parseBuffer, int len) { @@ -178,12 +190,14 @@ double Parser(char[] parseBuffer, int len) /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public async Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, DataIndexer indexer) + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. + /// Thrown when the target map is not a submap of the complete map."" + public async Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete) { await SetReaderPositionIfZeroAsync(); await Task.Factory.StartNew(() => - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, DataValueParsers.FastParseDoubleDataValueDangerous)); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, DataValueParsers.FastParseDoubleDataValueDangerous)); } /// @@ -194,13 +208,15 @@ await Task.Factory.StartNew(() => /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. /// A to observe while waiting for the task to complete. - public async Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, DataIndexer indexer, CancellationToken cancellationToken) + /// Thrown when the target map is not a submap of the complete map. + public async Task ReadDoubleDataValuesAsync(DoubleDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete, CancellationToken cancellationToken) { await SetReaderPositionIfZeroAsync(cancellationToken); await Task.Factory.StartNew(() => - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, DataValueParsers.FastParseDoubleDataValueDangerous, cancellationToken), cancellationToken); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, DataValueParsers.FastParseDoubleDataValueDangerous, cancellationToken), cancellationToken); } /// @@ -210,12 +226,14 @@ await Task.Factory.StartNew(() => /// /// The buffer to store the read values. /// The starting index in the buffer to begin storing the read values. - /// Provides the indexes where the data will be read. - public async Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, DataIndexer indexer) + /// Map defining the data to be read. Must be a submap of the map. + /// Map defining the complete data set. + /// Thrown when the target map is not a submap of the complete map. + public async Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete) { await SetReaderPositionIfZeroAsync(); await Task.Factory.StartNew(() => - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, DataValueParsers.FastParseDecimalDataValueDangerous)); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, DataValueParsers.FastParseDecimalDataValueDangerous)); } /// @@ -228,11 +246,11 @@ await Task.Factory.StartNew(() => /// The starting index in the buffer to begin storing the read values. /// Provides the indexes where the data will be read. /// A to observe while waiting for the task to complete. - public async Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, DataIndexer indexer, CancellationToken cancellationToken) + public async Task ReadDecimalDataValuesAsync(DecimalDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete, CancellationToken cancellationToken) { await SetReaderPositionIfZeroAsync(cancellationToken); await Task.Factory.StartNew(() => - ReadItemsFromStreamByCoordinate(buffer, offset, indexer, DataValueParsers.FastParseDecimalDataValueDangerous, cancellationToken), cancellationToken); + ReadItemsFromStreamByCoordinate(buffer, offset, target, complete, DataValueParsers.FastParseDecimalDataValueDangerous, cancellationToken), cancellationToken); } #endregion @@ -275,8 +293,11 @@ private async Task SetReaderPositionIfZeroAsync(CancellationToken? cancellationT _stream.Position = start + dataKeyword.Length + 1; // +1 to skip the '=' } - private void ReadItemsFromStreamByCoordinate(T[] buffer, int offset, DataIndexer indexer, Func readItem, CancellationToken? token = null) + private void ReadItemsFromStreamByCoordinate(T[] buffer, int offset, IMatrixMap target, IMatrixMap complete, Func readItem, CancellationToken? token = null) { + if(!target.IsSubmapOf(complete)) throw new ArgumentException($"The {nameof(target)} map is not a submap of the {nameof(complete)} map."); + DataIndexer indexer = new(complete, target); + int startingIndex = offset; byte[] internalBuffer = new byte[_readBufferSize]; diff --git a/docs/README.md b/docs/README.md index eff21db..c120c2d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -52,23 +52,40 @@ Especially if the contents of your px-files do not follow the standard px-file f The entries need to be in the same key-value format as the output of the ```PxFileMetadataReader``` ```ReadMetadata``` method. #### PxFileStreamDataReader : IPxFileStreamDataReader, IDisposable - ```ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, DataIndexer indexer)``` reads data from the px-file into the provided buffer. There are simillary named methods for reading data in to other types of buffers. + ```ReadDecimalDataValues(DecimalDataValue[] buffer, int offset, IMatrixMap target, IMatrixMap complete)``` reads data from the px-file into the provided buffer. There are simillary named methods for reading data in to other types of buffers. The data will be written in to the buffer in order, starting form the offset. -The ```DataIndexer``` generates the indexes where the data will be read from. It can be built with the map of the complete file meta and other map (targetMap) which describes the values that will be read. - **IMPORTANT!** The target map must have the same order as the complete file map. This is for performance reasons, we do not want to move back and forth in the file or generate a second indexer for placing the data in the buffer. -Simple example for using the datareader: +### Metadata example +```csharp + // Read meta + using Stream pxFileStream = GetFileStream(); + PxFileMetadataReader reader = new(); + Encoding encoding = reader.GetEncoding(fileStream); + IEnumerable> entries = reader.ReadMetadata(fileStream, encoding); + + // Build meta + MatrixMetadataBuilder builder = new(); + MatrixMetadata completeMeta = builder.Build(entries); + MatrixMetadata metaWeUse = completeMeta.GetTransform(GetSomeSubsetMap()); +``` + +### Data reader example ```csharp - IReadOnlyMatrixMetadata metaWeUse = GetMetaFromSomewhere(); - IMatrixMap completeMap = GetCompleteMapFromSomewhere(); - - DataIndexer indexer = new(completeMap, meta); - Matrix output = new(meta, new DecimalDataValue[indexer.DataLength]); - using Stream fileStream = File.OpenRead(PATH_TO_PX_FILE); + // Read data & build the matrix + Matrix output = new(metaWeUse, new DecimalDataValue[indexer.DataLength]); + using Stream fileStream = GetFileStream(); using PxFileStreamDataReader dataReader = new(fileStream); - dataReader.ReadDecimalDataValues(output.Data, 0, indexer); + dataReader.ReadDecimalDataValues(output.Data, 0, metaWeUse, completeMap); +``` + +### Reader/builder configuration +Behaviour of the reader and builder objects can be changed with ```PxFileSyntaxConf``` object. +```csharp + PxFileSyntaxConf conf = PxFileSyntaxConf.Default; + conf.Content.PropertyTypeDefinitions["EXAMPLE"] = MetaPropertyType.TextArray; + MatrixMetadataBuilder builder = new(conf); ``` ### Metadata models