Skip to content

Commit 3b562b0

Browse files
authored
Add support for reading and writing the .NET Half type (#418)
1 parent 9d6ba70 commit 3b562b0

18 files changed

+214
-32
lines changed

cpp/LogicalType.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ extern "C"
106106
TRYCATCH(*logical_type = new std::shared_ptr(LogicalType::UUID());)
107107
}
108108

109+
PARQUETSHARP_EXPORT ExceptionInfo* LogicalType_Float16(const std::shared_ptr<const LogicalType>** logical_type)
110+
{
111+
TRYCATCH(*logical_type = new std::shared_ptr(LogicalType::Float16());)
112+
}
113+
109114
PARQUETSHARP_EXPORT ExceptionInfo* LogicalType_None(const std::shared_ptr<const LogicalType>** logical_type)
110115
{
111116
TRYCATCH(*logical_type = new std::shared_ptr(LogicalType::None());)

csharp.test/TestLogicalTypeRoundtrip.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,32 @@ private static ExpectedColumn[] CreateExpectedColumns()
16311631
Values = Enumerable.Range(0, NumRows).Select(i => i % 11 == 0 ? (Int96?) null : new Int96(i, i * i, i * i * i)).ToArray(),
16321632
HasStatistics = false
16331633
},
1634+
#if NET5_0_OR_GREATER
1635+
new ExpectedColumn
1636+
{
1637+
Name = "half_field",
1638+
PhysicalType = PhysicalType.FixedLenByteArray,
1639+
LogicalType = LogicalType.Float16(),
1640+
Length = 2,
1641+
Values = Enumerable.Range(0, NumRows).Select(i => i % 5 == 0 ? Half.NaN : (Half) Math.Sqrt(i)).ToArray(),
1642+
Min = (Half) 1.0,
1643+
Max = (Half) Math.Sqrt(NumRows - 1),
1644+
Converter = (v, _) => LogicalRead.ToHalf((FixedLenByteArray) v)
1645+
},
1646+
new ExpectedColumn
1647+
{
1648+
Name = "half?_field",
1649+
PhysicalType = PhysicalType.FixedLenByteArray,
1650+
LogicalType = LogicalType.Float16(),
1651+
Length = 2,
1652+
Values = Enumerable.Range(0, NumRows).Select(i => i % 11 == 0 ? (Half?) null : i % 5 == 0 ? Half.NaN : (Half) Math.Sqrt(i)).ToArray(),
1653+
NullCount = (NumRows + 10) / 11,
1654+
NumValues = NumRows - (NumRows + 10) / 11,
1655+
Min = (Half) 1.0,
1656+
Max = (Half) Math.Sqrt(NumRows - 1),
1657+
Converter = (v, _) => LogicalRead.ToHalf((FixedLenByteArray) v)
1658+
},
1659+
#endif
16341660
new ExpectedColumn
16351661
{
16361662
Name = "float_field",

csharp/AadPrefixVerifier.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ internal IntPtr CreateGcHandle()
2626

2727
internal static AadPrefixVerifier GetGcHandleTarget(IntPtr handle)
2828
{
29-
return (AadPrefixVerifier) GCHandle.FromIntPtr(handle).Target;
29+
return (AadPrefixVerifier) GCHandle.FromIntPtr(handle).Target!;
3030
}
3131

3232
internal delegate void FreeGcHandleFunc(IntPtr handle);
@@ -46,7 +46,7 @@ private static void Verify(IntPtr handle, IntPtr aadPrefix, out string? exceptio
4646

4747
try
4848
{
49-
var obj = (AadPrefixVerifier) GCHandle.FromIntPtr(handle).Target;
49+
var obj = (AadPrefixVerifier) GCHandle.FromIntPtr(handle).Target!;
5050
var aadPrefixStr = StringUtil.PtrToStringUtf8(aadPrefix);
5151
obj.Verify(aadPrefixStr);
5252
}

csharp/ByteArray.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public bool Equals(ByteArray other)
2323
return Length == other.Length && Pointer == other.Pointer;
2424
}
2525

26-
public override bool Equals(object obj)
26+
public override bool Equals(object? obj)
2727
{
2828
return obj is ByteArray other && Equals(other);
2929
}

csharp/ByteArrayReaderCache.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics.CodeAnalysis;
34
using System.Linq;
45
using System.Runtime.CompilerServices;
56

@@ -40,7 +41,11 @@ public TLogical Add(TPhysical physical, TLogical logical)
4041
}
4142

