예제 #1
0
        public KeyType(DataKind kind, ulong min, int count, bool contiguous = true)
            : base(ToRawType(kind), kind)
        {
            Contracts.CheckParam(min >= 0, nameof(min));
            Contracts.CheckParam(count >= 0, nameof(count), "count for key type must be non-negative");
            Contracts.CheckParam((ulong)count <= ulong.MaxValue - min, nameof(count));
            Contracts.CheckParam((ulong)count <= kind.ToMaxInt(), nameof(count));
            Contracts.CheckParam(contiguous || count == 0, nameof(count), "count must be 0 for non-contiguous");

            _contiguous = contiguous;
            _min        = min;
            _count      = count;
            Contracts.Assert(IsKey);
        }
예제 #2
0
        private KeyType(Type type, DataKind kind, ulong min, int count, bool contiguous)
            : base(type, kind)
        {
            Contracts.AssertValue(type);
            Contracts.Assert(kind.ToType() == type);

            Contracts.CheckParam(min >= 0, nameof(min));
            Contracts.CheckParam(count >= 0, nameof(count), "Must be non-negative.");
            Contracts.CheckParam((ulong)count <= ulong.MaxValue - min, nameof(count));
            Contracts.CheckParam((ulong)count <= kind.ToMaxInt(), nameof(count));
            Contracts.CheckParam(contiguous || count == 0, nameof(count), "Must be 0 for non-contiguous");

            Contiguous = contiguous;
            Min        = min;
            Count      = count;
        }
        private static bool TryCreateEx(IExceptionContext ectx, ColInfo info, DataKind kind, KeyRange range, out PrimitiveType itemType, out ColInfoEx ex)
        {
            ectx.AssertValue(info);
            ectx.Assert(Enum.IsDefined(typeof(DataKind), kind));

            ex = null;

            var typeSrc = info.TypeSrc;

            if (range != null)
            {
                itemType = TypeParsingUtils.ConstructKeyType(kind, range);
                if (!typeSrc.ItemType.IsKey && !typeSrc.ItemType.IsText)
                {
                    return(false);
                }
            }
            else if (!typeSrc.ItemType.IsKey)
            {
                itemType = PrimitiveType.FromKind(kind);
            }
            else if (!KeyType.IsValidDataKind(kind))
            {
                itemType = PrimitiveType.FromKind(kind);
                return(false);
            }
            else
            {
                var key = typeSrc.ItemType.AsKey;
                ectx.Assert(KeyType.IsValidDataKind(key.RawKind));
                int count = key.Count;
                // Technically, it's an error for the counts not to match, but we'll let the Conversions
                // code return false below. There's a possibility we'll change the standard conversions to
                // map out of bounds values to zero, in which case, this is the right thing to do.
                ulong max = kind.ToMaxInt();
                if ((ulong)count > max)
                {
                    count = (int)max;
                }
                itemType = new KeyType(kind, key.Min, count, key.Contiguous);
            }

            // Ensure that the conversion is legal. We don't actually cache the delegate here. It will get
            // re-fetched by the utils code when needed.
            bool     identity;
            Delegate del;

            if (!Conversions.Instance.TryGetStandardConversion(typeSrc.ItemType, itemType, out del, out identity))
            {
                return(false);
            }

            ColumnType typeDst = itemType;

            if (typeSrc.IsVector)
            {
                typeDst = new VectorType(itemType, typeSrc.AsVector);
            }

            // An output column is transposable iff the input column was transposable.
            VectorType slotType = null;

            if (info.SlotTypeSrc != null)
            {
                slotType = new VectorType(itemType, info.SlotTypeSrc);
            }

            ex = new ColInfoEx(kind, range != null, typeDst, slotType);
            return(true);
        }
