Skip to content

Commit f0e07a0

Browse files
committed
Refactor Enum writer
1 parent 7c18505 commit f0e07a0

File tree

5 files changed

+45
-21
lines changed

5 files changed

+45
-21
lines changed

DuckDB.NET.Data/DuckDBAppender.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ public void Close()
7474
logicalType.Dispose();
7575
}
7676

77+
foreach (var writer in vectorWriters)
78+
{
79+
writer.Dispose();
80+
}
81+
7782
var state = NativeMethods.Appender.DuckDBAppenderClose(nativeAppender);
7883
if (!state.IsSuccess())
7984
{

DuckDB.NET.Data/DuckDBAppenderRow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void EndRow()
7070

7171
#region Append Enum
7272

73-
public DuckDBAppenderRow AppendValue<TEnum>(TEnum value) where TEnum : Enum => AppendValueInternal(value);
73+
public DuckDBAppenderRow AppendValue<TEnum>(TEnum? value) where TEnum : Enum => AppendValueInternal(value);
7474

7575
#endregion
7676

DuckDB.NET.Data/Internal/Writer/EnumVectorDataWriter.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,40 @@ namespace DuckDB.NET.Data.Internal.Writer;
99
internal sealed unsafe class EnumVectorDataWriter : VectorDataWriterBase
1010
{
1111
private readonly DuckDBType enumType;
12+
private readonly DuckDBLogicalType logicalType;
1213

1314
private readonly uint enumDictionarySize;
1415

15-
private readonly Dictionary<string, uint> enumValues;
16+
private readonly Dictionary<string, uint> enumValues = [];
1617

1718
public EnumVectorDataWriter(IntPtr vector, void* vectorData, DuckDBLogicalType logicalType, DuckDBType columnType) : base(vector, vectorData, columnType)
1819
{
20+
this.logicalType = logicalType;
21+
1922
enumType = NativeMethods.LogicalType.DuckDBEnumInternalType(logicalType);
2023
enumDictionarySize = NativeMethods.LogicalType.DuckDBEnumDictionarySize(logicalType);
2124

22-
uint maxEnumDictionarySize = enumType switch
25+
var maxEnumDictionarySize = enumType switch
2326
{
2427
DuckDBType.UnsignedTinyInt => byte.MaxValue,
2528
DuckDBType.UnsignedSmallInt => ushort.MaxValue,
2629
DuckDBType.UnsignedInteger => uint.MaxValue,
2730
_ => throw new NotSupportedException($"The internal enum type must be utinyint, usmallint, or uinteger."),
2831
};
29-
if (enumDictionarySize > maxEnumDictionarySize)
30-
{
31-
// This exception should only be thrown if the DuckDB library has a bug.
32-
throw new InvalidOperationException($"The internal enum type is \"{enumType}\" but the enum dictionary size is greater than {maxEnumDictionarySize}.");
33-
}
34-
35-
enumValues = [];
36-
for (uint index = 0; index < enumDictionarySize; index++)
37-
{
38-
string enumValueName = NativeMethods.LogicalType.DuckDBEnumDictionaryValue(logicalType, index).ToManagedString();
39-
enumValues.Add(enumValueName, index);
40-
}
4132
}
4233

4334
internal override bool AppendString(string value, int rowIndex)
4435
{
45-
if (enumValues.TryGetValue(value, out uint enumValue))
36+
if (enumValues.Count == 0)
37+
{
38+
for (uint index = 0; index < enumDictionarySize; index++)
39+
{
40+
var enumValueName = NativeMethods.LogicalType.DuckDBEnumDictionaryValue(logicalType, index).ToManagedString();
41+
enumValues.Add(enumValueName, index);
42+
}
43+
}
44+
45+
if (enumValues.TryGetValue(value, out var enumValue))
4646
{
4747
// The following casts to byte and ushort are safe because we ensure in the constructor that the value enumDictionarySize is not too high.
4848
return enumType switch
@@ -59,7 +59,7 @@ internal override bool AppendString(string value, int rowIndex)
5959

6060
internal override bool AppendEnum<TEnum>(TEnum value, int rowIndex)
6161
{
62-
ulong enumValue = ConvertEnumValueToUInt64(value);
62+
var enumValue = ConvertEnumValueToUInt64(value);
6363
if (enumValue < enumDictionarySize)
6464
{
6565
// The following casts to byte, ushort and uint are safe because we ensure in the constructor that the value enumDictionarySize is not too high.
@@ -72,12 +72,12 @@ internal override bool AppendEnum<TEnum>(TEnum value, int rowIndex)
7272
};
7373
}
7474

75-
throw new InvalidOperationException($"Failed to write Enum column because the value is outside the range (0-{enumDictionarySize-1}).");
75+
throw new InvalidOperationException($"Failed to write Enum column because the value is outside the range (0-{enumDictionarySize - 1}).");
7676
}
7777

7878
private static ulong ConvertEnumValueToUInt64<TEnum>(TEnum value) where TEnum : Enum
7979
{
80-
return Convert.GetTypeCode(value) switch
80+
return value.GetTypeCode() switch
8181
{
8282
TypeCode.SByte => (ulong)Convert.ToSByte(value),
8383
TypeCode.Byte => Convert.ToByte(value),
@@ -90,4 +90,10 @@ private static ulong ConvertEnumValueToUInt64<TEnum>(TEnum value) where TEnum :
9090
_ => throw new InvalidOperationException($"Failed to convert the enum value {value} to ulong."),
9191
};
9292
}
93+
94+
public override void Dispose()
95+
{
96+
logicalType.Dispose();
97+
base.Dispose();
98+
}
9399
}

DuckDB.NET.Data/Internal/Writer/ListVectorDataWriter.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ internal sealed unsafe class ListVectorDataWriter : VectorDataWriterBase
1010
{
1111
private ulong offset = 0;
1212
private readonly ulong arraySize;
13+
private readonly DuckDBLogicalType childType;
1314
private readonly VectorDataWriterBase listItemWriter;
1415

1516
public bool IsList => ColumnType == DuckDBType.List;
1617
private ulong vectorReservedSize = DuckDBGlobalData.VectorSize;
1718

1819
public ListVectorDataWriter(IntPtr vector, void* vectorData, DuckDBType columnType, DuckDBLogicalType logicalType) : base(vector, vectorData, columnType)
1920
{
20-
using var childType = IsList ? NativeMethods.LogicalType.DuckDBListTypeChildType(logicalType) : NativeMethods.LogicalType.DuckDBArrayTypeChildType(logicalType);
21+
childType = IsList ? NativeMethods.LogicalType.DuckDBListTypeChildType(logicalType) : NativeMethods.LogicalType.DuckDBArrayTypeChildType(logicalType);
2122
var childVector = IsList ? NativeMethods.Vectors.DuckDBListVectorGetChild(vector) : NativeMethods.Vectors.DuckDBArrayVectorGetChild(vector);
2223

2324
arraySize = IsList ? 0 : (ulong)NativeMethods.LogicalType.DuckDBArrayVectorGetSize(logicalType);
@@ -81,6 +82,7 @@ internal override bool AppendCollection(ICollection value, int rowIndex)
8182
#endif
8283
IEnumerable<DateTimeOffset> items => WriteItems(items),
8384
IEnumerable<DateTimeOffset?> items => WriteItems(items),
85+
IEnumerable<object> items => WriteItems(items),
8486

8587
_ => WriteItemsFallback(value),
8688
};
@@ -159,4 +161,10 @@ private void ResizeVector(int rowIndex, ulong count)
159161

160162
listItemWriter.InitializerWriter();
161163
}
164+
165+
public override void Dispose()
166+
{
167+
listItemWriter.Dispose();
168+
childType.Dispose();
169+
}
162170
}

DuckDB.NET.Data/Internal/Writer/VectorDataWriterBase.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace DuckDB.NET.Data.Internal.Writer;
88

9-
internal unsafe class VectorDataWriterBase(IntPtr vector, void* vectorData, DuckDBType columnType)
9+
internal unsafe class VectorDataWriterBase(IntPtr vector, void* vectorData, DuckDBType columnType) : IDisposable
1010
{
1111
private ulong* validity;
1212

@@ -118,4 +118,9 @@ internal void InitializerWriter()
118118
validity = default;
119119
vectorData = NativeMethods.Vectors.DuckDBVectorGetData(Vector);
120120
}
121+
122+
public virtual void Dispose()
123+
{
124+
125+
}
121126
}

0 commit comments

Comments
 (0)