Beispiel #1
0
 private static void ConvertTimeSpanMillis(ReadOnlySpan <int> source, Span <TimeSpan> destination)
 {
     for (int i = 0; i != destination.Length; ++i)
     {
         destination[i] = LogicalRead.ToTimeSpanMillis(source[i]);
     }
 }
Beispiel #2
0
 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++]);
     }
 }
Beispiel #3
0
 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++]);
     }
 }
Beispiel #4
0
 private static void ConvertDateTimeMillis(ReadOnlySpan <long> source, Span <DateTime> destination)
 {
     for (int i = 0; i != destination.Length; ++i)
     {
         destination[i] = LogicalRead.ToDateTimeMillis(source[i]);
     }
 }
Beispiel #5
0
 private static void ConvertUuid(ReadOnlySpan <FixedLenByteArray> source, Span <Guid> destination)
 {
     for (int i = 0; i != destination.Length; ++i)
     {
         destination[i] = LogicalRead.ToUuid(source[i]);
     }
 }
Beispiel #6
0
 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++]);
     }
 }
Beispiel #7
0
 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);
     }
 }
Beispiel #8
0
 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);
     }
 }
Beispiel #9
0
        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]);
            }
        }
Beispiel #10
0
        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)));
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
 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&lt;TLogical, TPhysical&gt;.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&lt;TLogical, TPhysical&gt;.DirectReader
 /// </returns>
 public virtual Delegate?GetDirectReader <TLogical, TPhysical>()
     where TPhysical : unmanaged
 {
     return(LogicalRead <TLogical, TPhysical> .GetDirectReader());
 }
Beispiel #15
0
        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}");
        }