diff --git a/src/Microsoft.Data.Analysis/DateTimeComputation.cs b/src/Microsoft.Data.Analysis/DateTimeComputation.cs index 5335d30f87..ef052b4011 100644 --- a/src/Microsoft.Data.Analysis/DateTimeComputation.cs +++ b/src/Microsoft.Data.Analysis/DateTimeComputation.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; using System.Text; namespace Microsoft.Data.Analysis @@ -189,26 +191,35 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable throw new NotSupportedException(); } - public void Max(PrimitiveColumnContainer column, out DateTime ret) + public void Max(PrimitiveColumnContainer column, out DateTime? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var maxDate = DateTime.MinValue; + bool hasMaxValue = false; + for (int b = 0; b < column.Buffers.Count; b++) { - var buffer = column.Buffers[b]; - var readOnlySpan = buffer.ReadOnlySpan; + var readOnlySpan = column.Buffers[b].ReadOnlySpan; + var bitmapSpan = column.NullBitMapBuffers[b].ReadOnlySpan; for (int i = 0; i < readOnlySpan.Length; i++) { + //Check if bit is not set (value is null) - skip + if (!BitmapHelper.IsValid(bitmapSpan, i)) + continue; + var val = readOnlySpan[i]; - if (val > ret) + if (val > maxDate) { - ret = val; + maxDate = val; + hasMaxValue = true; } } } + + ret = hasMaxValue ? maxDate : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out DateTime ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out DateTime? ret) { ret = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; @@ -237,26 +248,36 @@ public void Max(PrimitiveColumnContainer column, IEnumerable row } } - public void Min(PrimitiveColumnContainer column, out DateTime ret) + public void Min(PrimitiveColumnContainer column, out DateTime? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var minDate = DateTime.MaxValue; + bool hasMinValue = false; + for (int b = 0; b < column.Buffers.Count; b++) { - var buffer = column.Buffers[b]; - var readOnlySpan = buffer.ReadOnlySpan; + var readOnlySpan = column.Buffers[b].ReadOnlySpan; + var bitmapSpan = column.NullBitMapBuffers[b].ReadOnlySpan; + for (int i = 0; i < readOnlySpan.Length; i++) { + //Check if bit is not set (value is null) - skip + if (!BitmapHelper.IsValid(bitmapSpan, i)) + continue; + var val = readOnlySpan[i]; - if (val < ret) + if (val < minDate) { - ret = val; + minDate = val; + hasMinValue = true; } } } + + ret = hasMinValue ? minDate : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out DateTime ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out DateTime? ret) { ret = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; @@ -285,22 +306,22 @@ public void Min(PrimitiveColumnContainer column, IEnumerable row } } - public void Product(PrimitiveColumnContainer column, out DateTime ret) + public void Product(PrimitiveColumnContainer column, out DateTime? ret) { throw new NotSupportedException(); } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out DateTime ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out DateTime? ret) { throw new NotSupportedException(); } - public void Sum(PrimitiveColumnContainer column, out DateTime ret) + public void Sum(PrimitiveColumnContainer column, out DateTime? ret) { throw new NotSupportedException(); } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out DateTime ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out DateTime? ret) { throw new NotSupportedException(); } diff --git a/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs b/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs index e482d834ec..745d1800e9 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs +++ b/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs @@ -12,8 +12,24 @@ namespace Microsoft.Data.Analysis { + internal static class BitmapHelper + { + // Faster to use when we already have a span since it avoids indexing + public static bool IsValid(ReadOnlySpan bitMapBufferSpan, int index) + { + int nullBitMapSpanIndex = index / 8; + byte thisBitMap = bitMapBufferSpan[nullBitMapSpanIndex]; + return IsBitSet(thisBitMap, index); + } + + public static bool IsBitSet(byte curBitMap, int index) + { + return ((curBitMap >> (index & 7)) & 1) != 0; + } + } + /// - /// PrimitiveDataFrameColumnContainer is just a store for the column data. APIs that want to change the data must be defined in PrimitiveDataFrameColumn + /// PrimitiveColumnContainer is just a store for the column data. APIs that want to change the data must be defined in PrimitiveDataFrameColumn /// /// internal partial class PrimitiveColumnContainer : IEnumerable @@ -224,7 +240,7 @@ public void ApplyElementwise(Func func) for (int i = 0; i < mutableBuffer.Length; i++) { long curIndex = i + prevLength; - bool isValid = IsValid(mutableNullBitMapBuffer, i); + bool isValid = BitmapHelper.IsValid(mutableNullBitMapBuffer, i); T? value = func(isValid ? mutableBuffer[i] : null, curIndex); mutableBuffer[i] = value.GetValueOrDefault(); SetValidityBit(mutableNullBitMapBuffer, i, value != null); @@ -247,7 +263,7 @@ public void Apply(Func func, PrimitiveColumnContainer(Func func, PrimitiveColumnContainer bitMapBufferSpan, int index) - { - int nullBitMapSpanIndex = index / 8; - byte thisBitMap = bitMapBufferSpan[nullBitMapSpanIndex]; - return IsBitSet(thisBitMap, index); - } - public bool IsValid(long index) => NullCount == 0 || GetValidityBit(index); private byte SetBit(byte curBitMap, int index, bool value) @@ -330,11 +338,6 @@ internal void SetValidityBit(long index, bool value) SetValidityBit(bitMapBuffer.Span, (int)index, value); } - private bool IsBitSet(byte curBitMap, int index) - { - return ((curBitMap >> (index & 7)) & 1) != 0; - } - private bool GetValidityBit(long index) { if ((uint)index >= Length) @@ -351,7 +354,7 @@ private bool GetValidityBit(long index) int bitMapBufferIndex = (int)((uint)index / 8); Debug.Assert(bitMapBuffer.Length > bitMapBufferIndex); byte curBitMap = bitMapBuffer[bitMapBufferIndex]; - return IsBitSet(curBitMap, (int)index); + return BitmapHelper.IsBitSet(curBitMap, (int)index); } public long Length; @@ -513,7 +516,7 @@ public PrimitiveColumnContainer Clone(PrimitiveColumnContainer mapIndic spanIndex = buffer.Length - 1 - i; long mapRowIndex = mapIndicesIntSpan.IsEmpty ? mapIndicesLongSpan[spanIndex] : mapIndicesIntSpan[spanIndex]; - bool mapRowIndexIsValid = mapIndices.IsValid(mapIndicesNullBitMapSpan, spanIndex); + bool mapRowIndexIsValid = BitmapHelper.IsValid(mapIndicesNullBitMapSpan, spanIndex); if (mapRowIndexIsValid && (mapRowIndex < minRange || mapRowIndex >= maxRange)) { int bufferIndex = (int)(mapRowIndex / maxCapacity); @@ -528,7 +531,7 @@ public PrimitiveColumnContainer Clone(PrimitiveColumnContainer mapIndic { mapRowIndex -= minRange; value = thisSpan[(int)mapRowIndex]; - isValid = IsValid(thisNullBitMapSpan, (int)mapRowIndex); + isValid = BitmapHelper.IsValid(thisNullBitMapSpan, (int)mapRowIndex); } retSpan[i] = isValid ? value : default; diff --git a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.cs b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.cs index 58e6a1e7c5..5501236c03 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.cs +++ b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.cs @@ -93,49 +93,49 @@ public override DataFrameColumn CumulativeSum(IEnumerable rowIndices, bool /// public override object Max() { - PrimitiveColumnComputation.Instance.Max(_columnContainer, out T ret); + PrimitiveColumnComputation.Instance.Max(_columnContainer, out T? ret); return ret; } /// public override object Max(IEnumerable rowIndices) { - PrimitiveColumnComputation.Instance.Max(_columnContainer, rowIndices, out T ret); + PrimitiveColumnComputation.Instance.Max(_columnContainer, rowIndices, out T? ret); return ret; } /// public override object Min() { - PrimitiveColumnComputation.Instance.Min(_columnContainer, out T ret); + PrimitiveColumnComputation.Instance.Min(_columnContainer, out T? ret); return ret; } /// public override object Min(IEnumerable rowIndices) { - PrimitiveColumnComputation.Instance.Min(_columnContainer, rowIndices, out T ret); + PrimitiveColumnComputation.Instance.Min(_columnContainer, rowIndices, out T? ret); return ret; } /// public override object Product() { - PrimitiveColumnComputation.Instance.Product(_columnContainer, out T ret); + PrimitiveColumnComputation.Instance.Product(_columnContainer, out T? ret); return ret; } /// public override object Product(IEnumerable rowIndices) { - PrimitiveColumnComputation.Instance.Product(_columnContainer, rowIndices, out T ret); + PrimitiveColumnComputation.Instance.Product(_columnContainer, rowIndices, out T? ret); return ret; } /// public override object Sum() { - PrimitiveColumnComputation.Instance.Sum(_columnContainer, out T ret); + PrimitiveColumnComputation.Instance.Sum(_columnContainer, out T? ret); return ret; } /// public override object Sum(IEnumerable rowIndices) { - PrimitiveColumnComputation.Instance.Sum(_columnContainer, rowIndices, out T ret); + PrimitiveColumnComputation.Instance.Sum(_columnContainer, rowIndices, out T? ret); return ret; } /// diff --git a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.tt b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.tt index 0d09ea3e37..763762c4b4 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.tt +++ b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Computations.tt @@ -51,13 +51,13 @@ namespace Microsoft.Data.Analysis PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(ret._columnContainer); return ret; <# } else if (compMethod.MethodType == MethodType.ElementwiseComputation && compMethod.HasReturnValue == true) {#> - PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(_columnContainer, out T ret); + PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(_columnContainer, out T? ret); return ret; <# } else if (compMethod.MethodType == MethodType.Reduction && compMethod.IsNumeric == true && compMethod.SupportsRowSubsets == true) { #> - PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(_columnContainer, rowIndices, out T ret); + PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(_columnContainer, rowIndices, out T? ret); return ret; <# } else if (compMethod.MethodType == MethodType.Reduction && compMethod.IsNumeric == true) { #> - PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(_columnContainer, out T ret); + PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(_columnContainer, out T? ret); return ret; <# } else { #> PrimitiveColumnComputation.Instance.<#=compMethod.MethodName#>(_columnContainer, out bool ret); diff --git a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Sort.cs b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Sort.cs index d83c601777..a70bc1aecc 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Sort.cs +++ b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.Sort.cs @@ -45,7 +45,7 @@ private Int64DataFrameColumn GetSortIndices(IComparer comparer, out Int64Data for (int i = 0; i < sortIndices.Length; i++) { int localSortIndex = sortIndices[i]; - if (_columnContainer.IsValid(nullBitMapSpan, localSortIndex)) + if (BitmapHelper.IsValid(nullBitMapSpan, localSortIndex)) { nonNullSortIndices.Add(sortIndices[i]); } diff --git a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs index 4696244e2a..5e7cc13b4c 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs +++ b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs @@ -584,7 +584,7 @@ public override Dictionary> GroupColumnValues(out for (int i = 0; i < readOnlySpan.Length; i++) { long currentLength = i + previousLength; - if (_columnContainer.IsValid(nullBitMapSpan, i)) + if (BitmapHelper.IsValid(nullBitMapSpan, i)) { bool containsKey = multimap.TryGetValue(readOnlySpan[i], out ICollection values); if (containsKey) diff --git a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.cs b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.cs index dd1ad7542e..cf01656497 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.cs +++ b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.cs @@ -25,14 +25,14 @@ internal interface IPrimitiveColumnComputation void CumulativeProduct(PrimitiveColumnContainer column, IEnumerable rows); void CumulativeSum(PrimitiveColumnContainer column); void CumulativeSum(PrimitiveColumnContainer column, IEnumerable rows); - void Max(PrimitiveColumnContainer column, out T ret); - void Max(PrimitiveColumnContainer column, IEnumerable rows, out T ret); - void Min(PrimitiveColumnContainer column, out T ret); - void Min(PrimitiveColumnContainer column, IEnumerable rows, out T ret); - void Product(PrimitiveColumnContainer column, out T ret); - void Product(PrimitiveColumnContainer column, IEnumerable rows, out T ret); - void Sum(PrimitiveColumnContainer column, out T ret); - void Sum(PrimitiveColumnContainer column, IEnumerable rows, out T ret); + void Max(PrimitiveColumnContainer column, out T? ret); + void Max(PrimitiveColumnContainer column, IEnumerable rows, out T? ret); + void Min(PrimitiveColumnContainer column, out T? ret); + void Min(PrimitiveColumnContainer column, IEnumerable rows, out T? ret); + void Product(PrimitiveColumnContainer column, out T? ret); + void Product(PrimitiveColumnContainer column, IEnumerable rows, out T? ret); + void Sum(PrimitiveColumnContainer column, out T? ret); + void Sum(PrimitiveColumnContainer column, IEnumerable rows, out T? ret); void Round(PrimitiveColumnContainer column); } @@ -195,42 +195,42 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out bool ret) + public void Max(PrimitiveColumnContainer column, out bool? ret) { throw new NotSupportedException(); } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out bool ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out bool? ret) { throw new NotSupportedException(); } - public void Min(PrimitiveColumnContainer column, out bool ret) + public void Min(PrimitiveColumnContainer column, out bool? ret) { throw new NotSupportedException(); } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out bool ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out bool? ret) { throw new NotSupportedException(); } - public void Product(PrimitiveColumnContainer column, out bool ret) + public void Product(PrimitiveColumnContainer column, out bool? ret) { throw new NotSupportedException(); } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out bool ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out bool? ret) { throw new NotSupportedException(); } - public void Sum(PrimitiveColumnContainer column, out bool ret) + public void Sum(PrimitiveColumnContainer column, out bool? ret) { throw new NotSupportedException(); } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out bool ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out bool? ret) { throw new NotSupportedException(); } @@ -281,7 +281,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (byte)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -345,7 +345,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (byte)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -409,7 +409,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (byte)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -473,7 +473,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (byte)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -524,9 +524,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out byte ret) + public void Max(PrimitiveColumnContainer column, out byte? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = byte.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -535,17 +536,20 @@ public void Max(PrimitiveColumnContainer column, out byte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (byte)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (byte)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out byte ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out byte? ret) { - ret = byte.MinValue; + var value = byte.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -562,13 +566,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (byte)(Math.Max(readOnlySpan[(int)row], ret)); + value = (byte)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out byte ret) + public void Min(PrimitiveColumnContainer column, out byte? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = byte.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -577,17 +584,20 @@ public void Min(PrimitiveColumnContainer column, out byte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (byte)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (byte)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out byte ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out byte? ret) { - ret = byte.MaxValue; + var value = byte.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -604,11 +614,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (byte)(Math.Min(readOnlySpan[(int)row], ret)); + value = (byte)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out byte ret) + public void Product(PrimitiveColumnContainer column, out byte? ret) { ret = (byte)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -619,7 +631,7 @@ public void Product(PrimitiveColumnContainer column, out byte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (byte)(readOnlySpan[i] * ret); } @@ -627,9 +639,9 @@ public void Product(PrimitiveColumnContainer column, out byte ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out byte ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out byte? ret) { - ret = default; + byte value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -646,13 +658,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable row maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((byte)(readOnlySpan[(int)row] * ret)); + value = checked((byte)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out byte ret) + public void Sum(PrimitiveColumnContainer column, out byte? ret) { - ret = (byte)0; + var value = (byte)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -661,17 +676,20 @@ public void Sum(PrimitiveColumnContainer column, out byte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (byte)(readOnlySpan[i] + ret); + hasValue = true; + value = (byte)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out byte ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out byte? ret) { - ret = default; + byte value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -688,8 +706,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((byte)(readOnlySpan[(int)row] + ret)); + value = checked((byte)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -748,7 +768,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (char)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -812,7 +832,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (char)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -876,7 +896,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (char)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -940,7 +960,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (char)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -991,9 +1011,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out char ret) + public void Max(PrimitiveColumnContainer column, out char? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = char.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1002,17 +1023,20 @@ public void Max(PrimitiveColumnContainer column, out char ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (char)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (char)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out char ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out char? ret) { - ret = char.MinValue; + var value = char.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1029,13 +1053,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (char)(Math.Max(readOnlySpan[(int)row], ret)); + value = (char)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out char ret) + public void Min(PrimitiveColumnContainer column, out char? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = char.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1044,17 +1071,20 @@ public void Min(PrimitiveColumnContainer column, out char ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (char)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (char)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out char ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out char? ret) { - ret = char.MaxValue; + var value = char.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1071,11 +1101,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (char)(Math.Min(readOnlySpan[(int)row], ret)); + value = (char)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out char ret) + public void Product(PrimitiveColumnContainer column, out char? ret) { ret = (char)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -1086,7 +1118,7 @@ public void Product(PrimitiveColumnContainer column, out char ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (char)(readOnlySpan[i] * ret); } @@ -1094,9 +1126,9 @@ public void Product(PrimitiveColumnContainer column, out char ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out char ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out char? ret) { - ret = default; + char value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1113,13 +1145,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable row maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((char)(readOnlySpan[(int)row] * ret)); + value = checked((char)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out char ret) + public void Sum(PrimitiveColumnContainer column, out char? ret) { - ret = (char)0; + var value = (char)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1128,17 +1163,20 @@ public void Sum(PrimitiveColumnContainer column, out char ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (char)(readOnlySpan[i] + ret); + hasValue = true; + value = (char)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out char ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out char? ret) { - ret = default; + char value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1155,8 +1193,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((char)(readOnlySpan[(int)row] + ret)); + value = checked((char)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -1215,7 +1255,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (decimal)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -1279,7 +1319,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (decimal)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -1343,7 +1383,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (decimal)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -1407,7 +1447,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (decimal)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -1458,9 +1498,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable< } } - public void Max(PrimitiveColumnContainer column, out decimal ret) + public void Max(PrimitiveColumnContainer column, out decimal? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = decimal.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1469,17 +1510,20 @@ public void Max(PrimitiveColumnContainer column, out decimal ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (decimal)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (decimal)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out decimal ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out decimal? ret) { - ret = decimal.MinValue; + var value = decimal.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1496,13 +1540,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (decimal)(Math.Max(readOnlySpan[(int)row], ret)); + value = (decimal)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out decimal ret) + public void Min(PrimitiveColumnContainer column, out decimal? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = decimal.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1511,17 +1558,20 @@ public void Min(PrimitiveColumnContainer column, out decimal ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (decimal)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (decimal)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out decimal ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out decimal? ret) { - ret = decimal.MaxValue; + var value = decimal.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1538,11 +1588,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (decimal)(Math.Min(readOnlySpan[(int)row], ret)); + value = (decimal)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out decimal ret) + public void Product(PrimitiveColumnContainer column, out decimal? ret) { ret = (decimal)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -1553,7 +1605,7 @@ public void Product(PrimitiveColumnContainer column, out decimal ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (decimal)(readOnlySpan[i] * ret); } @@ -1561,9 +1613,9 @@ public void Product(PrimitiveColumnContainer column, out decimal ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out decimal ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out decimal? ret) { - ret = default; + decimal value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1580,13 +1632,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((decimal)(readOnlySpan[(int)row] * ret)); + value = checked((decimal)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out decimal ret) + public void Sum(PrimitiveColumnContainer column, out decimal? ret) { - ret = (decimal)0; + var value = (decimal)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1595,17 +1650,20 @@ public void Sum(PrimitiveColumnContainer column, out decimal ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (decimal)(readOnlySpan[i] + ret); + hasValue = true; + value = (decimal)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out decimal ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out decimal? ret) { - ret = default; + decimal value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1622,8 +1680,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((decimal)(readOnlySpan[(int)row] + ret)); + value = checked((decimal)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -1682,7 +1742,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (double)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -1746,7 +1806,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (double)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -1810,7 +1870,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (double)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -1874,7 +1934,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (double)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -1925,9 +1985,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out double ret) + public void Max(PrimitiveColumnContainer column, out double? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = double.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1936,17 +1997,20 @@ public void Max(PrimitiveColumnContainer column, out double ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (double)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (double)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out double ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out double? ret) { - ret = double.MinValue; + var value = double.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -1963,13 +2027,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (double)(Math.Max(readOnlySpan[(int)row], ret)); + value = (double)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out double ret) + public void Min(PrimitiveColumnContainer column, out double? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = double.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -1978,17 +2045,20 @@ public void Min(PrimitiveColumnContainer column, out double ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (double)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (double)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out double ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out double? ret) { - ret = double.MaxValue; + var value = double.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2005,11 +2075,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (double)(Math.Min(readOnlySpan[(int)row], ret)); + value = (double)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out double ret) + public void Product(PrimitiveColumnContainer column, out double? ret) { ret = (double)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -2020,7 +2092,7 @@ public void Product(PrimitiveColumnContainer column, out double ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (double)(readOnlySpan[i] * ret); } @@ -2028,9 +2100,9 @@ public void Product(PrimitiveColumnContainer column, out double ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out double ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out double? ret) { - ret = default; + double value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2047,13 +2119,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable r maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((double)(readOnlySpan[(int)row] * ret)); + value = checked((double)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out double ret) + public void Sum(PrimitiveColumnContainer column, out double? ret) { - ret = (double)0; + var value = (double)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -2062,17 +2137,20 @@ public void Sum(PrimitiveColumnContainer column, out double ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (double)(readOnlySpan[i] + ret); + hasValue = true; + value = (double)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out double ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out double? ret) { - ret = default; + double value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2089,8 +2167,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((double)(readOnlySpan[(int)row] + ret)); + value = checked((double)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -2149,7 +2229,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (float)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -2213,7 +2293,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (float)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -2277,7 +2357,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (float)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -2341,7 +2421,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (float)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -2392,9 +2472,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out float ret) + public void Max(PrimitiveColumnContainer column, out float? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = float.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -2403,17 +2484,20 @@ public void Max(PrimitiveColumnContainer column, out float ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (float)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (float)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out float ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out float? ret) { - ret = float.MinValue; + var value = float.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2430,13 +2514,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (float)(Math.Max(readOnlySpan[(int)row], ret)); + value = (float)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out float ret) + public void Min(PrimitiveColumnContainer column, out float? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = float.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -2445,17 +2532,20 @@ public void Min(PrimitiveColumnContainer column, out float ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (float)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (float)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out float ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out float? ret) { - ret = float.MaxValue; + var value = float.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2472,11 +2562,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (float)(Math.Min(readOnlySpan[(int)row], ret)); + value = (float)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out float ret) + public void Product(PrimitiveColumnContainer column, out float? ret) { ret = (float)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -2487,7 +2579,7 @@ public void Product(PrimitiveColumnContainer column, out float ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (float)(readOnlySpan[i] * ret); } @@ -2495,9 +2587,9 @@ public void Product(PrimitiveColumnContainer column, out float ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out float ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out float? ret) { - ret = default; + float value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2514,13 +2606,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable ro maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((float)(readOnlySpan[(int)row] * ret)); + value = checked((float)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out float ret) + public void Sum(PrimitiveColumnContainer column, out float? ret) { - ret = (float)0; + var value = (float)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -2529,17 +2624,20 @@ public void Sum(PrimitiveColumnContainer column, out float ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (float)(readOnlySpan[i] + ret); + hasValue = true; + value = (float)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out float ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out float? ret) { - ret = default; + float value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2556,8 +2654,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((float)(readOnlySpan[(int)row] + ret)); + value = checked((float)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -2616,7 +2716,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (int)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -2680,7 +2780,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (int)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -2744,7 +2844,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (int)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -2808,7 +2908,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (int)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -2859,9 +2959,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out int ret) + public void Max(PrimitiveColumnContainer column, out int? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = int.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -2870,17 +2971,20 @@ public void Max(PrimitiveColumnContainer column, out int ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (int)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (int)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out int ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out int? ret) { - ret = int.MinValue; + var value = int.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2897,13 +3001,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, ou maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (int)(Math.Max(readOnlySpan[(int)row], ret)); + value = (int)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out int ret) + public void Min(PrimitiveColumnContainer column, out int? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = int.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -2912,17 +3019,20 @@ public void Min(PrimitiveColumnContainer column, out int ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (int)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (int)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out int ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out int? ret) { - ret = int.MaxValue; + var value = int.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2939,11 +3049,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, ou maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (int)(Math.Min(readOnlySpan[(int)row], ret)); + value = (int)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out int ret) + public void Product(PrimitiveColumnContainer column, out int? ret) { ret = (int)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -2954,7 +3066,7 @@ public void Product(PrimitiveColumnContainer column, out int ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (int)(readOnlySpan[i] * ret); } @@ -2962,9 +3074,9 @@ public void Product(PrimitiveColumnContainer column, out int ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out int ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out int? ret) { - ret = default; + int value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -2981,13 +3093,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable rows maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((int)(readOnlySpan[(int)row] * ret)); + value = checked((int)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out int ret) + public void Sum(PrimitiveColumnContainer column, out int? ret) { - ret = (int)0; + var value = (int)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -2996,17 +3111,20 @@ public void Sum(PrimitiveColumnContainer column, out int ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (int)(readOnlySpan[i] + ret); + hasValue = true; + value = (int)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out int ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out int? ret) { - ret = default; + int value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3023,8 +3141,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, ou maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((int)(readOnlySpan[(int)row] + ret)); + value = checked((int)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -3083,7 +3203,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (long)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -3147,7 +3267,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (long)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -3211,7 +3331,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (long)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -3275,7 +3395,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (long)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -3326,9 +3446,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out long ret) + public void Max(PrimitiveColumnContainer column, out long? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = long.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -3337,17 +3458,20 @@ public void Max(PrimitiveColumnContainer column, out long ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (long)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (long)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out long ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out long? ret) { - ret = long.MinValue; + var value = long.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3364,13 +3488,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (long)(Math.Max(readOnlySpan[(int)row], ret)); + value = (long)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out long ret) + public void Min(PrimitiveColumnContainer column, out long? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = long.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -3379,17 +3506,20 @@ public void Min(PrimitiveColumnContainer column, out long ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (long)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (long)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out long ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out long? ret) { - ret = long.MaxValue; + var value = long.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3406,11 +3536,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (long)(Math.Min(readOnlySpan[(int)row], ret)); + value = (long)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out long ret) + public void Product(PrimitiveColumnContainer column, out long? ret) { ret = (long)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -3421,7 +3553,7 @@ public void Product(PrimitiveColumnContainer column, out long ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (long)(readOnlySpan[i] * ret); } @@ -3429,9 +3561,9 @@ public void Product(PrimitiveColumnContainer column, out long ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out long ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out long? ret) { - ret = default; + long value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3448,13 +3580,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable row maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((long)(readOnlySpan[(int)row] * ret)); + value = checked((long)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out long ret) + public void Sum(PrimitiveColumnContainer column, out long? ret) { - ret = (long)0; + var value = (long)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -3463,17 +3598,20 @@ public void Sum(PrimitiveColumnContainer column, out long ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (long)(readOnlySpan[i] + ret); + hasValue = true; + value = (long)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out long ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out long? ret) { - ret = default; + long value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3490,8 +3628,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((long)(readOnlySpan[(int)row] + ret)); + value = checked((long)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -3550,7 +3690,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (sbyte)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -3614,7 +3754,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (sbyte)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -3678,7 +3818,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (sbyte)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -3742,7 +3882,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (sbyte)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -3793,9 +3933,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out sbyte ret) + public void Max(PrimitiveColumnContainer column, out sbyte? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = sbyte.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -3804,17 +3945,20 @@ public void Max(PrimitiveColumnContainer column, out sbyte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (sbyte)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (sbyte)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out sbyte ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out sbyte? ret) { - ret = sbyte.MinValue; + var value = sbyte.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3831,13 +3975,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (sbyte)(Math.Max(readOnlySpan[(int)row], ret)); + value = (sbyte)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out sbyte ret) + public void Min(PrimitiveColumnContainer column, out sbyte? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = sbyte.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -3846,17 +3993,20 @@ public void Min(PrimitiveColumnContainer column, out sbyte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (sbyte)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (sbyte)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out sbyte ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out sbyte? ret) { - ret = sbyte.MaxValue; + var value = sbyte.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3873,11 +4023,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (sbyte)(Math.Min(readOnlySpan[(int)row], ret)); + value = (sbyte)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out sbyte ret) + public void Product(PrimitiveColumnContainer column, out sbyte? ret) { ret = (sbyte)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -3888,7 +4040,7 @@ public void Product(PrimitiveColumnContainer column, out sbyte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (sbyte)(readOnlySpan[i] * ret); } @@ -3896,9 +4048,9 @@ public void Product(PrimitiveColumnContainer column, out sbyte ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out sbyte ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out sbyte? ret) { - ret = default; + sbyte value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3915,13 +4067,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable ro maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((sbyte)(readOnlySpan[(int)row] * ret)); + value = checked((sbyte)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out sbyte ret) + public void Sum(PrimitiveColumnContainer column, out sbyte? ret) { - ret = (sbyte)0; + var value = (sbyte)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -3930,17 +4085,20 @@ public void Sum(PrimitiveColumnContainer column, out sbyte ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (sbyte)(readOnlySpan[i] + ret); + hasValue = true; + value = (sbyte)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out sbyte ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out sbyte? ret) { - ret = default; + sbyte value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -3957,8 +4115,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((sbyte)(readOnlySpan[(int)row] + ret)); + value = checked((sbyte)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -4017,7 +4177,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (short)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -4081,7 +4241,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (short)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -4145,7 +4305,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (short)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -4209,7 +4369,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (short)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -4260,9 +4420,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out short ret) + public void Max(PrimitiveColumnContainer column, out short? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = short.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -4271,17 +4432,20 @@ public void Max(PrimitiveColumnContainer column, out short ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (short)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (short)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out short ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out short? ret) { - ret = short.MinValue; + var value = short.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4298,13 +4462,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (short)(Math.Max(readOnlySpan[(int)row], ret)); + value = (short)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out short ret) + public void Min(PrimitiveColumnContainer column, out short? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = short.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -4313,17 +4480,20 @@ public void Min(PrimitiveColumnContainer column, out short ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (short)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (short)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out short ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out short? ret) { - ret = short.MaxValue; + var value = short.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4340,11 +4510,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (short)(Math.Min(readOnlySpan[(int)row], ret)); + value = (short)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out short ret) + public void Product(PrimitiveColumnContainer column, out short? ret) { ret = (short)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -4355,7 +4527,7 @@ public void Product(PrimitiveColumnContainer column, out short ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (short)(readOnlySpan[i] * ret); } @@ -4363,9 +4535,9 @@ public void Product(PrimitiveColumnContainer column, out short ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out short ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out short? ret) { - ret = default; + short value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4382,13 +4554,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable ro maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((short)(readOnlySpan[(int)row] * ret)); + value = checked((short)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out short ret) + public void Sum(PrimitiveColumnContainer column, out short? ret) { - ret = (short)0; + var value = (short)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -4397,17 +4572,20 @@ public void Sum(PrimitiveColumnContainer column, out short ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (short)(readOnlySpan[i] + ret); + hasValue = true; + value = (short)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out short ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out short? ret) { - ret = default; + short value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4424,8 +4602,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((short)(readOnlySpan[(int)row] + ret)); + value = checked((short)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -4484,7 +4664,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (uint)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -4548,7 +4728,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (uint)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -4612,7 +4792,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (uint)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -4676,7 +4856,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (uint)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -4727,9 +4907,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out uint ret) + public void Max(PrimitiveColumnContainer column, out uint? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = uint.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -4738,17 +4919,20 @@ public void Max(PrimitiveColumnContainer column, out uint ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (uint)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (uint)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out uint ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out uint? ret) { - ret = uint.MinValue; + var value = uint.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4765,13 +4949,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (uint)(Math.Max(readOnlySpan[(int)row], ret)); + value = (uint)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out uint ret) + public void Min(PrimitiveColumnContainer column, out uint? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = uint.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -4780,17 +4967,20 @@ public void Min(PrimitiveColumnContainer column, out uint ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (uint)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (uint)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out uint ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out uint? ret) { - ret = uint.MaxValue; + var value = uint.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4807,11 +4997,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (uint)(Math.Min(readOnlySpan[(int)row], ret)); + value = (uint)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out uint ret) + public void Product(PrimitiveColumnContainer column, out uint? ret) { ret = (uint)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -4822,7 +5014,7 @@ public void Product(PrimitiveColumnContainer column, out uint ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (uint)(readOnlySpan[i] * ret); } @@ -4830,9 +5022,9 @@ public void Product(PrimitiveColumnContainer column, out uint ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out uint ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out uint? ret) { - ret = default; + uint value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4849,13 +5041,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable row maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((uint)(readOnlySpan[(int)row] * ret)); + value = checked((uint)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out uint ret) + public void Sum(PrimitiveColumnContainer column, out uint? ret) { - ret = (uint)0; + var value = (uint)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -4864,17 +5059,20 @@ public void Sum(PrimitiveColumnContainer column, out uint ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (uint)(readOnlySpan[i] + ret); + hasValue = true; + value = (uint)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out uint ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out uint? ret) { - ret = default; + uint value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -4891,8 +5089,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, o maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((uint)(readOnlySpan[(int)row] + ret)); + value = checked((uint)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -4951,7 +5151,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ulong)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -5015,7 +5215,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ulong)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -5079,7 +5279,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ulong)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -5143,7 +5343,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ulong)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -5194,9 +5394,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out ulong ret) + public void Max(PrimitiveColumnContainer column, out ulong? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = ulong.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -5205,17 +5406,20 @@ public void Max(PrimitiveColumnContainer column, out ulong ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (ulong)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (ulong)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out ulong ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out ulong? ret) { - ret = ulong.MinValue; + var value = ulong.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5232,13 +5436,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (ulong)(Math.Max(readOnlySpan[(int)row], ret)); + value = (ulong)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out ulong ret) + public void Min(PrimitiveColumnContainer column, out ulong? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = ulong.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -5247,17 +5454,20 @@ public void Min(PrimitiveColumnContainer column, out ulong ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (ulong)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (ulong)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out ulong ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out ulong? ret) { - ret = ulong.MaxValue; + var value = ulong.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5274,11 +5484,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (ulong)(Math.Min(readOnlySpan[(int)row], ret)); + value = (ulong)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out ulong ret) + public void Product(PrimitiveColumnContainer column, out ulong? ret) { ret = (ulong)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -5289,7 +5501,7 @@ public void Product(PrimitiveColumnContainer column, out ulong ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ulong)(readOnlySpan[i] * ret); } @@ -5297,9 +5509,9 @@ public void Product(PrimitiveColumnContainer column, out ulong ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out ulong ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out ulong? ret) { - ret = default; + ulong value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5316,13 +5528,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable ro maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((ulong)(readOnlySpan[(int)row] * ret)); + value = checked((ulong)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out ulong ret) + public void Sum(PrimitiveColumnContainer column, out ulong? ret) { - ret = (ulong)0; + var value = (ulong)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -5331,17 +5546,20 @@ public void Sum(PrimitiveColumnContainer column, out ulong ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (ulong)(readOnlySpan[i] + ret); + hasValue = true; + value = (ulong)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out ulong ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out ulong? ret) { - ret = default; + ulong value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5358,8 +5576,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((ulong)(readOnlySpan[(int)row] + ret)); + value = checked((ulong)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) @@ -5418,7 +5638,7 @@ public void CumulativeMax(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ushort)(Math.Max(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -5482,7 +5702,7 @@ public void CumulativeMin(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ushort)(Math.Min(readOnlySpan[i], ret)); mutableSpan[i] = ret; @@ -5546,7 +5766,7 @@ public void CumulativeProduct(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ushort)(readOnlySpan[i] * ret); mutableSpan[i] = ret; @@ -5610,7 +5830,7 @@ public void CumulativeSum(PrimitiveColumnContainer column) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ushort)(readOnlySpan[i] + ret); mutableSpan[i] = ret; @@ -5661,9 +5881,10 @@ public void CumulativeSum(PrimitiveColumnContainer column, IEnumerable column, out ushort ret) + public void Max(PrimitiveColumnContainer column, out ushort? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = ushort.MinValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -5672,17 +5893,20 @@ public void Max(PrimitiveColumnContainer column, out ushort ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (ushort)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (ushort)(Math.Max(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Max(PrimitiveColumnContainer column, IEnumerable rows, out ushort ret) + public void Max(PrimitiveColumnContainer column, IEnumerable rows, out ushort? ret) { - ret = ushort.MinValue; + var value = ushort.MinValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5699,13 +5923,16 @@ public void Max(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (ushort)(Math.Max(readOnlySpan[(int)row], ret)); + value = (ushort)(Math.Max(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Min(PrimitiveColumnContainer column, out ushort ret) + public void Min(PrimitiveColumnContainer column, out ushort? ret) { - ret = column.Buffers[0].ReadOnlySpan[0]; + var value = ushort.MaxValue; + bool hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -5714,17 +5941,20 @@ public void Min(PrimitiveColumnContainer column, out ushort ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (ushort)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (ushort)(Math.Min(readOnlySpan[i], value)); } } } + + ret = hasValue ? value : null; } - public void Min(PrimitiveColumnContainer column, IEnumerable rows, out ushort ret) + public void Min(PrimitiveColumnContainer column, IEnumerable rows, out ushort? ret) { - ret = ushort.MaxValue; + var value = ushort.MaxValue; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5741,11 +5971,13 @@ public void Min(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = (ushort)(Math.Min(readOnlySpan[(int)row], ret)); + value = (ushort)(Math.Min(readOnlySpan[(int)row], value)); } + + ret = value; } - public void Product(PrimitiveColumnContainer column, out ushort ret) + public void Product(PrimitiveColumnContainer column, out ushort? ret) { ret = (ushort)1; for (int b = 0; b < column.Buffers.Count; b++) @@ -5756,7 +5988,7 @@ public void Product(PrimitiveColumnContainer column, out ushort ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { ret = (ushort)(readOnlySpan[i] * ret); } @@ -5764,9 +5996,9 @@ public void Product(PrimitiveColumnContainer column, out ushort ret) } } - public void Product(PrimitiveColumnContainer column, IEnumerable rows, out ushort ret) + public void Product(PrimitiveColumnContainer column, IEnumerable rows, out ushort? ret) { - ret = default; + ushort value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5783,13 +6015,16 @@ public void Product(PrimitiveColumnContainer column, IEnumerable r maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((ushort)(readOnlySpan[(int)row] * ret)); + value = checked((ushort)(readOnlySpan[(int)row] * value)); } + + ret = value; } - public void Sum(PrimitiveColumnContainer column, out ushort ret) + public void Sum(PrimitiveColumnContainer column, out ushort? ret) { - ret = (ushort)0; + var value = (ushort)0; + var hasValue = false; for (int b = 0; b < column.Buffers.Count; b++) { var buffer = column.Buffers[b]; @@ -5798,17 +6033,20 @@ public void Sum(PrimitiveColumnContainer column, out ushort ret) for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { - ret = (ushort)(readOnlySpan[i] + ret); + hasValue = true; + value = (ushort)(readOnlySpan[i] + value); } } } + + ret = hasValue ? value : null; } - public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out ushort ret) + public void Sum(PrimitiveColumnContainer column, IEnumerable rows, out ushort? ret) { - ret = default; + ushort value = default; var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; long maxRange = ReadOnlyDataFrameBuffer.MaxCapacity; @@ -5825,8 +6063,10 @@ public void Sum(PrimitiveColumnContainer column, IEnumerable rows, maxRange = checked((bufferIndex + 1) * maxCapacity); } row -= minRange; - ret = checked((ushort)(readOnlySpan[(int)row] + ret)); + value = checked((ushort)(readOnlySpan[(int)row] + value)); } + + ret = value; } public void Round(PrimitiveColumnContainer column) diff --git a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.tt b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.tt index 7749369ecc..4bea44c3f3 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.tt +++ b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumnComputations.tt @@ -29,9 +29,9 @@ namespace Microsoft.Data.Analysis <# } else if (compMethod.MethodType == MethodType.ElementwiseComputation && compMethod.HasReturnValue == true) {#> void <#=compMethod.MethodName#>(PrimitiveColumnContainer column, out T ret); <# } else if (compMethod.MethodType == MethodType.Reduction && compMethod.IsNumeric == true && compMethod.SupportsRowSubsets == true) { #> - void <#=compMethod.MethodName#>(PrimitiveColumnContainer column, IEnumerable rows, out T ret); + void <#=compMethod.MethodName#>(PrimitiveColumnContainer column, IEnumerable rows, out T? ret); <# } else if (compMethod.MethodType == MethodType.Reduction && compMethod.IsNumeric == true) { #> - void <#=compMethod.MethodName#>(PrimitiveColumnContainer column, out T ret); + void <#=compMethod.MethodName#>(PrimitiveColumnContainer column, out T? ret); <# } else { #> void <#=compMethod.MethodName#>(PrimitiveColumnContainer column, out bool ret); <# } #> @@ -78,9 +78,9 @@ namespace Microsoft.Data.Analysis <# } else if (method.MethodType == MethodType.ElementwiseComputation && method.HasReturnValue == true) {#> public void <#=method.MethodName#>(PrimitiveColumnContainer<<#=type.TypeName#>> column, out <#=type.TypeName#> ret) <# } else if (method.MethodType == MethodType.Reduction && method.IsNumeric == true && method.SupportsRowSubsets == true) { #> - public void <#=method.MethodName#>(PrimitiveColumnContainer<<#=type.TypeName#>> column, IEnumerable rows, out <#=type.TypeName#> ret) + public void <#=method.MethodName#>(PrimitiveColumnContainer<<#=type.TypeName#>> column, IEnumerable rows, out <#=type.TypeName#>? ret) <# } else if (method.MethodType == MethodType.Reduction && method.IsNumeric == true) { #> - public void <#=method.MethodName#>(PrimitiveColumnContainer<<#=type.TypeName#>> column, out <#=type.TypeName#> ret) + public void <#=method.MethodName#>(PrimitiveColumnContainer<<#=type.TypeName#>> column, out <#=type.TypeName#>? ret) <# } else { #> public void <#=method.MethodName#>(PrimitiveColumnContainer<<#=type.TypeName#>> column, out bool ret) <# } #> @@ -90,11 +90,11 @@ namespace Microsoft.Data.Analysis <# } else { #> <# if ((method.MethodName == "Max" || method.MethodName == "Min" || method.MethodName == "Product" || method.MethodName == "Sum") && method.SupportsRowSubsets == true) { #> <# if (method.MethodName == "Max") { #> - ret = <#=type.TypeName#>.MinValue; + var value = <#=type.TypeName#>.MinValue; <# } else if (method.MethodName == "Min") { #> - ret = <#=type.TypeName#>.MaxValue; + var value = <#=type.TypeName#>.MaxValue; <# } else { #> - ret = default; + <#=type.TypeName#> value = default; <# } #> var readOnlySpan = column.Buffers[0].ReadOnlySpan; long minRange = 0; @@ -113,18 +113,20 @@ namespace Microsoft.Data.Analysis } row -= minRange; <# if (method.MethodName == "Max") { #> - ret = (<#=type.TypeName#>)(Math.Max(readOnlySpan[(int)row], ret)); + value = (<#=type.TypeName#>)(Math.Max(readOnlySpan[(int)row], value)); <# } #> <# if (method.MethodName == "Min") { #> - ret = (<#=type.TypeName#>)(Math.Min(readOnlySpan[(int)row], ret)); + value = (<#=type.TypeName#>)(Math.Min(readOnlySpan[(int)row], value)); <# } #> <# if (method.MethodName == "Product") { #> - ret = checked((<#=type.TypeName#>)(readOnlySpan[(int)row] * ret)); + value = checked((<#=type.TypeName#>)(readOnlySpan[(int)row] * value)); <# } #> <# if (method.MethodName == "Sum") { #> - ret = checked((<#=type.TypeName#>)(readOnlySpan[(int)row] + ret)); + value = checked((<#=type.TypeName#>)(readOnlySpan[(int)row] + value)); <# } #> } + + ret = value; <# } else if ((method.MethodName == "CumulativeMax" || method.MethodName == "CumulativeMin" || method.MethodName == "CumulativeProduct" || method.MethodName == "CumulativeSum") && method.SupportsRowSubsets == true) { #> <# if (method.MethodName == "CumulativeMax") { #> var ret = <#=type.TypeName#>.MinValue; @@ -183,8 +185,12 @@ namespace Microsoft.Data.Analysis <# } else if (method.MethodName == "CumulativeMax" || method.MethodName == "CumulativeMin" || method.MethodName == "CumulativeProduct" || method.MethodName == "CumulativeSum" || method.MethodName == "Max" || method.MethodName == "Min" || method.MethodName == "Product" || method.MethodName == "Sum") { #> <# if (method.MethodName == "CumulativeMax" || method.MethodName == "CumulativeMin") { #> var ret = column.Buffers[0].ReadOnlySpan[0]; -<# } else if ((method.MethodName == "Max" || method.MethodName == "Min") && method.SupportsRowSubsets == false) { #> - ret = column.Buffers[0].ReadOnlySpan[0]; +<# } else if (method.MethodName == "Max" && method.SupportsRowSubsets == false) { #> + var value = <#=type.TypeName#>.MinValue; + bool hasValue = false; +<# } else if (method.MethodName == "Min" && method.SupportsRowSubsets == false) { #> + var value = <#=type.TypeName#>.MaxValue; + bool hasValue = false; <# } else if (method.MethodName == "CumulativeProduct") { #> var ret = (<#=type.TypeName#>)1; <# } else if (method.MethodName =="Product" && method.SupportsRowSubsets == false) { #> @@ -192,7 +198,8 @@ namespace Microsoft.Data.Analysis <# } else if (method.MethodName =="CumulativeSum") { #> var ret = (<#=type.TypeName#>)0; <# } else if (method.SupportsRowSubsets == false) { #> - ret = (<#=type.TypeName#>)0; + var value = (<#=type.TypeName#>)0; + var hasValue = false; <# } #> for (int b = 0; b < column.Buffers.Count; b++) { @@ -206,7 +213,7 @@ namespace Microsoft.Data.Analysis for (int i = 0; i < readOnlySpan.Length; i++) { - if (column.IsValid(readOnlyBitMapSpan, i)) + if (BitmapHelper.IsValid(readOnlyBitMapSpan, i)) { <# if (method.MethodName == "CumulativeMax") { #> ret = (<#=type.TypeName#>)(Math.Max(readOnlySpan[i], ret)); @@ -225,23 +232,32 @@ namespace Microsoft.Data.Analysis mutableSpan[i] = ret; <# } #> <# if (method.MethodName == "Max") { #> - ret = (<#=type.TypeName#>)(Math.Max(readOnlySpan[i], ret)); + hasValue = true; + value = (<#=type.TypeName#>)(Math.Max(readOnlySpan[i], value)); <# } #> <# if (method.MethodName == "Min") { #> - ret = (<#=type.TypeName#>)(Math.Min(readOnlySpan[i], ret)); + hasValue = true; + value = (<#=type.TypeName#>)(Math.Min(readOnlySpan[i], value)); <# } #> <# if (method.MethodName == "Product") { #> ret = (<#=type.TypeName#>)(readOnlySpan[i] * ret); <# } #> <# if (method.MethodName == "Sum") { #> - ret = (<#=type.TypeName#>)(readOnlySpan[i] + ret); + hasValue = true; + value = (<#=type.TypeName#>)(readOnlySpan[i] + value); <# } #> } } <# if (method.MethodName == "CumulativeMax" || method.MethodName == "CumulativeMin" || method.MethodName == "CumulativeProduct" || method.MethodName == "CumulativeSum") { #> column.Buffers[b] = mutableBuffer; -<# } #> } +<# } else if (method.MethodName == "Product") { #> + } +<# } else { #> + } + + ret = hasValue ? value : null; +<# } #> <# } else if (method.MethodType == MethodType.ElementwiseComputation && method.Operator != null) { #> for (int b = 0; b < column.Buffers.Count; b++) { diff --git a/test/Microsoft.Data.Analysis.Tests/DataFrameTests.cs b/test/Microsoft.Data.Analysis.Tests/DataFrameTests.cs index 859eb508ef..f1d04381c5 100644 --- a/test/Microsoft.Data.Analysis.Tests/DataFrameTests.cs +++ b/test/Microsoft.Data.Analysis.Tests/DataFrameTests.cs @@ -1173,6 +1173,72 @@ public void TestComputationsIncludingDateTime() } } + [Fact] + public void TestIntComputations_MaxMin_WithNulls() + { + var column = new Int32DataFrameColumn("Int", new int?[] + { + null, + 2, + 1, + 4, + 3, + null + }); + + Assert.Equal(1, column.Min()); + Assert.Equal(4, column.Max()); + } + + [Fact] + public void TestIntSum_OnColumnWithNullsOnly() + { + var column = new Int32DataFrameColumn("Int", new int?[] { null, null }); + Assert.Null(column.Sum()); + } + + [Fact] + public void TestIntSum_OnEmptyColumn() + { + var column = new Int32DataFrameColumn("Int"); + Assert.Null(column.Sum()); + } + + [Fact] + public void TestIntComputations_MaxMin_OnEmptyColumn() + { + var column = new Int32DataFrameColumn("Int"); + + Assert.Null(column.Min()); + Assert.Null(column.Max()); + } + + [Fact] + public void TestDateTimeComputations_MaxMin_OnEmptyColumn() + { + var column = new DateTimeDataFrameColumn("DateTime"); + + Assert.Null(column.Min()); + Assert.Null(column.Max()); + } + + [Fact] + public void TestDateTimeComputations_MaxMin_WithNulls() + { + var dateTimeColumn = new DateTimeDataFrameColumn("DateTime", new DateTime?[] + { + null, + new DateTime(2022, 1, 1), + new DateTime(2020, 1, 1), + new DateTime(2023, 1, 1), + new DateTime(2021, 1, 1), + null + }); + + Assert.Equal(new DateTime(2020, 1, 1), dateTimeColumn.Min()); + Assert.Equal(new DateTime(2023, 1, 1), dateTimeColumn.Max()); + } + [Theory] [InlineData(5, 10)] [InlineData(-15, 10)]