Skip to content

Commit 75b3bcd

Browse files
committed
Optimise GetInt32.
Signed-off-by: Bradley Grainger <[email protected]>
1 parent 4bf3d69 commit 75b3bcd

File tree

3 files changed

+55
-21
lines changed

3 files changed

+55
-21
lines changed

src/MySqlConnector/Core/BinaryRow.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ protected override void GetDataOffsets(ReadOnlySpan<byte> data, int[] dataOffset
6969
}
7070
}
7171

72+
protected override int GetInt32Core(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition)
73+
{
74+
var isUnsigned = (columnDefinition.ColumnFlags & ColumnFlags.Unsigned) != 0;
75+
switch (columnDefinition.ColumnType)
76+
{
77+
case ColumnType.Tiny:
78+
return isUnsigned ? (int) data[0] : (sbyte) data[0];
79+
80+
case ColumnType.Int24:
81+
case ColumnType.Long:
82+
return isUnsigned ? checked((int) MemoryMarshal.Read<uint>(data)) : MemoryMarshal.Read<int>(data);
83+
84+
case ColumnType.Longlong:
85+
return isUnsigned ? checked((int) MemoryMarshal.Read<ulong>(data)) : checked((int) MemoryMarshal.Read<long>(data));
86+
87+
case ColumnType.Short:
88+
return isUnsigned ? (int) MemoryMarshal.Read<ushort>(data) : MemoryMarshal.Read<short>(data);
89+
90+
default:
91+
throw new FormatException();
92+
}
93+
}
94+
7295
protected override object GetValueCore(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition)
7396
{
7497
var isUnsigned = (columnDefinition.ColumnFlags & ColumnFlags.Unsigned) != 0;

src/MySqlConnector/Core/Row.cs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -200,29 +200,37 @@ public short GetInt16(int ordinal)
200200

201201
public int GetInt32(int ordinal)
202202
{
203-
var value = GetValue(ordinal);
204-
if (value is int)
205-
return (int) value;
203+
if (ordinal < 0 || ordinal > ResultSet.ColumnDefinitions!.Length)
204+
throw new ArgumentOutOfRangeException(nameof(ordinal), "value must be between 0 and {0}.".FormatInvariant(ResultSet.ColumnDefinitions!.Length));
206205

207-
if (value is sbyte)
208-
return (sbyte) value;
209-
if (value is byte)
210-
return (byte) value;
211-
if (value is short)
212-
return (short) value;
213-
if (value is ushort)
214-
return (ushort) value;
215-
if (value is uint)
216-
return checked((int) (uint) value);
217-
if (value is long)
218-
return checked((int) (long) value);
219-
if (value is ulong)
220-
return checked((int) (ulong) value);
221-
if (value is decimal)
222-
return (int) (decimal) value;
223-
return (int) value;
206+
if (m_dataOffsets[ordinal] == -1)
207+
throw new InvalidCastException();
208+
209+
var columnDefinition = ResultSet.ColumnDefinitions[ordinal];
210+
if ((columnDefinition.ColumnType != ColumnType.Tiny &&
211+
columnDefinition.ColumnType != ColumnType.Short &&
212+
columnDefinition.ColumnType != ColumnType.Int24 &&
213+
columnDefinition.ColumnType != ColumnType.Long &&
214+
columnDefinition.ColumnType != ColumnType.Longlong &&
215+
columnDefinition.ColumnType != ColumnType.Bit &&
216+
columnDefinition.ColumnType != ColumnType.Year &&
217+
columnDefinition.ColumnType != ColumnType.Decimal) ||
218+
(columnDefinition.ColumnType == ColumnType.Tiny && Connection.TreatTinyAsBoolean && columnDefinition.ColumnLength == 1 && (columnDefinition.ColumnFlags & ColumnFlags.Unsigned) == 0))
219+
{
220+
throw new InvalidCastException("Can't convert {0} to Int32".FormatInvariant(ResultSet.ColumnTypes![ordinal]));
221+
}
222+
223+
var data = m_data.Slice(m_dataOffsets[ordinal], m_dataLengths[ordinal]).Span;
224+
225+
if (columnDefinition.ColumnType == ColumnType.Bit)
226+
return checked((int) ReadBit(data, columnDefinition));
227+
else if (columnDefinition.ColumnType == ColumnType.Decimal)
228+
return (int) (decimal) GetValue(ordinal);
229+
return GetInt32Core(data, columnDefinition);
224230
}
225231

232+
protected abstract int GetInt32Core(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition);
233+
226234
public long GetInt64(int ordinal)
227235
{
228236
var value = GetValue(ordinal);
@@ -433,7 +441,7 @@ protected static Guid CreateGuidFromBytes(MySqlGuidFormat guidFormat, ReadOnlySp
433441
#endif
434442
}
435443

436-
protected static object ReadBit(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition)
444+
protected static ulong ReadBit(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition)
437445
{
438446
if ((columnDefinition.ColumnFlags & ColumnFlags.Binary) == 0)
439447
{

src/MySqlConnector/Core/TextRow.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ protected override void GetDataOffsets(ReadOnlySpan<byte> data, int[] dataOffset
3131
}
3232
}
3333

34+
protected override int GetInt32Core(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) =>
35+
!Utf8Parser.TryParse(data, out int value, out var bytesConsumed) || bytesConsumed != data.Length ? throw new OverflowException() : value;
36+
3437
protected override object GetValueCore(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition)
3538
{
3639
var isUnsigned = (columnDefinition.ColumnFlags & ColumnFlags.Unsigned) != 0;

0 commit comments

Comments
 (0)