예제 #1
0
        public override int GetHashCode()
        {
            var aSChd = ShardKey <TRecord> .GetValueBytes(this._greatGrandChildId);

            var aResult = new byte[4];

            if (!(aSChd is null))
            {
                if (aSChd.Length > 0)
                {
                    aResult[0] = aSChd[0];
                }
                if (aSChd.Length > 1)
                {
                    aResult[1] = aSChd[1];
                }
                if (aSChd.Length > 2)
                {
                    aResult[2] = aSChd[2];
                }
                if (aSChd.Length > 3)
                {
                    aResult[3] = aSChd[3];
                }
            }

            return(_key.GetHashCode() | BitConverter.ToInt32(aResult, 0));
        }
예제 #2
0
        internal byte[] ToArray()
        {
            var aOrigin   = System.Text.Encoding.UTF8.GetBytes(new[] { this._key.Origin });
            var shardData = ShardKey <TRecord> .GetValueBytes(_key.ShardId);

            var recordData = ShardKey <TRecord> .GetValueBytes(_key.RecordId);

            var childData = ShardKey <TRecord> .GetValueBytes(_key.ChildId);

            var grandChildData = ShardKey <TRecord> .GetValueBytes(_key.GrandChildId);

            var greatGrandChildData = ShardKey <TRecord> .GetValueBytes(_greatGrandChildId);

            var aResult = new byte[aOrigin.Length + shardData.Length + recordData.Length + childData.Length + grandChildData.Length + 1];

            aResult[0] = (byte)(aOrigin.Length | (1 << 2)); //origin length on bits 1 & 2, version (1) on bit 3.
            var resultIndex = 1;

            aOrigin.CopyTo(aResult, resultIndex);
            resultIndex += aOrigin.Length;
            shardData.CopyTo(aResult, resultIndex);
            resultIndex += shardData.Length;
            recordData.CopyTo(aResult, resultIndex);
            resultIndex += recordData.Length;
            childData.CopyTo(aResult, resultIndex);
            resultIndex += childData.Length;
            grandChildData.CopyTo(aResult, resultIndex);
            resultIndex += grandChildData.Length;
            greatGrandChildData.CopyTo(aResult, resultIndex);
            resultIndex += greatGrandChildData.Length;
            return(aResult);
        }
예제 #3
0
        internal static byte[] GetValueBytes(IComparable value)
        {
            switch (value)
            {
            case int i:
                return(BitConverter.GetBytes(i));

            case byte b:
                return(new byte[1] {
                    b
                });

            case short s:
                return(BitConverter.GetBytes(s));

            case long l:
                return(BitConverter.GetBytes(l));

            case char c:
                return(BitConverter.GetBytes(c));

            case decimal d:
                var aid = Decimal.GetBits(d);
                var i0  = BitConverter.GetBytes(aid[0]);
                var i1  = BitConverter.GetBytes(aid[1]);
                var i2  = BitConverter.GetBytes(aid[2]);
                var i3  = BitConverter.GetBytes(aid[3]);
                return(new byte[16] {
                    i0[0], i0[1], i0[2], i0[3], i1[0], i1[1], i1[2], i1[3], i2[0], i2[1], i2[2], i2[3], i3[0], i3[1], i3[2], i3[3]
                });

            case double o:
                return(BitConverter.GetBytes(o));

            case float f:
                return(BitConverter.GetBytes(f));

            case uint ui:
                return(BitConverter.GetBytes(ui));

            case ulong ul:
                return(BitConverter.GetBytes(ul));

            case ushort us:
                return(BitConverter.GetBytes(us));

            case sbyte sb:
                return(new byte[1] {
                    (byte)((int)sb + 128)
                });

            //case bool bln:
            //    return BitConverter.GetBytes(bln);
            case DateTime dt:
                return(BitConverter.GetBytes(dt.Ticks));

            case string str:
                if (str is null)
                {
                    return(new byte[1] {
                        0
                    });
                }
                else
                {
                    var aStr = System.Text.Encoding.UTF8.GetBytes(str);
                    if (aStr.Length > 128)
                    {
                        throw new Exception("Shard values cannot serialize strings longer than 128 bytes.");
                    }
                    var aResult = new byte[aStr.Length + 1];
                    aResult[0] = Convert.ToByte((aStr.Length << 1) + 1);
                    aStr.CopyTo(aResult, 1);
                    return(aResult);
                }

            case Enum e:
                var type     = Enum.GetUnderlyingType(value.GetType());
                var newValue = Convert.ChangeType(value, type);
                return(ShardKey <TRecord> .GetValueBytes(newValue as IComparable));

            case DateTimeOffset dto:
                var adt = BitConverter.GetBytes(dto.Ticks);
                var tsp = BitConverter.GetBytes(dto.Offset.Ticks);
                return(new byte[] { adt[0], adt[1], adt[2], adt[3], adt[4], adt[5], adt[6], adt[7], tsp[0], tsp[1], tsp[2], tsp[3], tsp[4], tsp[5], tsp[6], tsp[7] });

            case TimeSpan ts:
                return(BitConverter.GetBytes(ts.Ticks));

            case Guid g:
                return(g.ToByteArray());

            //case null:
            //    return new byte[0];
            default:
                if (value is Nullable)
                {
                    if (value == null)
                    {
                        return(BitConverter.GetBytes(true));
                    }
                    var shdType      = Nullable.GetUnderlyingType(value.GetType());
                    var nonNullValue = Convert.ChangeType(value, shdType);
                    var aVal         = GetValueBytes(nonNullValue as IComparable);
                    var valResult    = new byte[1 + aVal.Length];
                    valResult[0] = BitConverter.GetBytes(false)[0];
                    aVal.CopyTo(valResult, 1);
                    return(valResult);
                }
                else
                {
                    throw new Exception("Cannot serialize this type.");
                }
            }
        }