예제 #1
0
        /// <summary>
        /// Put binary types to Grid.
        /// </summary>
        /// <param name="types">Binary types.</param>
        public void PutBinaryTypes(ICollection <BinaryType> types)
        {
            DoOutOp((int)Op.PutMeta, w =>
            {
                w.WriteInt(types.Count);

                foreach (var meta in types)
                {
                    w.WriteInt(meta.TypeId);
                    w.WriteString(meta.TypeName);
                    w.WriteString(meta.AffinityKeyFieldName);

                    var fields = meta.GetFieldsMap();

                    w.WriteInt(fields.Count);

                    foreach (var field in fields)
                    {
                        w.WriteString(field.Key);
                        w.WriteInt(field.Value.TypeId);
                        w.WriteInt(field.Value.FieldId);
                    }

                    // Enum data
                    w.WriteBoolean(meta.IsEnum);

                    if (meta.IsEnum)
                    {
                        if (meta.EnumValuesMap != null)
                        {
                            w.WriteInt(meta.EnumValuesMap.Count);

                            foreach (var pair in meta.EnumValuesMap)
                            {
                                w.WriteString(pair.Key);
                                w.WriteInt(pair.Value);
                            }
                        }
                        else
                        {
                            w.WriteInt(0);
                        }
                    }

                    // Send schemas
                    var desc = meta.Descriptor;
                    Debug.Assert(desc != null);

                    var count    = 0;
                    var countPos = w.Stream.Position;
                    w.WriteInt(0); // Reserve for count

                    foreach (var schema in desc.Schema.GetAll())
                    {
                        w.WriteInt(schema.Key);

                        var ids = schema.Value;
                        w.WriteInt(ids.Length);

                        foreach (var id in ids)
                        {
                            w.WriteInt(id);
                        }

                        count++;
                    }

                    w.Stream.WriteInt(countPos, count);
                }
            });

            Marshaller.OnBinaryTypesSent(types);
        }
예제 #2
0
 /// <summary>
 /// Gets the type name by id.
 /// </summary>
 /// <param name="id">The identifier.</param>
 /// <returns>Type or null.</returns>
 public string GetTypeName(int id)
 {
     return(DoOutInOp((int)Op.GetType, w => w.WriteInt(id), r => Marshaller.StartUnmarshal(r).ReadString()));
 }
