private void CompareBinaryArrays <T>(BinaryArray actualArray) where T : IArrowArray { Assert.IsAssignableFrom <T>(_expectedArray); Assert.IsAssignableFrom <T>(actualArray); var expectedArray = (BinaryArray)_expectedArray; actualArray.Data.DataType.Accept(_arrayTypeComparer); Assert.Equal(expectedArray.Length, actualArray.Length); Assert.Equal(expectedArray.NullCount, actualArray.NullCount); Assert.Equal(expectedArray.Offset, actualArray.Offset); CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, actualArray.NullBitmapBuffer); if (_strictCompare) { Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span)); Assert.True(expectedArray.Values.Slice(0, expectedArray.Length).SequenceEqual(actualArray.Values.Slice(0, actualArray.Length))); } else { for (int i = 0; i < expectedArray.Length; i++) { Assert.True( expectedArray.GetBytes(i).SequenceEqual(actualArray.GetBytes(i)), $"BinaryArray values do not match at index {i}."); } } }
private static void AssertArrayContents(IEnumerable <byte[]> expectedContents, BinaryArray array) { var expectedContentsArr = expectedContents.ToArray(); Assert.Equal(expectedContentsArr.Length, array.Length); for (int i = 0; i < array.Length; i++) { var expectedArray = expectedContentsArr[i]; var actualArray = array.IsNull(i) ? null : array.GetBytes(i).ToArray(); Assert.Equal(expectedArray, actualArray); } }
public static Func <int, T> GetGetter <T>(IArrowArray array) { if (array is null) { return(null); } // TODO: determine fastest way to read out a value from the array. if (typeof(T) == typeof(bool)) { var booleanArray = new BooleanArray(array.Data); return((Func <int, T>)(object) new Func <int, bool>( index => booleanArray.GetBoolean(index).GetValueOrDefault())); } if (typeof(T) == typeof(bool?)) { var booleanArray = new BooleanArray(array.Data); return((Func <int, T>)(object) new Func <int, bool?>(booleanArray.GetBoolean)); } if (typeof(T) == typeof(sbyte)) { var int8Array = new Int8Array(array.Data); return((Func <int, T>)(object) new Func <int, sbyte>( index => int8Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(sbyte?)) { var int8Array = new Int8Array(array.Data); return((Func <int, T>)(object) new Func <int, sbyte?>(int8Array.GetValue)); } if (typeof(T) == typeof(byte)) { var uint8Array = new UInt8Array(array.Data); return((Func <int, T>)(object) new Func <int, byte>( index => uint8Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(byte?)) { var uint8Array = new UInt8Array(array.Data); return((Func <int, T>)(object) new Func <int, byte?>(uint8Array.GetValue)); } if (typeof(T) == typeof(short)) { var int16Array = new Int16Array(array.Data); return((Func <int, T>)(object) new Func <int, short>( index => int16Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(short?)) { var int16Array = new Int16Array(array.Data); return((Func <int, T>)(object) new Func <int, short?>(int16Array.GetValue)); } if (typeof(T) == typeof(ushort)) { var uint16Array = new UInt16Array(array.Data); return((Func <int, T>)(object) new Func <int, ushort>( index => uint16Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(ushort?)) { var uint16Array = new UInt16Array(array.Data); return((Func <int, T>)(object) new Func <int, ushort?>(uint16Array.GetValue)); } if (typeof(T) == typeof(int)) { var int32Array = new Int32Array(array.Data); return((Func <int, T>)(object) new Func <int, int>( index => int32Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(int?)) { var int32Array = new Int32Array(array.Data); return((Func <int, T>)(object) new Func <int, int?>(int32Array.GetValue)); } if (typeof(T) == typeof(uint)) { var uint32Array = new UInt32Array(array.Data); return((Func <int, T>)(object) new Func <int, uint>( index => uint32Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(uint?)) { var uint32Array = new UInt32Array(array.Data); return((Func <int, T>)(object) new Func <int, uint?>(uint32Array.GetValue)); } if (typeof(T) == typeof(long)) { var int64Array = new Int64Array(array.Data); return((Func <int, T>)(object) new Func <int, long>( index => int64Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(long?)) { var int64Array = new Int64Array(array.Data); return((Func <int, T>)(object) new Func <int, long?>(int64Array.GetValue)); } if (typeof(T) == typeof(ulong)) { var uint64Array = new UInt64Array(array.Data); return((Func <int, T>)(object) new Func <int, ulong>( index => uint64Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(ulong?)) { var uint64Array = new UInt64Array(array.Data); return((Func <int, T>)(object) new Func <int, ulong?>(uint64Array.GetValue)); } if (typeof(T) == typeof(double)) { var doubleArray = new DoubleArray(array.Data); return((Func <int, T>)(object) new Func <int, double>( index => doubleArray.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(double?)) { var doubleArray = new DoubleArray(array.Data); return((Func <int, T>)(object) new Func <int, double?>(doubleArray.GetValue)); } if (typeof(T) == typeof(float)) { var floatArray = new FloatArray(array.Data); return((Func <int, T>)(object) new Func <int, float>( index => floatArray.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(float?)) { var floatArray = new FloatArray(array.Data); return((Func <int, T>)(object) new Func <int, float?>(floatArray.GetValue)); } if (typeof(T) == typeof(DateTime)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime>( index => date32Array.GetDate(index).GetValueOrDefault().DateTime)); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime>( index => date64Array.GetDate(index).GetValueOrDefault().DateTime)); } } if (typeof(T) == typeof(DateTime?)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime?>( index => date32Array.GetDate(index)?.DateTime)); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime?>( index => date64Array.GetDate(index)?.DateTime)); } } if (typeof(T) == typeof(DateTimeOffset)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset>( index => date32Array.GetDate(index).GetValueOrDefault())); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset>( index => date64Array.GetDate(index).GetValueOrDefault())); } } if (typeof(T) == typeof(DateTimeOffset?)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset?>( date32Array.GetDate)); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset?>( date64Array.GetDate)); } } if (typeof(T) == typeof(TimeSpan)) { var timestampArray = new TimestampArray(array.Data); return((Func <int, T>)(object) new Func <int, TimeSpan>( index => timestampArray.GetTimestamp(index).GetValueOrDefault().TimeOfDay)); } if (typeof(T) == typeof(TimeSpan?)) { var timestampArray = new TimestampArray(array.Data); return((Func <int, T>)(object) new Func <int, TimeSpan?>( index => timestampArray.GetTimestamp(index)?.TimeOfDay)); } if (typeof(T) == typeof(byte[])) { var binaryArray = new BinaryArray(array.Data); return((Func <int, T>)(object) new Func <int, byte[]>( // TODO: how to avoid this allocation/copy? index => binaryArray.GetBytes(index).ToArray())); } if (typeof(T) == typeof(string)) { var stringArray = new StringArray(array.Data); return((Func <int, T>)(object) new Func <int, string>( index => stringArray.GetString(index))); } // It's something else we don't yet support. switch (array.Data.DataType.TypeId) { case ArrowTypeId.Decimal: case ArrowTypeId.Dictionary: case ArrowTypeId.FixedSizedBinary: case ArrowTypeId.HalfFloat: case ArrowTypeId.Interval: case ArrowTypeId.List: case ArrowTypeId.Map: case ArrowTypeId.Null: case ArrowTypeId.Struct: case ArrowTypeId.Time32: case ArrowTypeId.Time64: case ArrowTypeId.Union: default: // TODO: support additional types? throw new NotSupportedException( $"Not supported array type: {array.Data.DataType.TypeId}"); } }