예제 #4
0
        private static bool TryCreateEx(IExceptionContext ectx, ColInfo info, DataKind kind, KeyRange range,
                                        out PrimitiveType itemType, out ColInfoEx ex)
        {
            ectx.AssertValue(info);
            ectx.Assert(Enum.IsDefined(typeof(DataKind), kind));

            ex = null;

            var typeSrc = info.TypeSrc;

            if (range != null)
            {
                itemType = TypeParsingUtils.ConstructKeyType(kind, range);
                if (!typeSrc.ItemType().IsKey() && !typeSrc.ItemType().IsText() && typeSrc.ItemType().RawKind() != kind &&
                    !(typeSrc.ItemType().RawKind() == DataKind.I8 && (kind == DataKind.U8 || kind == DataKind.U4)))
                {
                    return(false);
                }
            }
            else if (!typeSrc.ItemType().IsKey())
            {
                itemType = ColumnTypeHelper.PrimitiveFromKind(kind);
            }
            else if (!ColumnTypeHelper.IsValidDataKind(kind))
            {
                itemType = ColumnTypeHelper.PrimitiveFromKind(kind);
                return(false);
            }
            else
            {
                var key = typeSrc.ItemType().AsKey();
                ectx.Assert(ColumnTypeHelper.IsValidDataKind(key.RawKind()));
                int count = key.Count;
                // Technically, it's an error for the counts not to match, but we'll let the Conversions
                // code return false below. There's a possibility we'll change the standard conversions to
                // map out of bounds values to zero, in which case, this is the right thing to do.
                ulong max = kind.ToMaxInt();
                if ((ulong)count > max)
                {
                    count = (int)max;
                }
                itemType = new KeyType(kind.ToType(), key.Min, count, key.Contiguous);
            }

            // Ensure that the conversion is legal. We don't actually cache the delegate here. It will get
            // re-fetched by the utils code when needed.
            bool     identity;
            Delegate del;

            if (!Conversions.Instance.TryGetStandardConversion(typeSrc.ItemType(), itemType, out del, out identity))
            {
                if (typeSrc.ItemType().RawKind() == itemType.RawKind())
                {
                    switch (typeSrc.ItemType().RawKind())
                    {
                    case DataKind.U4:
                        // Key starts at 1.
                        uint plus = (itemType.IsKey() ? (uint)1 : (uint)0) - (typeSrc.IsKey() ? (uint)1 : (uint)0);
                        identity = false;
                        ValueMapper <uint, uint> map_ = (in uint src, ref uint dst) => { dst = src + plus; };
                        del = (Delegate)map_;
                        if (del == null)
                        {
                            throw Contracts.ExceptNotSupp("Issue with casting");
                        }
                        break;

                    default:
                        throw Contracts.Except("Not suppoted type {0}", typeSrc.ItemType().RawKind());
                    }
                }
                else if (typeSrc.ItemType().RawKind() == DataKind.I8 && kind == DataKind.U8)
                {
                    ulong plus = (itemType.IsKey() ? (ulong)1 : (ulong)0) - (typeSrc.IsKey() ? (ulong)1 : (ulong)0);
                    identity = false;
                    ValueMapper <long, ulong> map_ = (in long src, ref ulong dst) =>
                    {
                        CheckRange(src, dst, ectx); dst = (ulong)src + plus;
                    };
                    del = (Delegate)map_;
                    if (del == null)
                    {
                        throw Contracts.ExceptNotSupp("Issue with casting");
                    }
                }
                else if (typeSrc.ItemType().RawKind() == DataKind.I8 && kind == DataKind.U4)
                {
                    uint plus = (itemType.IsKey() ? (uint)1 : (uint)0) - (typeSrc.IsKey() ? (uint)1 : (uint)0);
                    identity = false;
                    ValueMapper <long, uint> map_ = (in long src, ref uint dst) =>
                    {
                        CheckRange(src, dst, ectx); dst = (uint)src + plus;
                    };
                    del = (Delegate)map_;
                    if (del == null)
                    {
                        throw Contracts.ExceptNotSupp("Issue with casting");
                    }
                }
                else
                {
                    return(false);
                }
            }

            ColumnType typeDst = itemType;

            if (typeSrc.IsVector())
            {
                typeDst = new VectorType(itemType, typeSrc.AsVector().Dimensions.ToArray());
            }

            // An output column is transposable iff the input column was transposable.
            VectorType slotType = null;

            if (info.SlotTypeSrc != null)
            {
                slotType = new VectorType(itemType, info.SlotTypeSrc.Dimensions.ToArray());
            }

            ex = new ColInfoEx(kind, range != null, typeDst, slotType);
            return(true);
        }