예제 #3
0
        /// <summary>
        /// Gets the Ignite-specific hash code for the provided value.
        /// </summary>
        public static unsafe int GetHashCode <T>(T val, Marshaller marsh, IDictionary <int, int> affinityKeyFieldIds)
        {
            Debug.Assert(marsh != null);
            Debug.Assert(val != null);

            var type = val.GetType();

            if (type == typeof(int))
            {
                return(TypeCaster <int> .Cast(val));
            }

            if (type == typeof(long))
            {
                return(GetLongHashCode(TypeCaster <long> .Cast(val)));
            }

            if (type == typeof(bool))
            {
                return(TypeCaster <bool> .Cast(val) ? 1231 : 1237);
            }

            if (type == typeof(byte))
            {
                return(TypeCaster <byte> .Cast(val));
            }

            if (type == typeof(short))
            {
                return(TypeCaster <short> .Cast(val));
            }

            if (type == typeof(char))
            {
                return(TypeCaster <char> .Cast(val));
            }

            if (type == typeof(float))
            {
                var floatVal = TypeCaster <float> .Cast(val);

                return(*(int *)&floatVal);
            }

            if (type == typeof(double))
            {
                var doubleVal = TypeCaster <double> .Cast(val);

                return(GetLongHashCode(*(long *)&doubleVal));
            }

            if (type == typeof(sbyte))
            {
                var val0 = TypeCaster <sbyte> .Cast(val);

                return(*(byte *)&val0);
            }

            if (type == typeof(ushort))
            {
                var val0 = TypeCaster <ushort> .Cast(val);

                return(*(short *)&val0);
            }

            if (type == typeof(uint))
            {
                var val0 = TypeCaster <uint> .Cast(val);

                return(*(int *)&val0);
            }

            if (type == typeof(ulong))
            {
                var val0 = TypeCaster <ulong> .Cast(val);

                return(GetLongHashCode(*(long *)&val0));
            }

            if (type == typeof(IntPtr))
            {
                var val0 = TypeCaster <IntPtr> .Cast(val).ToInt64();

                return(GetLongHashCode(val0));
            }

            if (type == typeof(UIntPtr))
            {
                var val0 = TypeCaster <UIntPtr> .Cast(val).ToUInt64();

                return(GetLongHashCode(*(long *)&val0));
            }

            if (type == typeof(Guid))
            {
                return(GetGuidHashCode(TypeCaster <Guid> .Cast(val)));
            }

            // DateTime, when used as key, is always written as BinaryObject.
            return(GetComplexTypeHashCode(val, marsh, affinityKeyFieldIds));
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BinaryProcessor"/> class.
 /// </summary>
 /// <param name="target">Target.</param>
 /// <param name="marsh">Marshaller.</param>
 public BinaryProcessor(IUnmanagedTarget target, Marshaller marsh) : base(target, marsh)
 {
     // No-op.
 }
예제 #5
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="marsh">Marshaller.</param>
 internal IgniteBinary(Marshaller marsh)
 {
     _marsh = marsh;
 }
예제 #6
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="marsh">Marshaller.</param>
 /// <param name="stream">Stream.</param>
 internal BinaryWriter(Marshaller marsh, IBinaryStream stream)
 {
     _marsh  = marsh;
     _stream = stream;
 }
예제 #7
0
        /** <inheritDoc /> */
        public int GetTypeId(string typeName)
        {
            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");

            return(Marshaller.GetDescriptor(typeName).TypeId);
        }
예제 #8
0
 /** <inheritDoc /> */
 public IBinaryType GetBinaryType(int typeId)
 {
     return(Marshaller.GetBinaryType(typeId));
 }
        /** <inheritdoc /> */
        int IBinaryEqualityComparer.GetHashCode(IBinaryStream stream, int startPos, int length,
                                                BinaryObjectSchemaHolder schema, int schemaId, Marshaller marshaller, IBinaryTypeDescriptor desc)
        {
            Debug.Assert(stream != null);
            Debug.Assert(startPos >= 0);
            Debug.Assert(length >= 0);
            Debug.Assert(schema != null);
            Debug.Assert(marshaller != null);
            Debug.Assert(desc != null);

            Validate();

            stream.Flush();

            // Preserve stream position.
            var pos = stream.Position;

            var reader = marshaller.StartUnmarshal(stream, BinaryMode.ForceBinary);
            var fields = schema.GetFullSchema(schemaId);

            int hash = 0;

            foreach (var fieldName in FieldNames)
            {
                int fieldId   = BinaryUtils.FieldId(desc.TypeId, fieldName, desc.NameMapper, desc.IdMapper);
                int fieldHash = 0;  // Null (missing) field hash code is 0.
                int fieldPos;

                if (fields.TryGetValue(fieldId, out fieldPos))
                {
                    stream.Seek(startPos + fieldPos - BinaryObjectHeader.Size, SeekOrigin.Begin);
                    var fieldVal = reader.Deserialize <object>();
                    fieldHash = fieldVal != null?fieldVal.GetHashCode() : 0;
                }

                hash = 31 * hash + fieldHash;
            }

            // Restore stream position.
            stream.Seek(pos, SeekOrigin.Begin);

            return(hash);
        }
예제 #10
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="marsh">Marshaller.</param>
 internal Binary(Marshaller marsh)
 {
     _marsh = marsh;
 }
예제 #11
0
        /// <summary>
        /// Gets the Ignite-specific hash code for an array.
        /// </summary>
        private static int GetArrayHashCode <T>(T val, Marshaller marsh, IDictionary <int, int> affinityKeyFieldIds)
        {
            var res = 1;

            var bytes = val as sbyte[];  // Matches byte[] too.

            if (bytes != null)
            {
                foreach (var x in bytes)
                {
                    res = 31 * res + x;
                }

                return(res);
            }

            var ints = val as int[]; // Matches uint[] too.

            if (ints != null)
            {
                foreach (var x in ints)
                {
                    res = 31 * res + x;
                }

                return(res);
            }

            var longs = val as long[]; // Matches ulong[] too.

            if (longs != null)
            {
                foreach (var x in longs)
                {
                    res = 31 * res + GetLongHashCode(x);
                }

                return(res);
            }

            var guids = val as Guid[];

            if (guids != null)
            {
                foreach (var x in guids)
                {
                    res = 31 * res + GetGuidHashCode(x);
                }

                return(res);
            }

            var shorts = val as short[]; // Matches ushort[] too.

            if (shorts != null)
            {
                foreach (var x in shorts)
                {
                    res = 31 * res + x;
                }

                return(res);
            }

            var chars = val as char[];

            if (chars != null)
            {
                foreach (var x in chars)
                {
                    res = 31 * res + x;
                }

                return(res);
            }

            // This covers all other arrays.
            // We don't have special handling for unlikely use cases such as float[] and double[].
            var arr = val as Array;

            Debug.Assert(arr != null);

            if (arr.Rank != 1)
            {
                throw new IgniteException(
                          string.Format("Failed to compute hash code for object '{0}' of type '{1}': " +
                                        "multidimensional arrays are not supported", val, val.GetType()));
            }

            foreach (var element in arr)
            {
                res = 31 * res + (element == null ? 0 : GetHashCode(element, marsh, affinityKeyFieldIds));
            }

            return(res);
        }
예제 #12
0
        /// <summary>
        /// Reads the unregistered type.
        /// </summary>
        private Type ReadUnregisteredType(Type knownType)
        {
            var typeName = ReadString();  // Must read always.

            return(knownType ?? Marshaller.ResolveType(typeName));
        }
예제 #13
0
        /// <summary>
        /// Reads the schema according to this header data.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="position">The position.</param>
        /// <param name="hdr">The header.</param>
        /// <param name="schema">The schema.</param>
        /// <param name="marsh">The marshaller.</param>
        /// <returns>
        /// Schema.
        /// </returns>
        public static BinaryObjectSchemaField[] ReadSchema(IBinaryStream stream, int position, BinaryObjectHeader hdr,
                                                           BinaryObjectSchema schema, Marshaller marsh)
        {
            Debug.Assert(stream != null);
            Debug.Assert(schema != null);
            Debug.Assert(marsh != null);

            return(ReadSchema(stream, position, hdr, () => GetFieldIds(hdr, schema, marsh)));
        }
예제 #14
0
        /// <summary>
        /// Gets the field ids.
        /// </summary>
        private static int[] GetFieldIds(BinaryObjectHeader hdr, BinaryObjectSchema schema, Marshaller marsh)
        {
            var fieldIds = schema.Get(hdr.SchemaId);

            if (fieldIds == null)
            {
                Debug.Assert(hdr.TypeId != BinaryUtils.TypeUnregistered);

                if (marsh.Ignite != null)
                {
                    fieldIds = marsh.Ignite.BinaryProcessor.GetSchema(hdr.TypeId, hdr.SchemaId);
                }

                if (fieldIds == null)
                {
                    throw new BinaryObjectException("Cannot find schema for object with compact footer [" +
                                                    "typeId=" + hdr.TypeId + ", schemaId=" + hdr.SchemaId + ']');
                }
            }
            return(fieldIds);
        }
예제 #15
0
        /// <summary>
        /// Gets the field ids.
        /// </summary>
        private static int[] GetFieldIds(BinaryObjectHeader hdr, BinaryObjectSchema schema, Marshaller marsh)
        {
            var fieldIds = schema.Get(hdr.SchemaId);

            if (fieldIds == null)
            {
                if (marsh.Ignite != null)
                {
                    fieldIds = marsh.Ignite.ClusterGroup.GetSchema(hdr.TypeId, hdr.SchemaId);
                }

                if (fieldIds == null)
                {
                    throw new BinaryObjectException("Cannot find schema for object with compact footer [" +
                                                    "typeId=" + hdr.TypeId + ", schemaId=" + hdr.SchemaId + ']');
                }
            }
            return(fieldIds);
        }