4243
[MethodImpl(MethodImplOptions.AggressiveInlining)]
44+
#if (NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER)
45+
public bool TryGetValue(TPhysical physical, [MaybeNullWhen(false)] out TLogical logical)
46+
#else
4347
public bool TryGetValue(TPhysical physical, out TLogical logical)
48+
#endif
4449
{
4550
if (_map == null) throw new InvalidOperationException("cache is not in a usable state");
4651
return _map.TryGetValue(physical, out logical);

csharp/Column.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@ public Column(Type logicalSystemType, string name, LogicalType? logicalTypeOverr
2121
{
2222
var isDecimal = logicalSystemType == typeof(decimal) || logicalSystemType == typeof(decimal?);
2323
var isUuid = logicalSystemType == typeof(Guid) || logicalSystemType == typeof(Guid?);
24+
#if NET5_0_OR_GREATER
25+
var isHalf = logicalSystemType == typeof(Half) || logicalSystemType == typeof(Half?);
26+
#else
27+
var isHalf = false;
28+
#endif
2429

25-
if (length != -1 && !isDecimal && !isUuid)
30+
if (length != -1 && !(isDecimal || isUuid || isHalf))
2631
{
27-
throw new ArgumentException("length can only be set with the decimal or Guid type");
32+
throw new ArgumentException("length can only be set with the decimal, Guid or Half type");
2833
}
2934

3035
if (isDecimal && !(logicalTypeOverride is DecimalLogicalType))
@@ -106,6 +111,13 @@ private static unsafe int GetTypeLength(Type logicalSystemType)
106111
return 16;
107112
}
108113

114+
#if NET5_0_OR_GREATER
115+
if (logicalSystemType == typeof(Half) || logicalSystemType == typeof(Half?))
116+
{
117+
return 2;
118+
}
119+
#endif
120+
109121
return -1;
110122
}
111123

@@ -119,7 +131,7 @@ private static Node CreateSchemaNode(LogicalTypeFactory logicalTypeFactory, Type
119131

120132
if (type.IsArray)
121133
{
122-
var item = CreateSchemaNode(logicalTypeFactory, type.GetElementType(), "item", logicalTypeOverride, length);
134+
var item = CreateSchemaNode(logicalTypeFactory, type.GetElementType()!, "item", logicalTypeOverride, length);
123135
var list = new GroupNode("list", Repetition.Repeated, new[] {item});
124136

125137
try

csharp/Date.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public bool Equals(Date other)
3939
return Days == other.Days;
4040
}
4141

42-
public override bool Equals(object obj)
42+
public override bool Equals(object? obj)
4343
{
4444
return obj is Date date && Equals(date);
4545
}
@@ -49,7 +49,7 @@ public override int GetHashCode()
4949
return Days;
5050
}
5151

52-
public int CompareTo(object obj)
52+
public int CompareTo(object? obj)
5353
{
5454
return obj switch
5555
{

csharp/DateTimeNanos.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public bool Equals(DateTimeNanos other)
3535
return Ticks == other.Ticks;
3636
}
3737

38-
public override bool Equals(object obj)
38+
public override bool Equals(object? obj)
3939
{
4040
return obj is DateTimeNanos date && Equals(date);
4141
}
@@ -45,7 +45,7 @@ public override int GetHashCode()
4545
return Ticks.GetHashCode();
4646
}
4747

48-
public int CompareTo(object obj)
48+
public int CompareTo(object? obj)
4949
{
5050
return obj switch
5151
{

csharp/DecryptionKeyRetriever.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ internal IntPtr CreateGcHandle()
2525

2626
internal static DecryptionKeyRetriever GetGcHandleTarget(IntPtr handle)
2727
{
28-
return (DecryptionKeyRetriever) GCHandle.FromIntPtr(handle).Target;
28+
return (DecryptionKeyRetriever) GCHandle.FromIntPtr(handle).Target!;
2929
}
3030

3131
internal delegate void FreeGcHandleFunc(IntPtr handle);
@@ -45,7 +45,7 @@ private static void GetKey(IntPtr handle, IntPtr keyMetadata, out AesKey key, ou
4545

4646
try
4747
{
48-
var obj = (DecryptionKeyRetriever) GCHandle.FromIntPtr(handle).Target;
48+
var obj = (DecryptionKeyRetriever) GCHandle.FromIntPtr(handle).Target!;
4949
var keyMetadataStr = StringUtil.PtrToStringUtf8(keyMetadata);
5050
key = new AesKey(obj.GetKey(keyMetadataStr));
5151
}

csharp/FixedLenByteArray.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public bool Equals(FixedLenByteArray other)
2121
return Pointer == other.Pointer;
2222
}
2323

24-
public override bool Equals(object obj)
24+
public override bool Equals(object? obj)
2525
{
2626
return obj is FixedLenByteArray other && Equals(other);
2727
}

0 commit comments

Comments
 (0)