http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs deleted file mode 100644 index ea3e368..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs +++ /dev/null @@ -1,1421 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.IO; - using Apache.Ignite.Core.Impl.Portable.IO; - using Apache.Ignite.Core.Impl.Portable.Metadata; - using Apache.Ignite.Core.Impl.Portable.Structure; - using Apache.Ignite.Core.Portable; - - using PU = PortableUtils; - - /// <summary> - /// Portable writer implementation. - /// </summary> - internal class PortableWriterImpl : IPortableWriter, IPortableRawWriter - { - /** Marshaller. */ - private readonly PortableMarshaller _marsh; - - /** Stream. */ - private readonly IPortableStream _stream; - - /** Builder (used only during build). */ - private PortableBuilderImpl _builder; - - /** Handles. */ - private PortableHandleDictionary<object, long> _hnds; - - /** Metadatas collected during this write session. */ - private IDictionary<int, IPortableMetadata> _metas; - - /** Current type ID. */ - private int _curTypeId; - - /** Current name converter */ - private IPortableNameMapper _curConverter; - - /** Current mapper. */ - private IPortableIdMapper _curMapper; - - /** Current object start position. */ - private int _curPos; - - /** Current raw position. */ - private int _curRawPos; - - /** Whether we are currently detaching an object. */ - private bool _detaching; - - /** Current type structure tracker, */ - private PortableStructureTracker _curStruct; - - /** Schema holder. */ - private readonly PortableObjectSchemaHolder _schema = PortableObjectSchemaHolder.Current; - - /// <summary> - /// Gets the marshaller. - /// </summary> - internal PortableMarshaller Marshaller - { - get { return _marsh; } - } - - /// <summary> - /// Write named boolean value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Boolean value.</param> - public void WriteBoolean(string fieldName, bool val) - { - WriteFieldId(fieldName, PU.TypeBool); - - _stream.WriteByte(PU.TypeBool); - _stream.WriteBool(val); - } - - /// <summary> - /// Write boolean value. - /// </summary> - /// <param name="val">Boolean value.</param> - public void WriteBoolean(bool val) - { - _stream.WriteBool(val); - } - - /// <summary> - /// Write named boolean array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Boolean array.</param> - public void WriteBooleanArray(string fieldName, bool[] val) - { - WriteFieldId(fieldName, PU.TypeArrayBool); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayBool); - PU.WriteBooleanArray(val, _stream); - } - } - - /// <summary> - /// Write boolean array. - /// </summary> - /// <param name="val">Boolean array.</param> - public void WriteBooleanArray(bool[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayBool); - PU.WriteBooleanArray(val, _stream); - } - } - - /// <summary> - /// Write named byte value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Byte value.</param> - public void WriteByte(string fieldName, byte val) - { - WriteFieldId(fieldName, PU.TypeBool); - - _stream.WriteByte(PU.TypeByte); - _stream.WriteByte(val); - } - - /// <summary> - /// Write byte value. - /// </summary> - /// <param name="val">Byte value.</param> - public void WriteByte(byte val) - { - _stream.WriteByte(val); - } - - /// <summary> - /// Write named byte array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Byte array.</param> - public void WriteByteArray(string fieldName, byte[] val) - { - WriteFieldId(fieldName, PU.TypeArrayByte); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayByte); - PU.WriteByteArray(val, _stream); - } - } - - /// <summary> - /// Write byte array. - /// </summary> - /// <param name="val">Byte array.</param> - public void WriteByteArray(byte[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayByte); - PU.WriteByteArray(val, _stream); - } - } - - /// <summary> - /// Write named short value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Short value.</param> - public void WriteShort(string fieldName, short val) - { - WriteFieldId(fieldName, PU.TypeShort); - - _stream.WriteByte(PU.TypeShort); - _stream.WriteShort(val); - } - - /// <summary> - /// Write short value. - /// </summary> - /// <param name="val">Short value.</param> - public void WriteShort(short val) - { - _stream.WriteShort(val); - } - - /// <summary> - /// Write named short array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Short array.</param> - public void WriteShortArray(string fieldName, short[] val) - { - WriteFieldId(fieldName, PU.TypeArrayShort); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayShort); - PU.WriteShortArray(val, _stream); - } - } - - /// <summary> - /// Write short array. - /// </summary> - /// <param name="val">Short array.</param> - public void WriteShortArray(short[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayShort); - PU.WriteShortArray(val, _stream); - } - } - - /// <summary> - /// Write named char value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Char value.</param> - public void WriteChar(string fieldName, char val) - { - WriteFieldId(fieldName, PU.TypeChar); - - _stream.WriteByte(PU.TypeChar); - _stream.WriteChar(val); - } - - /// <summary> - /// Write char value. - /// </summary> - /// <param name="val">Char value.</param> - public void WriteChar(char val) - { - _stream.WriteChar(val); - } - - /// <summary> - /// Write named char array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Char array.</param> - public void WriteCharArray(string fieldName, char[] val) - { - WriteFieldId(fieldName, PU.TypeArrayChar); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayChar); - PU.WriteCharArray(val, _stream); - } - } - - /// <summary> - /// Write char array. - /// </summary> - /// <param name="val">Char array.</param> - public void WriteCharArray(char[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayChar); - PU.WriteCharArray(val, _stream); - } - } - - /// <summary> - /// Write named int value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Int value.</param> - public void WriteInt(string fieldName, int val) - { - WriteFieldId(fieldName, PU.TypeInt); - - _stream.WriteByte(PU.TypeInt); - _stream.WriteInt(val); - } - - /// <summary> - /// Write int value. - /// </summary> - /// <param name="val">Int value.</param> - public void WriteInt(int val) - { - _stream.WriteInt(val); - } - - /// <summary> - /// Write named int array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Int array.</param> - public void WriteIntArray(string fieldName, int[] val) - { - WriteFieldId(fieldName, PU.TypeArrayInt); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayInt); - PU.WriteIntArray(val, _stream); - } - } - - /// <summary> - /// Write int array. - /// </summary> - /// <param name="val">Int array.</param> - public void WriteIntArray(int[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayInt); - PU.WriteIntArray(val, _stream); - } - } - - /// <summary> - /// Write named long value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Long value.</param> - public void WriteLong(string fieldName, long val) - { - WriteFieldId(fieldName, PU.TypeLong); - - _stream.WriteByte(PU.TypeLong); - _stream.WriteLong(val); - } - - /// <summary> - /// Write long value. - /// </summary> - /// <param name="val">Long value.</param> - public void WriteLong(long val) - { - _stream.WriteLong(val); - } - - /// <summary> - /// Write named long array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Long array.</param> - public void WriteLongArray(string fieldName, long[] val) - { - WriteFieldId(fieldName, PU.TypeArrayLong); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayLong); - PU.WriteLongArray(val, _stream); - } - } - - /// <summary> - /// Write long array. - /// </summary> - /// <param name="val">Long array.</param> - public void WriteLongArray(long[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayLong); - PU.WriteLongArray(val, _stream); - } - } - - /// <summary> - /// Write named float value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Float value.</param> - public void WriteFloat(string fieldName, float val) - { - WriteFieldId(fieldName, PU.TypeFloat); - - _stream.WriteByte(PU.TypeFloat); - _stream.WriteFloat(val); - } - - /// <summary> - /// Write float value. - /// </summary> - /// <param name="val">Float value.</param> - public void WriteFloat(float val) - { - _stream.WriteFloat(val); - } - - /// <summary> - /// Write named float array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Float array.</param> - public void WriteFloatArray(string fieldName, float[] val) - { - WriteFieldId(fieldName, PU.TypeArrayFloat); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayFloat); - PU.WriteFloatArray(val, _stream); - } - } - - /// <summary> - /// Write float array. - /// </summary> - /// <param name="val">Float array.</param> - public void WriteFloatArray(float[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayFloat); - PU.WriteFloatArray(val, _stream); - } - } - - /// <summary> - /// Write named double value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Double value.</param> - public void WriteDouble(string fieldName, double val) - { - WriteFieldId(fieldName, PU.TypeDouble); - - _stream.WriteByte(PU.TypeDouble); - _stream.WriteDouble(val); - } - - /// <summary> - /// Write double value. - /// </summary> - /// <param name="val">Double value.</param> - public void WriteDouble(double val) - { - _stream.WriteDouble(val); - } - - /// <summary> - /// Write named double array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Double array.</param> - public void WriteDoubleArray(string fieldName, double[] val) - { - WriteFieldId(fieldName, PU.TypeArrayDouble); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayDouble); - PU.WriteDoubleArray(val, _stream); - } - } - - /// <summary> - /// Write double array. - /// </summary> - /// <param name="val">Double array.</param> - public void WriteDoubleArray(double[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayDouble); - PU.WriteDoubleArray(val, _stream); - } - } - - /// <summary> - /// Write named decimal value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Decimal value.</param> - public void WriteDecimal(string fieldName, decimal? val) - { - WriteFieldId(fieldName, PU.TypeDecimal); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeDecimal); - PortableUtils.WriteDecimal(val.Value, _stream); - } - } - - /// <summary> - /// Write decimal value. - /// </summary> - /// <param name="val">Decimal value.</param> - public void WriteDecimal(decimal? val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeDecimal); - PortableUtils.WriteDecimal(val.Value, _stream); - } - } - - /// <summary> - /// Write named decimal array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Decimal array.</param> - public void WriteDecimalArray(string fieldName, decimal?[] val) - { - WriteFieldId(fieldName, PU.TypeArrayDecimal); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayDecimal); - PU.WriteDecimalArray(val, _stream); - } - } - - /// <summary> - /// Write decimal array. - /// </summary> - /// <param name="val">Decimal array.</param> - public void WriteDecimalArray(decimal?[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayDecimal); - PU.WriteDecimalArray(val, _stream); - } - } - - /// <summary> - /// Write named date value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Date value.</param> - public void WriteTimestamp(string fieldName, DateTime? val) - { - WriteFieldId(fieldName, PU.TypeTimestamp); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PortableUtils.TypeTimestamp); - PortableUtils.WriteTimestamp(val.Value, _stream); - } - } - - /// <summary> - /// Write date value. - /// </summary> - /// <param name="val">Date value.</param> - public void WriteTimestamp(DateTime? val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PortableUtils.TypeTimestamp); - PortableUtils.WriteTimestamp(val.Value, _stream); - } - } - - /// <summary> - /// Write named date array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Date array.</param> - public void WriteTimestampArray(string fieldName, DateTime?[] val) - { - WriteFieldId(fieldName, PU.TypeTimestamp); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PortableUtils.TypeArrayTimestamp); - PortableUtils.WriteTimestampArray(val, _stream); - } - } - - /// <summary> - /// Write date array. - /// </summary> - /// <param name="val">Date array.</param> - public void WriteTimestampArray(DateTime?[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PortableUtils.TypeArrayTimestamp); - PortableUtils.WriteTimestampArray(val, _stream); - } - } - - /// <summary> - /// Write named string value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">String value.</param> - public void WriteString(string fieldName, string val) - { - WriteFieldId(fieldName, PU.TypeString); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeString); - PU.WriteString(val, _stream); - } - } - - /// <summary> - /// Write string value. - /// </summary> - /// <param name="val">String value.</param> - public void WriteString(string val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeString); - PU.WriteString(val, _stream); - } - } - - /// <summary> - /// Write named string array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">String array.</param> - public void WriteStringArray(string fieldName, string[] val) - { - WriteFieldId(fieldName, PU.TypeArrayString); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayString); - PU.WriteStringArray(val, _stream); - } - } - - /// <summary> - /// Write string array. - /// </summary> - /// <param name="val">String array.</param> - public void WriteStringArray(string[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayString); - PU.WriteStringArray(val, _stream); - } - } - - /// <summary> - /// Write named GUID value. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">GUID value.</param> - public void WriteGuid(string fieldName, Guid? val) - { - WriteFieldId(fieldName, PU.TypeGuid); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeGuid); - PU.WriteGuid(val.Value, _stream); - } - } - - /// <summary> - /// Write GUID value. - /// </summary> - /// <param name="val">GUID value.</param> - public void WriteGuid(Guid? val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeGuid); - PU.WriteGuid(val.Value, _stream); - } - } - - /// <summary> - /// Write named GUID array. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">GUID array.</param> - public void WriteGuidArray(string fieldName, Guid?[] val) - { - WriteFieldId(fieldName, PU.TypeArrayGuid); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayGuid); - PU.WriteGuidArray(val, _stream); - } - } - - /// <summary> - /// Write GUID array. - /// </summary> - /// <param name="val">GUID array.</param> - public void WriteGuidArray(Guid?[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayGuid); - PU.WriteGuidArray(val, _stream); - } - } - - /// <summary> - /// Write named enum value. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Enum value.</param> - public void WriteEnum<T>(string fieldName, T val) - { - WriteFieldId(fieldName, PU.TypeEnum); - - _stream.WriteByte(PU.TypeEnum); - PortableUtils.WriteEnum(_stream, (Enum)(object)val); - } - - /// <summary> - /// Write enum value. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="val">Enum value.</param> - public void WriteEnum<T>(T val) - { - _stream.WriteByte(PU.TypeEnum); - PortableUtils.WriteEnum(_stream, (Enum)(object)val); - } - - /// <summary> - /// Write named enum array. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Enum array.</param> - public void WriteEnumArray<T>(string fieldName, T[] val) - { - WriteFieldId(fieldName, PU.TypeArrayEnum); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArrayEnum); - PortableUtils.WriteArray(val, this); - } - } - - /// <summary> - /// Write enum array. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="val">Enum array.</param> - public void WriteEnumArray<T>(T[] val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArrayEnum); - PortableUtils.WriteArray(val, this); - } - } - - /// <summary> - /// Write named object value. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Object value.</param> - public void WriteObject<T>(string fieldName, T val) - { - WriteFieldId(fieldName, PU.TypeObject); - - if (val == null) - WriteNullField(); - else - Write(val); - } - - /// <summary> - /// Write object value. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="val">Object value.</param> - public void WriteObject<T>(T val) - { - Write(val); - } - - /// <summary> - /// Write named object array. - /// </summary> - /// <typeparam name="T">Element type.</typeparam> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Object array.</param> - public void WriteArray<T>(string fieldName, T[] val) - { - WriteFieldId(fieldName, PU.TypeArray); - - if (val == null) - WriteNullField(); - else - { - _stream.WriteByte(PU.TypeArray); - PortableUtils.WriteArray(val, this); - } - } - - /// <summary> - /// Write object array. - /// </summary> - /// <typeparam name="T">Element type.</typeparam> - /// <param name="val">Object array.</param> - public void WriteArray<T>(T[] val) - { - WriteArrayInternal(val); - } - - /// <summary> - /// Write object array. - /// </summary> - /// <param name="val">Object array.</param> - public void WriteArrayInternal(Array val) - { - if (val == null) - WriteNullRawField(); - else - { - _stream.WriteByte(PU.TypeArray); - PortableUtils.WriteArray(val, this); - } - } - - /// <summary> - /// Write named collection. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Collection.</param> - public void WriteCollection(string fieldName, ICollection val) - { - WriteFieldId(fieldName, PU.TypeCollection); - - if (val == null) - WriteNullField(); - else - WriteCollection(val); - } - - /// <summary> - /// Write collection. - /// </summary> - /// <param name="val">Collection.</param> - public void WriteCollection(ICollection val) - { - WriteByte(PU.TypeCollection); - PU.WriteCollection(val, this); - } - - /// <summary> - /// Write named dictionary. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="val">Dictionary.</param> - public void WriteDictionary(string fieldName, IDictionary val) - { - WriteFieldId(fieldName, PU.TypeDictionary); - - if (val == null) - WriteNullField(); - else - WriteDictionary(val); - } - - /// <summary> - /// Write dictionary. - /// </summary> - /// <param name="val">Dictionary.</param> - public void WriteDictionary(IDictionary val) - { - WriteByte(PU.TypeDictionary); - PU.WriteDictionary(val, this); - } - - /// <summary> - /// Write NULL field. - /// </summary> - private void WriteNullField() - { - _stream.WriteByte(PU.HdrNull); - } - - /// <summary> - /// Write NULL raw field. - /// </summary> - private void WriteNullRawField() - { - _stream.WriteByte(PU.HdrNull); - } - - /// <summary> - /// Get raw writer. - /// </summary> - /// <returns> - /// Raw writer. - /// </returns> - public IPortableRawWriter GetRawWriter() - { - if (_curRawPos == 0) - _curRawPos = _stream.Position; - - return this; - } - - /// <summary> - /// Set new builder. - /// </summary> - /// <param name="builder">Builder.</param> - /// <returns>Previous builder.</returns> - internal PortableBuilderImpl SetBuilder(PortableBuilderImpl builder) - { - PortableBuilderImpl ret = _builder; - - _builder = builder; - - return ret; - } - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="marsh">Marshaller.</param> - /// <param name="stream">Stream.</param> - internal PortableWriterImpl(PortableMarshaller marsh, IPortableStream stream) - { - _marsh = marsh; - _stream = stream; - } - - /// <summary> - /// Write object. - /// </summary> - /// <param name="obj">Object.</param> - public void Write<T>(T obj) - { - // Handle special case for null. - if (obj == null) - { - _stream.WriteByte(PU.HdrNull); - - return; - } - - // We use GetType() of a real object instead of typeof(T) to take advantage of - // automatic Nullable'1 unwrapping. - Type type = obj.GetType(); - - // Handle common case when primitive is written. - if (type.IsPrimitive) - { - WritePrimitive(obj, type); - - return; - } - - // Handle special case for builder. - if (WriteBuilderSpecials(obj)) - return; - - // Suppose that we faced normal object and perform descriptor lookup. - IPortableTypeDescriptor desc = _marsh.GetDescriptor(type); - - if (desc != null) - { - // Writing normal object. - var pos = _stream.Position; - - // Dealing with handles. - if (!(desc.Serializer is IPortableSystemTypeSerializer) && WriteHandle(pos, obj)) - return; - - // Skip header length as not everything is known now - _stream.Seek(PortableObjectHeader.Size, SeekOrigin.Current); - - // Preserve old frame. - int oldTypeId = _curTypeId; - IPortableNameMapper oldConverter = _curConverter; - IPortableIdMapper oldMapper = _curMapper; - int oldRawPos = _curRawPos; - var oldPos = _curPos; - - var oldStruct = _curStruct; - - // Push new frame. - _curTypeId = desc.TypeId; - _curConverter = desc.NameMapper; - _curMapper = desc.IdMapper; - _curRawPos = 0; - _curPos = pos; - - _curStruct = new PortableStructureTracker(desc, desc.WriterTypeStructure); - var schemaIdx = _schema.PushSchema(); - - try - { - // Write object fields. - desc.Serializer.WritePortable(obj, this); - - // Write schema - var schemaOffset = _stream.Position - pos; - - int schemaId; - short flags; - var hasSchema = _schema.WriteSchema(_stream, schemaIdx, out schemaId, out flags); - - if (!hasSchema) - schemaOffset = PortableObjectHeader.Size; - - // Calculate and write header. - if (hasSchema && _curRawPos > 0) - _stream.WriteInt(_curRawPos - pos); // raw offset is in the last 4 bytes - - var len = _stream.Position - pos; - - var header = new PortableObjectHeader(desc.UserType, desc.TypeId, obj.GetHashCode(), len, - schemaId, schemaOffset, !hasSchema, flags); - - PortableObjectHeader.Write(header, _stream, pos); - - Stream.Seek(pos + len, SeekOrigin.Begin); // Seek to the end - } - finally - { - _schema.PopSchema(schemaIdx); - } - - // Apply structure updates if any. - _curStruct.UpdateWriterStructure(this); - - // Restore old frame. - _curTypeId = oldTypeId; - _curConverter = oldConverter; - _curMapper = oldMapper; - _curRawPos = oldRawPos; - _curPos = oldPos; - - _curStruct = oldStruct; - } - else - { - // Are we dealing with a well-known type? - var handler = PortableSystemHandlers.GetWriteHandler(type); - - if (handler == null) // We did our best, object cannot be marshalled. - throw new PortableException("Unsupported object type [type=" + type + ", object=" + obj + ']'); - - handler(this, obj); - } - } - - /// <summary> - /// Write primitive type. - /// </summary> - /// <param name="val">Object.</param> - /// <param name="type">Type.</param> - private unsafe void WritePrimitive<T>(T val, Type type) - { - // .Net defines 14 primitive types. We support 12 - excluding IntPtr and UIntPtr. - // Types check sequence is designed to minimize comparisons for the most frequent types. - - if (type == typeof(int)) - { - _stream.WriteByte(PU.TypeInt); - _stream.WriteInt((int)(object)val); - } - else if (type == typeof(long)) - { - _stream.WriteByte(PU.TypeLong); - _stream.WriteLong((long)(object)val); - } - else if (type == typeof(bool)) - { - _stream.WriteByte(PU.TypeBool); - _stream.WriteBool((bool)(object)val); - } - else if (type == typeof(byte)) - { - _stream.WriteByte(PU.TypeByte); - _stream.WriteByte((byte)(object)val); - } - else if (type == typeof(short)) - { - _stream.WriteByte(PU.TypeShort); - _stream.WriteShort((short)(object)val); - } - else if (type == typeof (char)) - { - _stream.WriteByte(PU.TypeChar); - _stream.WriteChar((char)(object)val); - } - else if (type == typeof(float)) - { - _stream.WriteByte(PU.TypeFloat); - _stream.WriteFloat((float)(object)val); - } - else if (type == typeof(double)) - { - _stream.WriteByte(PU.TypeDouble); - _stream.WriteDouble((double)(object)val); - } - else if (type == typeof(sbyte)) - { - sbyte val0 = (sbyte)(object)val; - - _stream.WriteByte(PU.TypeByte); - _stream.WriteByte(*(byte*)&val0); - } - else if (type == typeof(ushort)) - { - ushort val0 = (ushort)(object)val; - - _stream.WriteByte(PU.TypeShort); - _stream.WriteShort(*(short*)&val0); - } - else if (type == typeof(uint)) - { - uint val0 = (uint)(object)val; - - _stream.WriteByte(PU.TypeInt); - _stream.WriteInt(*(int*)&val0); - } - else if (type == typeof(ulong)) - { - ulong val0 = (ulong)(object)val; - - _stream.WriteByte(PU.TypeLong); - _stream.WriteLong(*(long*)&val0); - } - else - throw new PortableException("Unsupported object type [type=" + type.FullName + ", object=" + val + ']'); - } - - /// <summary> - /// Try writing object as special builder type. - /// </summary> - /// <param name="obj">Object.</param> - /// <returns>True if object was written, false otherwise.</returns> - private bool WriteBuilderSpecials<T>(T obj) - { - if (_builder != null) - { - // Special case for portable object during build. - PortableUserObject portObj = obj as PortableUserObject; - - if (portObj != null) - { - if (!WriteHandle(_stream.Position, portObj)) - _builder.ProcessPortable(_stream, portObj); - - return true; - } - - // Special case for builder during build. - PortableBuilderImpl portBuilder = obj as PortableBuilderImpl; - - if (portBuilder != null) - { - if (!WriteHandle(_stream.Position, portBuilder)) - _builder.ProcessBuilder(_stream, portBuilder); - - return true; - } - } - - return false; - } - - /// <summary> - /// Add handle to handles map. - /// </summary> - /// <param name="pos">Position in stream.</param> - /// <param name="obj">Object.</param> - /// <returns><c>true</c> if object was written as handle.</returns> - private bool WriteHandle(long pos, object obj) - { - if (_hnds == null) - { - // Cache absolute handle position. - _hnds = new PortableHandleDictionary<object, long>(obj, pos); - - return false; - } - - long hndPos; - - if (!_hnds.TryGetValue(obj, out hndPos)) - { - // Cache absolute handle position. - _hnds.Add(obj, pos); - - return false; - } - - _stream.WriteByte(PU.HdrHnd); - - // Handle is written as difference between position before header and handle position. - _stream.WriteInt((int)(pos - hndPos)); - - return true; - } - - /// <summary> - /// Perform action with detached semantics. - /// </summary> - /// <param name="a"></param> - internal void WithDetach(Action<PortableWriterImpl> a) - { - if (_detaching) - a(this); - else - { - _detaching = true; - - PortableHandleDictionary<object, long> oldHnds = _hnds; - _hnds = null; - - try - { - a(this); - } - finally - { - _detaching = false; - - if (oldHnds != null) - { - // Merge newly recorded handles with old ones and restore old on the stack. - // Otherwise we can use current handles right away. - if (_hnds != null) - oldHnds.Merge(_hnds); - - _hnds = oldHnds; - } - } - } - } - - /// <summary> - /// Stream. - /// </summary> - internal IPortableStream Stream - { - get { return _stream; } - } - - /// <summary> - /// Gets collected metadatas. - /// </summary> - /// <returns>Collected metadatas (if any).</returns> - internal IDictionary<int, IPortableMetadata> Metadata() - { - return _metas; - } - - /// <summary> - /// Check whether the given object is portable, i.e. it can be - /// serialized with portable marshaller. - /// </summary> - /// <param name="obj">Object.</param> - /// <returns>True if portable.</returns> - internal bool IsPortable(object obj) - { - if (obj != null) - { - Type type = obj.GetType(); - - // We assume object as portable only in case it has descriptor. - // Collections, Enums and non-primitive arrays do not have descriptors - // and this is fine here because we cannot know whether their members - // are portable. - return _marsh.GetDescriptor(type) != null || PortableSystemHandlers.GetWriteHandler(type) != null; - } - - return true; - } - - /// <summary> - /// Write field ID. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="fieldTypeId">Field type ID.</param> - private void WriteFieldId(string fieldName, byte fieldTypeId) - { - if (_curRawPos != 0) - throw new PortableException("Cannot write named fields after raw data is written."); - - var fieldId = _curStruct.GetFieldId(fieldName, fieldTypeId); - - _schema.PushField(fieldId, _stream.Position - _curPos); - } - - /// <summary> - /// Saves metadata for this session. - /// </summary> - /// <param name="typeId">Type ID.</param> - /// <param name="typeName">Type name.</param> - /// <param name="affKeyFieldName">Affinity key field name.</param> - /// <param name="fields">Fields metadata.</param> - internal void SaveMetadata(int typeId, string typeName, string affKeyFieldName, IDictionary<string, int> fields) - { - if (_metas == null) - { - PortableMetadataImpl meta = - new PortableMetadataImpl(typeId, typeName, fields, affKeyFieldName); - - _metas = new Dictionary<int, IPortableMetadata>(1); - - _metas[typeId] = meta; - } - else - { - IPortableMetadata meta; - - if (_metas.TryGetValue(typeId, out meta)) - { - IDictionary<string, int> existingFields = ((PortableMetadataImpl)meta).FieldsMap(); - - foreach (KeyValuePair<string, int> field in fields) - { - if (!existingFields.ContainsKey(field.Key)) - existingFields[field.Key] = field.Value; - } - } - else - _metas[typeId] = new PortableMetadataImpl(typeId, typeName, fields, affKeyFieldName); - } - } - } -}
http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs deleted file mode 100644 index e72ffac..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System; - using System.Collections.Generic; - using System.IO; - using Apache.Ignite.Core.Common; - using Apache.Ignite.Core.Impl.Common; - using Apache.Ignite.Core.Impl.Portable.IO; - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Portables implementation. - /// </summary> - internal class PortablesImpl : IPortables - { - /** Owning grid. */ - private readonly PortableMarshaller _marsh; - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="marsh">Marshaller.</param> - internal PortablesImpl(PortableMarshaller marsh) - { - _marsh = marsh; - } - - /** <inheritDoc /> */ - public T ToPortable<T>(object obj) - { - if (obj is IPortableObject) - return (T)obj; - - IPortableStream stream = new PortableHeapStream(1024); - - // Serialize. - PortableWriterImpl writer = _marsh.StartMarshal(stream); - - try - { - writer.Write(obj); - } - finally - { - // Save metadata. - _marsh.FinishMarshal(writer); - } - - // Deserialize. - stream.Seek(0, SeekOrigin.Begin); - - return _marsh.Unmarshal<T>(stream, PortableMode.ForcePortable); - } - - /** <inheritDoc /> */ - public IPortableBuilder GetBuilder(Type type) - { - IgniteArgumentCheck.NotNull(type, "type"); - - IPortableTypeDescriptor desc = _marsh.GetDescriptor(type); - - if (desc == null) - throw new IgniteException("Type is not portable (add it to PortableConfiguration): " + - type.FullName); - - return Builder0(null, PortableFromDescriptor(desc), desc); - } - - /** <inheritDoc /> */ - public IPortableBuilder GetBuilder(string typeName) - { - IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName"); - - IPortableTypeDescriptor desc = _marsh.GetDescriptor(typeName); - - return Builder0(null, PortableFromDescriptor(desc), desc); - } - - /** <inheritDoc /> */ - public IPortableBuilder GetBuilder(IPortableObject obj) - { - IgniteArgumentCheck.NotNull(obj, "obj"); - - PortableUserObject obj0 = obj as PortableUserObject; - - if (obj0 == null) - throw new ArgumentException("Unsupported object type: " + obj.GetType()); - - IPortableTypeDescriptor desc = _marsh.GetDescriptor(true, obj0.TypeId); - - return Builder0(null, obj0, desc); - } - - /** <inheritDoc /> */ - public int GetTypeId(string typeName) - { - IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName"); - - return Marshaller.GetDescriptor(typeName).TypeId; - } - - /** <inheritDoc /> */ - public ICollection<IPortableMetadata> GetMetadata() - { - return Marshaller.Ignite.ClusterGroup.Metadata(); - } - - /** <inheritDoc /> */ - public IPortableMetadata GetMetadata(int typeId) - { - return Marshaller.GetMetadata(typeId); - } - - /** <inheritDoc /> */ - public IPortableMetadata GetMetadata(string typeName) - { - IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName"); - - return GetMetadata(GetTypeId(typeName)); - } - - /** <inheritDoc /> */ - public IPortableMetadata GetMetadata(Type type) - { - IgniteArgumentCheck.NotNull(type, "type"); - - var desc = Marshaller.GetDescriptor(type); - - return desc == null ? null : Marshaller.GetMetadata(desc.TypeId); - } - - /// <summary> - /// Marshaller. - /// </summary> - internal PortableMarshaller Marshaller - { - get - { - return _marsh; - } - } - - /// <summary> - /// Create empty portable object from descriptor. - /// </summary> - /// <param name="desc">Descriptor.</param> - /// <returns>Empty portable object.</returns> - private PortableUserObject PortableFromDescriptor(IPortableTypeDescriptor desc) - { - var len = PortableObjectHeader.Size; - - var hdr = new PortableObjectHeader(desc.UserType, desc.TypeId, 0, len, 0, len, true, 0); - - var stream = new PortableHeapStream(len); - - PortableObjectHeader.Write(hdr, stream, 0); - - return new PortableUserObject(_marsh, stream.InternalArray, 0, hdr); - } - - /// <summary> - /// Internal builder creation routine. - /// </summary> - /// <param name="parent">Parent builder.</param> - /// <param name="obj">Portable object.</param> - /// <param name="desc">Type descriptor.</param> - /// <returns>Builder.</returns> - private PortableBuilderImpl Builder0(PortableBuilderImpl parent, PortableUserObject obj, - IPortableTypeDescriptor desc) - { - return new PortableBuilderImpl(this, parent, obj, desc); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs deleted file mode 100644 index a33ea24..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System.Diagnostics; - using System.Runtime.Serialization.Formatters.Binary; - using Apache.Ignite.Core.Impl.Portable.IO; - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Wraps Serializable item in a portable. - /// </summary> - internal class SerializableObjectHolder : IPortableWriteAware - { - /** */ - private readonly object _item; - - /// <summary> - /// Initializes a new instance of the <see cref="SerializableObjectHolder"/> class. - /// </summary> - /// <param name="item">The item to wrap.</param> - public SerializableObjectHolder(object item) - { - _item = item; - } - - /// <summary> - /// Gets the item to wrap. - /// </summary> - public object Item - { - get { return _item; } - } - - /** <inheritDoc /> */ - public void WritePortable(IPortableWriter writer) - { - Debug.Assert(writer != null); - - var writer0 = (PortableWriterImpl)writer.GetRawWriter(); - - writer0.WithDetach(w => new BinaryFormatter().Serialize(new PortableStreamAdapter(w.Stream), Item)); - } - - /// <summary> - /// Initializes a new instance of the <see cref="SerializableObjectHolder"/> class. - /// </summary> - /// <param name="reader">The reader.</param> - public SerializableObjectHolder(IPortableReader reader) - { - Debug.Assert(reader != null); - - var reader0 = (PortableReaderImpl) reader.GetRawReader(); - - _item = new BinaryFormatter().Deserialize(new PortableStreamAdapter(reader0.Stream), null); - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs deleted file mode 100644 index 5b97ef7..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable.Structure -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Portable type structure. Cache field IDs and metadata to improve marshalling performance. - /// Every object write contains a set of field writes. Every unique ordered set of written fields - /// produce write "path". We cache these paths allowing for very fast traverse over object structure - /// without expensive map lookups and field ID calculations. - /// </summary> - internal class PortableStructure - { - /// <summary> - /// Create empty type structure. - /// </summary> - /// <returns>Empty type structure.</returns> - public static PortableStructure CreateEmpty() - { - return new PortableStructure(new[] { new PortableStructureEntry[0] }, - new PortableStructureJumpTable[1], new Dictionary<string, byte>()); - } - - /** Entries. */ - private readonly PortableStructureEntry[][] _paths; - - /** Jumps. */ - private readonly PortableStructureJumpTable[] _jumps; - - /** Field types. */ - private readonly IDictionary<string, byte> _fieldTypes; - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="paths">Paths.</param> - /// <param name="jumps">Jumps.</param> - /// <param name="fieldTypes">Field types.</param> - private PortableStructure(PortableStructureEntry[][] paths, - PortableStructureJumpTable[] jumps, IDictionary<string, byte> fieldTypes) - { - _paths = paths; - _jumps = jumps; - _fieldTypes = fieldTypes; - } - - /// <summary> - /// Gets field ID if possible. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="fieldType">Field type.</param> - /// <param name="pathIdx">Path index, changes during jumps.</param> - /// <param name="actionIdx">Action index.</param> - /// <returns>Field ID or zero in case there are no matching path.</returns> - public int GetFieldId(string fieldName, byte fieldType, ref int pathIdx, int actionIdx) - { - Debug.Assert(pathIdx <= _paths.Length); - - // Get path. - PortableStructureEntry[] path = _paths[pathIdx]; - - if (actionIdx < path.Length) - { - // Get entry matching the action index. - PortableStructureEntry entry = path[actionIdx]; - - if (entry.IsExpected(fieldName, fieldType)) - // Entry matches our expectations, return. - return entry.Id; - else if (entry.IsJumpTable) - { - // Entry is a pointer to a jump table. - Debug.Assert(entry.Id < _jumps.Length); - - PortableStructureJumpTable jmpTbl = _jumps[entry.Id]; - - int pathIdx0 = jmpTbl.GetPathIndex(fieldName); - - if (pathIdx0 < 0) - return 0; - - Debug.Assert(pathIdx0 < _paths.Length); - - entry = _paths[pathIdx0][actionIdx]; - - entry.ValidateType(fieldType); - - pathIdx = pathIdx0; - - return entry.Id; - } - } - - // Failed to find anything because this is a new field. - return 0; - } - - /// <summary> - /// Merge updates into a new type structure. - /// </summary> - /// <param name="exp">Expected type structure to apply updates to </param> - /// <param name="pathIdx">Path index.</param> - /// <param name="updates">Updates.</param> - /// <returns>New type structure with updates.</returns> - public PortableStructure Merge(PortableStructure exp, int pathIdx, - IList<PortableStructureUpdate> updates) - { - if (updates.Count == 0) - return this; - - // Algorithm ensures that updates are applied to the same type structure, - // where they were initially observed. This allow us to keep structure - // internals simpler and more efficient. On the other hand, this imposes - // some performance hit because in case of concurrent update, recorded - // changes will be discarded and recorded again during the next write - // on the same path. This should occur only during application warmup. - - // Note that field types are merged anyway to avoid metadata clashes. - PortableStructure res = MergeFieldTypes(updates); - - if (ReferenceEquals(exp, this)) - { - PortableStructureUpdate firstUpdate = updates[0]; - - if (firstUpdate.Index == 0) - { - // Special case: the very first structure update. Simply attach all updates. - Debug.Assert(_paths.Length == 1); - Debug.Assert(_paths[0].Length == 0); - Debug.Assert(pathIdx == 0); - - var newPaths = CopyPaths(updates.Count, 0); - - ApplyUpdatesToPath(newPaths[0], updates); - - res = new PortableStructure(newPaths, _jumps, res._fieldTypes); - } - else - { - // Get entry where updates should start. - PortableStructureEntry[] path = _paths[pathIdx]; - - PortableStructureEntry startEntry = default(PortableStructureEntry); - - if (firstUpdate.Index < path.Length) - startEntry = path[firstUpdate.Index]; - - if (startEntry.IsEmpty) - { - // We are on the empty/non-existent entry. Continue the path without branching. - var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 0); - - ApplyUpdatesToPath(newPaths[pathIdx], updates); - - res = new PortableStructure(newPaths, _jumps, res._fieldTypes); - } - else if (startEntry.IsJumpTable) - { - // We are on the jump table. Add a new path and record it in the jump table. - - // 1. Prepare new structures. - var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 1); - var newJumps = CopyJumps(0); - - // New path will be the last one. - int newPathIdx = newPaths.Length - 1; - - // Apply updates to the new path. - ApplyUpdatesToPath(newPaths[newPathIdx], updates); - - // Add the jump to the table. - newJumps[startEntry.Id] = - newJumps[startEntry.Id].CopyAndAdd(firstUpdate.FieldName, newPathIdx); - - res = new PortableStructure(newPaths, newJumps, res._fieldTypes); - } - else - { - // We are on existing entry. Need to create a new jump table here and two new paths. - - // 1. Prepaare new structures. - var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 2); - var newJumps = CopyJumps(1); - - // Old path will be moved here. - int oldPathIdx = newPaths.Length - 2; - - // New path will reside here. - int newPathIdx = newPaths.Length - 1; - - // Create new jump table. - int newJumpIdx = newJumps.Length - 1; - - newJumps[newJumpIdx] = new PortableStructureJumpTable(startEntry.Name, oldPathIdx, - firstUpdate.FieldName, newPathIdx); - - // Re-create old path in two steps: move old path to the new place, then clean the old path. - for (int i = firstUpdate.Index; i < path.Length; i++) - { - newPaths[oldPathIdx][i] = newPaths[pathIdx][i]; - - if (i == firstUpdate.Index) - // Inject jump table ... - newPaths[pathIdx][i] = new PortableStructureEntry(newJumpIdx); - else - // ... or just reset. - newPaths[pathIdx][i] = new PortableStructureEntry(); - } - - // Apply updates to the new path. - ApplyUpdatesToPath(newPaths[newPaths.Length - 1], updates); - - res = new PortableStructure(newPaths, newJumps, res._fieldTypes); - } - - } - } - - return res; - } - - /// <summary> - /// Copy and possibly expand paths. - /// </summary> - /// <param name="minLen">Minimum length.</param> - /// <param name="additionalPaths">Amount of additional paths required.</param> - /// <returns>Result.</returns> - private PortableStructureEntry[][] CopyPaths(int minLen, int additionalPaths) - { - var newPaths = new PortableStructureEntry[_paths.Length + additionalPaths][]; - - int newPathLen = Math.Max(_paths[0].Length, minLen); - - for (int i = 0; i < newPaths.Length; i++) - { - newPaths[i] = new PortableStructureEntry[newPathLen]; - - if (i < _paths.Length) - Array.Copy(_paths[i], newPaths[i], _paths[i].Length); - } - - return newPaths; - } - - /// <summary> - /// Copy and possibly expand jump tables. - /// </summary> - /// <param name="additionalJumps">Amount of additional jumps required.</param> - /// <returns>Result.</returns> - private PortableStructureJumpTable[] CopyJumps(int additionalJumps) - { - var newJumps = new PortableStructureJumpTable[_jumps.Length + additionalJumps]; - - // The very first jump is always null so that we can distinguish between jump table - // and empty value in PortableStructureEntry. - for (int i = 1; i < _jumps.Length; i++) - newJumps[i] = _jumps[i].Copy(); - - return newJumps; - } - - /// <summary> - /// Apply updates to path. - /// </summary> - /// <param name="path">Path.</param> - /// <param name="updates">Updates.</param> - private static void ApplyUpdatesToPath(IList<PortableStructureEntry> path, - IEnumerable<PortableStructureUpdate> updates) - { - foreach (var u in updates) - path[u.Index] = new PortableStructureEntry(u.FieldName, u.FieldId, u.FieldType); - } - - /// <summary> - /// Merge field types. - /// </summary> - /// <param name="updates">Updates.</param> - /// <returns>Type structure with applied updates.</returns> - private PortableStructure MergeFieldTypes(IList<PortableStructureUpdate> updates) - { - IDictionary<string, byte> newFieldTypes = new Dictionary<string, byte>(_fieldTypes); - - foreach (PortableStructureUpdate update in updates) - { - byte expType; - - if (_fieldTypes.TryGetValue(update.FieldName, out expType)) - { - // This is an old field. - if (expType != update.FieldType) - { - throw new PortableException("Field type mismatch detected [fieldName=" + update.FieldName + - ", expectedType=" + expType + ", actualType=" + update.FieldType + ']'); - } - } - else - // This is a new field. - newFieldTypes[update.FieldName] = update.FieldType; - } - - return newFieldTypes.Count == _fieldTypes.Count ? - this : new PortableStructure(_paths, _jumps, newFieldTypes); - } - - /// <summary> - /// Recorded field types. - /// </summary> - internal IDictionary<string, byte> FieldTypes - { - get { return _fieldTypes; } - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs deleted file mode 100644 index 9b6d282..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable.Structure -{ - using System.Diagnostics; - - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Portable type structure entry. Might be either a normal field, a reference to jump table, or an empty entry. - /// </summary> - internal struct PortableStructureEntry - { - /** Field name. */ - private readonly string _name; - - /** Field ID. */ - private readonly int _id; - - /** Field type. */ - private readonly byte _type; - - /// <summary> - /// Constructor for jump table entry. - /// </summary> - /// <param name="jumpTblIdx">Jump table index.</param> - public PortableStructureEntry(int jumpTblIdx) - { - Debug.Assert(jumpTblIdx > 0); - - _name = null; - _id = jumpTblIdx; - _type = 0; - } - - /// <summary> - /// Constructor for field entry. - /// </summary> - /// <param name="name">Field name.</param> - /// <param name="id">Field ID.</param> - /// <param name="type">Field type.</param> - public PortableStructureEntry(string name, int id, byte type) - { - Debug.Assert(name != null); - - _name = name; - _id = id; - _type = type; - } - - /// <summary> - /// Check whether current field entry matches passed arguments. - /// </summary> - /// <param name="name">Field name.</param> - /// <param name="type">Field type.</param> - /// <returns>True if expected.</returns> - public bool IsExpected(string name, byte type) - { - // Perform reference equality check first because field name is a literal in most cases. - if (!ReferenceEquals(_name, name) && !name.Equals(_name)) - return false; - - ValidateType(type); - - return true; - } - - /// <summary> - /// Validate field type. - /// </summary> - /// <param name="type">Expected type.</param> - public void ValidateType(byte type) - { - if (_type != type) - { - throw new PortableException("Field type mismatch detected [fieldName=" + _name + - ", expectedType=" + _type + ", actualType=" + type + ']'); - } - } - - /// <summary> - /// Whether this is an empty entry. - /// </summary> - /// <returns></returns> - public bool IsEmpty - { - get { return _id == 0; } - } - - /// <summary> - /// Whether this is a jump table. - /// </summary> - public bool IsJumpTable - { - get { return _name == null && _id >= 0; } - } - - /// <summary> - /// Field name. - /// </summary> - public string Name - { - get { return _name; } - } - - /// <summary> - /// Field ID. - /// </summary> - public int Id - { - get { return _id; } - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs deleted file mode 100644 index 7f8b373..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable.Structure -{ - using System; - using System.Diagnostics; - - /// <summary> - /// Jump table. - /// </summary> - internal class PortableStructureJumpTable - { - /** Names. */ - private readonly string[] _names; - - /** Path indexes. */ - private readonly int[] _pathIdxs; - - /// <summary> - /// Create minimal jump table with two entries. - /// </summary> - /// <param name="firstName">First name.</param> - /// <param name="firstPathIdx">First path index.</param> - /// <param name="secondName">Second name.</param> - /// <param name="secondPathIdx">Second path index.</param> - public PortableStructureJumpTable(string firstName, int firstPathIdx, - string secondName, int secondPathIdx) - { - _names = new[] { firstName, secondName }; - _pathIdxs = new[] { firstPathIdx, secondPathIdx }; - } - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="names">Field names.</param> - /// <param name="pathIdxs">Path indexes.</param> - private PortableStructureJumpTable(string[] names, int[] pathIdxs) - { - Debug.Assert(names.Length > 1); - Debug.Assert(names.Length == pathIdxs.Length); - - _names = names; - _pathIdxs = pathIdxs; - } - - /// <summary> - /// Get path index for the given field. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <returns>Path index.</returns> - public int GetPathIndex(string fieldName) - { - Debug.Assert(fieldName != null); - - // Optimistically assume that field name is a literal. - for (var i = 0; i < _names.Length; i++) - { - if (ReferenceEquals(fieldName, _names[i])) - return _pathIdxs[i]; - } - - // Fallback to slow-path with normal string comparison. - for (var i = 0; i < _names.Length; i++) - { - if (fieldName.Equals(_names[i])) - return _pathIdxs[i]; - } - - // No path found for the field. - return -1; - } - - /// <summary> - /// Copy jump table. - /// </summary> - /// <returns>New jump table.</returns> - public PortableStructureJumpTable Copy() - { - return new PortableStructureJumpTable(_names, _pathIdxs); - } - - /// <summary> - /// Copy jump table with additional jump. - /// </summary> - /// <param name="name">Field name.</param> - /// <param name="pathIdx">Path index.</param> - /// <returns>New jump table.</returns> - public PortableStructureJumpTable CopyAndAdd(string name, int pathIdx) - { - var newNames = new string[_names.Length + 1]; - var newPathIdxs = new int[_pathIdxs.Length + 1]; - - Array.Copy(_names, newNames, _names.Length); - Array.Copy(_pathIdxs, newPathIdxs, _pathIdxs.Length); - - newNames[newNames.Length - 1] = name; - newPathIdxs[newPathIdxs.Length - 1] = pathIdx; - - return new PortableStructureJumpTable(newNames, newPathIdxs); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureTracker.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureTracker.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureTracker.cs deleted file mode 100644 index 11ba032..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureTracker.cs +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable.Structure -{ - using System.Collections.Generic; - - /// <summary> - /// Encapsulates logic for tracking field access and updating type descriptor structure. - /// </summary> - internal struct PortableStructureTracker - { - /** Current type structure. */ - private readonly IPortableTypeDescriptor _desc; - - /** Struct. */ - private readonly PortableStructure _portStruct; - - /** Current type structure path index. */ - private int _curStructPath; - - /** Current type structure action index. */ - private int _curStructAction; - - /** Current type structure updates. */ - private List<PortableStructureUpdate> _curStructUpdates; - - /// <summary> - /// Initializes a new instance of the <see cref="PortableStructureTracker" /> class. - /// </summary> - /// <param name="desc">The desc.</param> - /// <param name="portStruct">The structure to work with.</param> - public PortableStructureTracker(IPortableTypeDescriptor desc, PortableStructure portStruct) - { - _desc = desc; - _portStruct = portStruct; - _curStructPath = 0; - _curStructAction = 0; - _curStructUpdates = null; - } - - /// <summary> - /// Gets the current structure action. - /// </summary> - public int CurStructAction - { - get { return _curStructAction; } - } - - /// <summary> - /// Gets the field ID. - /// </summary> - public int GetFieldId(string fieldName, byte fieldTypeId = 0) - { - _curStructAction++; - - if (_curStructUpdates == null) - { - var fieldId = _portStruct.GetFieldId(fieldName, fieldTypeId, ref _curStructPath, - _curStructAction); - - if (fieldId != 0) - return fieldId; - } - - return GetNewFieldId(fieldName, fieldTypeId, _curStructAction); - } - - /// <summary> - /// Updates the type structure. - /// </summary> - public void UpdateReaderStructure() - { - if (_curStructUpdates != null) - _desc.UpdateReadStructure(_desc.ReaderTypeStructure, _curStructPath, _curStructUpdates); - } - - /// <summary> - /// Updates the type structure and metadata for the specified writer. - /// </summary> - /// <param name="writer">The writer.</param> - public void UpdateWriterStructure(PortableWriterImpl writer) - { - if (_curStructUpdates != null) - { - _desc.UpdateWriteStructure(_desc.WriterTypeStructure, _curStructPath, _curStructUpdates); - - var marsh = writer.Marshaller; - - var metaHnd = marsh.GetMetadataHandler(_desc); - - if (metaHnd != null) - { - foreach (var u in _curStructUpdates) - metaHnd.OnFieldWrite(u.FieldId, u.FieldName, u.FieldType); - - var meta = metaHnd.OnObjectWriteFinished(); - - if (meta != null) - writer.SaveMetadata(_desc.TypeId, _desc.TypeName, _desc.AffinityKeyFieldName, meta); - } - } - } - - /// <summary> - /// Get ID for the new field and save structure update. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="fieldTypeId">Field type ID.</param> - /// <param name="action">Action index.</param> - /// <returns> - /// Field ID. - /// </returns> - private int GetNewFieldId(string fieldName, byte fieldTypeId, int action) - { - var fieldId = PortableUtils.FieldId(_desc.TypeId, fieldName, _desc.NameMapper, _desc.IdMapper); - - if (_curStructUpdates == null) - _curStructUpdates = new List<PortableStructureUpdate>(); - - _curStructUpdates.Add(new PortableStructureUpdate(fieldName, fieldId, fieldTypeId, action)); - - return fieldId; - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs deleted file mode 100644 index fa239db..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Apache.Ignite.Core.Impl.Portable.Structure -{ - /// <summary> - /// Portable type structure update descriptor. - /// </summary> - internal class PortableStructureUpdate - { - /** Field name. */ - private readonly string _fieldName; - - /** Field ID. */ - private readonly int _fieldId; - - /** Field type. */ - private readonly byte _fieldType; - - /** Field index. */ - private readonly int _idx; - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="fieldName">Field name.</param> - /// <param name="fieldId">Field ID.</param> - /// <param name="fieldType">Field type.</param> - /// <param name="idx">Index.</param> - public PortableStructureUpdate(string fieldName, int fieldId, byte fieldType, int idx) - { - _fieldName = fieldName; - _fieldId = fieldId; - _fieldType = fieldType; - _idx = idx; - } - - /// <summary> - /// Field name. - /// </summary> - public string FieldName - { - get { return _fieldName; } - } - - /// <summary> - /// Field ID. - /// </summary> - public int FieldId - { - get { return _fieldId; } - } - - /// <summary> - /// Field type. - /// </summary> - public byte FieldType - { - get { return _fieldType; } - } - - /// <summary> - /// Index. - /// </summary> - public int Index - { - get { return _idx; } - } - } -}
