private static void ConvertTimeSpanMillis(ReadOnlySpan <int> source, Span <TimeSpan> destination) { for (int i = 0; i != destination.Length; ++i) { destination[i] = LogicalRead.ToTimeSpanMillis(source[i]); } }
private static void ConvertTimeSpanMillis(ReadOnlySpan <int> source, ReadOnlySpan <short> defLevels, Span <TimeSpan?> destination, short nullLevel) { for (int i = 0, src = 0; i != destination.Length; ++i) { destination[i] = defLevels[i] == nullLevel ? default(TimeSpan?) : LogicalRead.ToTimeSpanMillis(source[src++]); } }
private static void ConvertDateTimeMicros(ReadOnlySpan <long> source, ReadOnlySpan <short> defLevels, Span <DateTime?> destination, short nullLevel) { for (int i = 0, src = 0; i != destination.Length; ++i) { destination[i] = defLevels[i] == nullLevel ? default(DateTime?) : LogicalRead.ToDateTimeMicros(source[src++]); } }
private static void ConvertDateTimeMillis(ReadOnlySpan <long> source, Span <DateTime> destination) { for (int i = 0; i != destination.Length; ++i) { destination[i] = LogicalRead.ToDateTimeMillis(source[i]); } }
private static void ConvertUuid(ReadOnlySpan <FixedLenByteArray> source, Span <Guid> destination) { for (int i = 0; i != destination.Length; ++i) { destination[i] = LogicalRead.ToUuid(source[i]); } }
private static void ConvertUuid(ReadOnlySpan <FixedLenByteArray> source, ReadOnlySpan <short> defLevels, Span <Guid?> destination, short nullLevel) { for (int i = 0, src = 0; i != destination.Length; ++i) { destination[i] = defLevels[i] == nullLevel ? default(Guid?) : LogicalRead.ToUuid(source[src++]); } }
private static void ConvertDecimal128(ReadOnlySpan <FixedLenByteArray> source, Span <decimal> destination, decimal multiplier) { for (int i = 0; i != destination.Length; ++i) { destination[i] = LogicalRead.ToDecimal(source[i], multiplier); } }
private static void ConvertDecimal128(ReadOnlySpan <FixedLenByteArray> source, ReadOnlySpan <short> defLevels, Span <decimal?> destination, decimal multiplier, short nullLevel) { for (int i = 0, src = 0; i != destination.Length; ++i) { destination[i] = defLevels[i] == nullLevel ? default(decimal?) : LogicalRead.ToDecimal(source[src++], multiplier); } }
private static void ConvertDateTimeMillis(ReadOnlySpan <long> source, Span <DateTime> destination) { var dst = MemoryMarshal.Cast <DateTime, long>(destination); for (int i = 0; i < destination.Length; ++i) { dst[i] = LogicalRead.ToDateTimeMillisTicks(source[i]); } }
private static string ToString(ByteArray byteArray, ByteArrayReaderCache <ByteArray, string> byteArrayCache) { if (byteArrayCache.TryGetValue(byteArray, out var str)) { // The string seems to already be in the cache. Check that the content matches. if (IsCacheValid(byteArrayCache, byteArray, str)) { return(str); } // The cache does not appear to be valid anymore. byteArrayCache.Clear(); } return(byteArrayCache.Add(byteArray, LogicalRead.ToString(byteArray))); }
public static Delegate?GetDirectReader() { if (typeof(TLogical) == typeof(bool) || typeof(TLogical) == typeof(int) || typeof(TLogical) == typeof(long) || typeof(TLogical) == typeof(Int96) || typeof(TLogical) == typeof(float) || typeof(TLogical) == typeof(double)) { return(LogicalRead.GetDirectReader <TPhysical, TPhysical>()); } if (typeof(TLogical) == typeof(uint)) { return(LogicalRead.GetDirectReader <uint, int>()); } if (typeof(TLogical) == typeof(ulong)) { return(LogicalRead.GetDirectReader <ulong, long>()); } return(null); }
private static void ConvertByteArray(ReadOnlySpan <ByteArray> source, ReadOnlySpan <short> defLevels, Span <byte[]> destination, short nullLevel) { for (int i = 0, src = 0; i != destination.Length; ++i) { destination[i] = !defLevels.IsEmpty && defLevels[i] == nullLevel ? null : LogicalRead.ToByteArray(source[src++]); } }
/// <summary> /// Return a converter delegate that converts a TPhysical readonly-span to a TLogical span. /// </summary> /// <returns> /// A delegate of type LogicalRead<TLogical, TPhysical>.Converter /// </returns> /// <param name="columnDescriptor">The descriptor of the column to be converted.</param> /// <param name="columnChunkMetaData">The metadata of the column-chunk to be converted.</param> public virtual Delegate GetConverter <TLogical, TPhysical>(ColumnDescriptor columnDescriptor, ColumnChunkMetaData columnChunkMetaData) where TPhysical : unmanaged { return(LogicalRead <TLogical, TPhysical> .GetConverter(columnDescriptor, columnChunkMetaData)); }
/// <summary> /// Return a reader delegate if a TPhysical column reader can directly write into a TLogical span (e.g. float to float, int to uint, etc). /// Otherwise return null. This is an optimisation to avoid needless memory copies between buffers (i.e. otherwise we have to use the /// identity converter). /// </summary> /// <returns> /// A delegate of type LogicalRead<TLogical, TPhysical>.DirectReader /// </returns> public virtual Delegate?GetDirectReader <TLogical, TPhysical>() where TPhysical : unmanaged { return(LogicalRead <TLogical, TPhysical> .GetDirectReader()); }
public static Delegate GetConverter(ColumnDescriptor columnDescriptor, ColumnChunkMetaData columnChunkMetaData) { if (typeof(TLogical) == typeof(bool) || typeof(TLogical) == typeof(int) || typeof(TLogical) == typeof(long) || typeof(TLogical) == typeof(Int96) || typeof(TLogical) == typeof(float) || typeof(TLogical) == typeof(double)) { return(LogicalRead.GetNativeConverter <TPhysical, TPhysical>()); } if (typeof(TLogical) == typeof(bool?) || typeof(TLogical) == typeof(int?) || typeof(TLogical) == typeof(long?) || typeof(TLogical) == typeof(Int96?) || typeof(TLogical) == typeof(float?) || typeof(TLogical) == typeof(double?)) { return(LogicalRead.GetNullableNativeConverter <TPhysical, TPhysical>()); } if (typeof(TLogical) == typeof(sbyte)) { return((LogicalRead <sbyte, int> .Converter)((s, _, d, _) => LogicalRead.ConvertInt8(s, d))); } if (typeof(TLogical) == typeof(sbyte?)) { return((LogicalRead <sbyte?, int> .Converter)LogicalRead.ConvertInt8); } if (typeof(TLogical) == typeof(byte)) { return((LogicalRead <byte, int> .Converter)((s, _, d, _) => LogicalRead.ConvertUInt8(s, d))); } if (typeof(TLogical) == typeof(byte?)) { return((LogicalRead <byte?, int> .Converter)LogicalRead.ConvertUInt8); } if (typeof(TLogical) == typeof(short)) { return((LogicalRead <short, int> .Converter)((s, _, d, _) => LogicalRead.ConvertInt16(s, d))); } if (typeof(TLogical) == typeof(short?)) { return((LogicalRead <short?, int> .Converter)LogicalRead.ConvertInt16); } if (typeof(TLogical) == typeof(ushort)) { return((LogicalRead <ushort, int> .Converter)((s, _, d, _) => LogicalRead.ConvertUInt16(s, d))); } if (typeof(TLogical) == typeof(ushort?)) { return((LogicalRead <ushort?, int> .Converter)LogicalRead.ConvertUInt16); } if (typeof(TLogical) == typeof(uint)) { return(LogicalRead.GetNativeConverter <uint, int>()); } if (typeof(TLogical) == typeof(uint?)) { return(LogicalRead.GetNullableNativeConverter <uint, int>()); } if (typeof(TLogical) == typeof(ulong)) { return(LogicalRead.GetNativeConverter <ulong, long>()); } if (typeof(TLogical) == typeof(ulong?)) { return(LogicalRead.GetNullableNativeConverter <ulong, long>()); } if (typeof(TLogical) == typeof(decimal)) { var multiplier = Decimal128.GetScaleMultiplier(columnDescriptor.TypeScale); return((LogicalRead <decimal, FixedLenByteArray> .Converter)((s, _, d, _) => LogicalRead.ConvertDecimal128(s, d, multiplier))); } if (typeof(TLogical) == typeof(decimal?)) { var multiplier = Decimal128.GetScaleMultiplier(columnDescriptor.TypeScale); return((LogicalRead <decimal?, FixedLenByteArray> .Converter)((s, dl, d, del) => LogicalRead.ConvertDecimal128(s, dl, d, multiplier, del))); } if (typeof(TLogical) == typeof(Guid)) { return((LogicalRead <Guid, FixedLenByteArray> .Converter)((s, _, d, _) => LogicalRead.ConvertUuid(s, d))); } if (typeof(TLogical) == typeof(Guid?)) { return((LogicalRead <Guid?, FixedLenByteArray> .Converter)LogicalRead.ConvertUuid); } if (typeof(TLogical) == typeof(Date)) { return(LogicalRead.GetNativeConverter <Date, int>()); } if (typeof(TLogical) == typeof(Date?)) { return(LogicalRead.GetNullableNativeConverter <Date, int>()); } var logicalType = columnDescriptor.LogicalType; if (typeof(TLogical) == typeof(DateTime)) { switch (((TimestampLogicalType)logicalType).TimeUnit) { case TimeUnit.Millis: return((LogicalRead <DateTime, long> .Converter)((s, _, d, _) => LogicalRead.ConvertDateTimeMillis(s, d))); case TimeUnit.Micros: return((LogicalRead <DateTime, long> .Converter)((s, _, d, _) => LogicalRead.ConvertDateTimeMicros(s, d))); } } if (typeof(TLogical) == typeof(DateTimeNanos)) { return(LogicalRead.GetNativeConverter <DateTimeNanos, long>()); } if (typeof(TLogical) == typeof(DateTime?)) { switch (((TimestampLogicalType)logicalType).TimeUnit) { case TimeUnit.Millis: return((LogicalRead <DateTime?, long> .Converter)LogicalRead.ConvertDateTimeMillis); case TimeUnit.Micros: return((LogicalRead <DateTime?, long> .Converter)LogicalRead.ConvertDateTimeMicros); case TimeUnit.Nanos: return((LogicalRead <TPhysical?, TPhysical> .Converter)LogicalRead.ConvertNative); } } if (typeof(TLogical) == typeof(DateTimeNanos?)) { return(LogicalRead.GetNullableNativeConverter <DateTimeNanos, long>()); } if (typeof(TLogical) == typeof(TimeSpan)) { switch (((TimeLogicalType)logicalType).TimeUnit) { case TimeUnit.Millis: return((LogicalRead <TimeSpan, int> .Converter)((s, _, d, _) => LogicalRead.ConvertTimeSpanMillis(s, d))); case TimeUnit.Micros: return((LogicalRead <TimeSpan, long> .Converter)((s, _, d, _) => LogicalRead.ConvertTimeSpanMicros(s, d))); } } if (typeof(TLogical) == typeof(TimeSpanNanos)) { return(LogicalRead.GetNativeConverter <TimeSpanNanos, long>()); } if (typeof(TLogical) == typeof(TimeSpan?)) { var timeLogicalType = (TimeLogicalType)logicalType; var timeUnit = timeLogicalType.TimeUnit; switch (timeUnit) { case TimeUnit.Millis: return((LogicalRead <TimeSpan?, int> .Converter)LogicalRead.ConvertTimeSpanMillis); case TimeUnit.Micros: return((LogicalRead <TimeSpan?, long> .Converter)LogicalRead.ConvertTimeSpanMicros); } } if (typeof(TLogical) == typeof(TimeSpanNanos?)) { return(LogicalRead.GetNullableNativeConverter <TimeSpanNanos, long>()); } if (typeof(TLogical) == typeof(string)) { var byteArrayCache = new ByteArrayReaderCache <TPhysical, TLogical>(columnChunkMetaData); return(byteArrayCache.IsUsable ? (LogicalRead <string?, ByteArray> .Converter)((s, dl, d, del) => LogicalRead.ConvertString(s, dl, d, del, (ByteArrayReaderCache <ByteArray, string>)(object) byteArrayCache)) : LogicalRead.ConvertString); } if (typeof(TLogical) == typeof(byte[])) { // Do not reuse byte[] instances, as they are not immutable. // Perhaps an optional optimisation if there is demand for it? //return byteArrayCache.IsUsable // ? (LogicalRead<byte[], ByteArray>.Converter) ((s, dl, d, nl) => ConvertByteArray(s, dl, d, nl, (ByteArrayReaderCache<ByteArray, byte[]>) (object) byteArrayCache)) // : (LogicalRead<byte[], ByteArray>.Converter) ConvertByteArray; return((LogicalRead <byte[]?, ByteArray> .Converter)LogicalRead.ConvertByteArray); } throw new NotSupportedException($"unsupported logical system type {typeof(TLogical)} with logical type {logicalType}"); }