http://git-wip-us.apache.org/repos/asf/ignite/blob/f0bac562/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs deleted file mode 100644 index dc0f570..0000000 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs +++ /dev/null @@ -1,923 +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.Portable.IO; - using Apache.Ignite.Core.Impl.Portable.Metadata; - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Portable builder implementation. - /// </summary> - internal class PortableBuilderImpl : IPortableBuilder - { - /** Type IDs for metadata. */ - private static readonly IDictionary<Type, int> TypeIds; - - /** Cached dictionary with no values. */ - private static readonly IDictionary<int, object> EmptyVals = new Dictionary<int, object>(); - - /** Offset: length. */ - private const int OffsetLen = 10; - - /** Portables. */ - private readonly PortablesImpl _portables; - - /** */ - private readonly PortableBuilderImpl _parent; - - /** Initial portable object. */ - private readonly PortableUserObject _obj; - - /** Type descriptor. */ - private readonly IPortableTypeDescriptor _desc; - - /** Values. */ - private IDictionary<string, PortableBuilderField> _vals; - - /** Contextual fields. */ - private IDictionary<int, object> _cache; - - /** Hash code. */ - private int _hashCode; - - /** Current context. */ - private Context _ctx; - - /// <summary> - /// Static initializer. - /// </summary> - static PortableBuilderImpl() - { - TypeIds = new Dictionary<Type, int>(); - - // 1. Primitives. - TypeIds[typeof(byte)] = PortableUtils.TypeByte; - TypeIds[typeof(bool)] = PortableUtils.TypeBool; - TypeIds[typeof(short)] = PortableUtils.TypeShort; - TypeIds[typeof(char)] = PortableUtils.TypeChar; - TypeIds[typeof(int)] = PortableUtils.TypeInt; - TypeIds[typeof(long)] = PortableUtils.TypeLong; - TypeIds[typeof(float)] = PortableUtils.TypeFloat; - TypeIds[typeof(double)] = PortableUtils.TypeDouble; - TypeIds[typeof(decimal)] = PortableUtils.TypeDecimal; - - TypeIds[typeof(byte[])] = PortableUtils.TypeArrayByte; - TypeIds[typeof(bool[])] = PortableUtils.TypeArrayBool; - TypeIds[typeof(short[])] = PortableUtils.TypeArrayShort; - TypeIds[typeof(char[])] = PortableUtils.TypeArrayChar; - TypeIds[typeof(int[])] = PortableUtils.TypeArrayInt; - TypeIds[typeof(long[])] = PortableUtils.TypeArrayLong; - TypeIds[typeof(float[])] = PortableUtils.TypeArrayFloat; - TypeIds[typeof(double[])] = PortableUtils.TypeArrayDouble; - TypeIds[typeof(decimal[])] = PortableUtils.TypeArrayDecimal; - - // 2. String. - TypeIds[typeof(string)] = PortableUtils.TypeString; - TypeIds[typeof(string[])] = PortableUtils.TypeArrayString; - - // 3. Guid. - TypeIds[typeof(Guid)] = PortableUtils.TypeGuid; - TypeIds[typeof(Guid?)] = PortableUtils.TypeGuid; - TypeIds[typeof(Guid[])] = PortableUtils.TypeArrayGuid; - TypeIds[typeof(Guid?[])] = PortableUtils.TypeArrayGuid; - - // 4. Date. - TypeIds[typeof(DateTime)] = PortableUtils.TypeDate; - TypeIds[typeof(DateTime?)] = PortableUtils.TypeDate; - TypeIds[typeof(DateTime[])] = PortableUtils.TypeArrayDate; - TypeIds[typeof(DateTime?[])] = PortableUtils.TypeArrayDate; - } - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="portables">Portables.</param> - /// <param name="obj">Initial portable object.</param> - /// <param name="desc">Type descriptor.</param> - public PortableBuilderImpl(PortablesImpl portables, PortableUserObject obj, - IPortableTypeDescriptor desc) : this(portables, null, obj, desc) - { - // No-op. - } - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="portables">Portables.</param> - /// <param name="parent">Parent builder.</param> - /// <param name="obj">Initial portable object.</param> - /// <param name="desc">Type descriptor.</param> - public PortableBuilderImpl(PortablesImpl portables, PortableBuilderImpl parent, - PortableUserObject obj, IPortableTypeDescriptor desc) - { - _portables = portables; - _parent = parent ?? this; - _obj = obj; - _desc = desc; - - _hashCode = obj.GetHashCode(); - } - - /** <inheritDoc /> */ - public IPortableBuilder SetHashCode(int hashCode) - { - _hashCode = hashCode; - - return this; - } - - /** <inheritDoc /> */ - public T GetField<T>(string name) - { - PortableBuilderField field; - - if (_vals != null && _vals.TryGetValue(name, out field)) - return field != PortableBuilderField.RmvMarker ? (T)field.Value : default(T); - T val = _obj.Field<T>(name, this); - - if (_vals == null) - _vals = new Dictionary<string, PortableBuilderField>(2); - - _vals[name] = new PortableBuilderField(typeof(T), val); - - return val; - } - - /** <inheritDoc /> */ - public IPortableBuilder SetField<T>(string name, T val) - { - return SetField0(name, new PortableBuilderField(typeof(T), val)); - } - - /** <inheritDoc /> */ - public IPortableBuilder RemoveField(string name) - { - return SetField0(name, PortableBuilderField.RmvMarker); - } - - /** <inheritDoc /> */ - public IPortableObject Build() - { - PortableHeapStream inStream = new PortableHeapStream(_obj.Data); - - inStream.Seek(_obj.Offset, SeekOrigin.Begin); - - // Assume that resulting length will be no less than header + [fields_cnt] * 12; - int len = PortableUtils.FullHdrLen + (_vals == null ? 0 : _vals.Count * 12); - - PortableHeapStream outStream = new PortableHeapStream(len); - - PortableWriterImpl writer = _portables.Marshaller.StartMarshal(outStream); - - writer.Builder(this); - - // All related builders will work in this context with this writer. - _parent._ctx = new Context(writer); - - try - { - // Write. - writer.Write(this, null); - - // Process metadata. - _portables.Marshaller.FinishMarshal(writer); - - // Create portable object once metadata is processed. - return new PortableUserObject(_portables.Marshaller, outStream.InternalArray, 0, - _desc.TypeId, _hashCode); - } - finally - { - // Cleanup. - _parent._ctx.Closed = true; - } - } - - /// <summary> - /// Create child builder. - /// </summary> - /// <param name="obj">Portable object.</param> - /// <returns>Child builder.</returns> - public PortableBuilderImpl Child(PortableUserObject obj) - { - return _portables.ChildBuilder(_parent, obj); - } - - /// <summary> - /// Get cache field. - /// </summary> - /// <param name="pos">Position.</param> - /// <param name="val">Value.</param> - /// <returns><c>true</c> if value is found in cache.</returns> - public bool CachedField<T>(int pos, out T val) - { - if (_parent._cache != null) - { - object res; - - if (_parent._cache.TryGetValue(pos, out res)) - { - val = res != null ? (T)res : default(T); - - return true; - } - } - - val = default(T); - - return false; - } - - /// <summary> - /// Add field to cache test. - /// </summary> - /// <param name="pos">Position.</param> - /// <param name="val">Value.</param> - public void CacheField(int pos, object val) - { - if (_parent._cache == null) - _parent._cache = new Dictionary<int, object>(2); - - _parent._cache[pos] = val; - } - - /// <summary> - /// Internal set field routine. - /// </summary> - /// <param name="fieldName">Name.</param> - /// <param name="val">Value.</param> - /// <returns>This builder.</returns> - private IPortableBuilder SetField0(string fieldName, PortableBuilderField val) - { - if (_vals == null) - _vals = new Dictionary<string, PortableBuilderField>(); - - _vals[fieldName] = val; - - return this; - } - - /// <summary> - /// Mutate portable object. - /// </summary> - /// <param name="inStream">Input stream with initial object.</param> - /// <param name="outStream">Output stream.</param> - /// <param name="desc">Portable type descriptor.</param> - /// <param name="hashCode">Hash code.</param> - /// <param name="vals">Values.</param> - internal void Mutate( - PortableHeapStream inStream, - PortableHeapStream outStream, - IPortableTypeDescriptor desc, - int hashCode, - IDictionary<string, PortableBuilderField> vals) - { - // Set correct builder to writer frame. - PortableBuilderImpl oldBuilder = _parent._ctx.Writer.Builder(_parent); - - int streamPos = inStream.Position; - - try - { - // Prepare fields. - IPortableMetadataHandler metaHnd = _portables.Marshaller.MetadataHandler(desc); - - IDictionary<int, object> vals0; - - if (vals == null || vals.Count == 0) - vals0 = EmptyVals; - else - { - vals0 = new Dictionary<int, object>(vals.Count); - - foreach (KeyValuePair<string, PortableBuilderField> valEntry in vals) - { - int fieldId = PortableUtils.FieldId(desc.TypeId, valEntry.Key, desc.NameConverter, desc.Mapper); - - if (vals0.ContainsKey(fieldId)) - throw new IgniteException("Collision in field ID detected (change field name or " + - "define custom ID mapper) [fieldName=" + valEntry.Key + ", fieldId=" + fieldId + ']'); - - vals0[fieldId] = valEntry.Value.Value; - - // Write metadata if: 1) it is enabled for type; 2) type is not null (i.e. it is neither - // remove marker, nor a field read through "GetField" method. - if (metaHnd != null && valEntry.Value.Type != null) - metaHnd.OnFieldWrite(fieldId, valEntry.Key, TypeId(valEntry.Value.Type)); - } - } - - // Actual processing. - Mutate0(_parent._ctx, inStream, outStream, true, hashCode, vals0); - - // 3. Handle metadata. - if (metaHnd != null) - { - IDictionary<string, int> meta = metaHnd.OnObjectWriteFinished(); - - if (meta != null) - _parent._ctx.Writer.SaveMetadata(desc.TypeId, desc.TypeName, desc.AffinityKeyFieldName, meta); - } - } - finally - { - // Restore builder frame. - _parent._ctx.Writer.Builder(oldBuilder); - - inStream.Seek(streamPos, SeekOrigin.Begin); - } - } - - /// <summary> - /// Internal mutation routine. - /// </summary> - /// <param name="inStream">Input stream.</param> - /// <param name="outStream">Output stream.</param> - /// <param name="ctx">Context.</param> - /// <param name="changeHash">WHether hash should be changed.</param> - /// <param name="hash">New hash.</param> - /// <param name="vals">Values to be replaced.</param> - /// <returns>Mutated object.</returns> - private void Mutate0(Context ctx, PortableHeapStream inStream, IPortableStream outStream, - bool changeHash, int hash, IDictionary<int, object> vals) - { - int inStartPos = inStream.Position; - int outStartPos = outStream.Position; - - byte inHdr = inStream.ReadByte(); - - if (inHdr == PortableUtils.HdrNull) - outStream.WriteByte(PortableUtils.HdrNull); - else if (inHdr == PortableUtils.HdrHnd) - { - int inHnd = inStream.ReadInt(); - - int oldPos = inStartPos - inHnd; - int newPos; - - if (ctx.OldToNew(oldPos, out newPos)) - { - // Handle is still valid. - outStream.WriteByte(PortableUtils.HdrHnd); - outStream.WriteInt(outStartPos - newPos); - } - else - { - // Handle is invalid, write full object. - int inRetPos = inStream.Position; - - inStream.Seek(oldPos, SeekOrigin.Begin); - - Mutate0(ctx, inStream, outStream, false, 0, EmptyVals); - - inStream.Seek(inRetPos, SeekOrigin.Begin); - } - } - else if (inHdr == PortableUtils.HdrFull) - { - byte inUsrFlag = inStream.ReadByte(); - int inTypeId = inStream.ReadInt(); - int inHash = inStream.ReadInt(); - int inLen = inStream.ReadInt(); - int inRawOff = inStream.ReadInt(); - - int hndPos; - - if (ctx.AddOldToNew(inStartPos, outStartPos, out hndPos)) - { - // Object could be cached in parent builder. - object cachedVal; - - if (_parent._cache != null && _parent._cache.TryGetValue(inStartPos, out cachedVal)) { - ctx.Writer.Write(cachedVal, null); - } - else - { - // New object, write in full form. - outStream.WriteByte(PortableUtils.HdrFull); - outStream.WriteByte(inUsrFlag); - outStream.WriteInt(inTypeId); - outStream.WriteInt(changeHash ? hash : inHash); - - // Skip length and raw offset as they are not known at this point. - outStream.Seek(8, SeekOrigin.Current); - - // Write regular fields. - while (inStream.Position < inStartPos + inRawOff) - { - int inFieldId = inStream.ReadInt(); - int inFieldLen = inStream.ReadInt(); - int inFieldDataPos = inStream.Position; - - object fieldVal; - - bool fieldFound = vals.TryGetValue(inFieldId, out fieldVal); - - if (!fieldFound || fieldVal != PortableBuilderField.RmvMarkerObj) - { - outStream.WriteInt(inFieldId); - - int fieldLenPos = outStream.Position; // Here we will write length later. - - outStream.Seek(4, SeekOrigin.Current); - - if (fieldFound) - { - // Replace field with new value. - if (fieldVal != PortableBuilderField.RmvMarkerObj) - ctx.Writer.Write(fieldVal, null); - - vals.Remove(inFieldId); - } - else - { - // If field was requested earlier, then we must write tracked value - if (_parent._cache != null && _parent._cache.TryGetValue(inFieldDataPos, out fieldVal)) - ctx.Writer.Write(fieldVal, null); - else - // Filed is not tracked, re-write as is. - Mutate0(ctx, inStream, outStream, false, 0, EmptyVals); - } - - int fieldEndPos = outStream.Position; - - outStream.Seek(fieldLenPos, SeekOrigin.Begin); - outStream.WriteInt(fieldEndPos - fieldLenPos - 4); - outStream.Seek(fieldEndPos, SeekOrigin.Begin); - } - - // Position intput stream pointer after the field. - inStream.Seek(inFieldDataPos + inFieldLen, SeekOrigin.Begin); - } - - // Write remaining new fields. - foreach (KeyValuePair<int, object> valEntry in vals) - { - if (valEntry.Value != PortableBuilderField.RmvMarkerObj) - { - outStream.WriteInt(valEntry.Key); - - int fieldLenPos = outStream.Position; // Here we will write length later. - - outStream.Seek(4, SeekOrigin.Current); - - ctx.Writer.Write(valEntry.Value, null); - - int fieldEndPos = outStream.Position; - - outStream.Seek(fieldLenPos, SeekOrigin.Begin); - outStream.WriteInt(fieldEndPos - fieldLenPos - 4); - outStream.Seek(fieldEndPos, SeekOrigin.Begin); - } - } - - // Write raw data. - int rawPos = outStream.Position; - - outStream.Write(inStream.InternalArray, inStartPos + inRawOff, inLen - inRawOff); - - // Write length and raw data offset. - int outResPos = outStream.Position; - - outStream.Seek(outStartPos + OffsetLen, SeekOrigin.Begin); - - outStream.WriteInt(outResPos - outStartPos); // Length. - outStream.WriteInt(rawPos - outStartPos); // Raw offset. - - outStream.Seek(outResPos, SeekOrigin.Begin); - } - } - else - { - // Object has already been written, write as handle. - outStream.WriteByte(PortableUtils.HdrHnd); - outStream.WriteInt(outStartPos - hndPos); - } - - // Synchronize input stream position. - inStream.Seek(inStartPos + inLen, SeekOrigin.Begin); - } - else - { - // Try writing as well-known type with fixed size. - outStream.WriteByte(inHdr); - - if (!WriteAsPredefined(inHdr, inStream, outStream, ctx)) - throw new IgniteException("Unexpected header [position=" + (inStream.Position - 1) + - ", header=" + inHdr + ']'); - } - } - - /// <summary> - /// Process portable object inverting handles if needed. - /// </summary> - /// <param name="outStream">Output stream.</param> - /// <param name="port">Portable.</param> - internal void ProcessPortable(IPortableStream outStream, PortableUserObject port) - { - // Special case: writing portable object with correct inversions. - PortableHeapStream inStream = new PortableHeapStream(port.Data); - - inStream.Seek(port.Offset, SeekOrigin.Begin); - - // Use fresh context to ensure correct portable inversion. - Mutate0(new Context(), inStream, outStream, false, 0, EmptyVals); - } - - /// <summary> - /// Process child builder. - /// </summary> - /// <param name="outStream">Output stream.</param> - /// <param name="builder">Builder.</param> - internal void ProcessBuilder(IPortableStream outStream, PortableBuilderImpl builder) - { - PortableHeapStream inStream = new PortableHeapStream(builder._obj.Data); - - inStream.Seek(builder._obj.Offset, SeekOrigin.Begin); - - // Builder parent context might be null only in one case: if we never met this group of - // builders before. In this case we set context to their parent and track it. Context - // cleanup will be performed at the very end of build process. - if (builder._parent._ctx == null || builder._parent._ctx.Closed) - builder._parent._ctx = new Context(_parent._ctx); - - builder.Mutate(inStream, outStream as PortableHeapStream, builder._desc, - builder._hashCode, builder._vals); - } - - /// <summary> - /// Write object as a predefined type if possible. - /// </summary> - /// <param name="hdr">Header.</param> - /// <param name="inStream">Input stream.</param> - /// <param name="outStream">Output stream.</param> - /// <param name="ctx">Context.</param> - /// <returns><c>True</c> if was written.</returns> - private bool WriteAsPredefined(byte hdr, PortableHeapStream inStream, IPortableStream outStream, - Context ctx) - { - switch (hdr) - { - case PortableUtils.TypeByte: - TransferBytes(inStream, outStream, 1); - - break; - - case PortableUtils.TypeShort: - TransferBytes(inStream, outStream, 2); - - break; - - case PortableUtils.TypeInt: - TransferBytes(inStream, outStream, 4); - - break; - - case PortableUtils.TypeLong: - TransferBytes(inStream, outStream, 8); - - break; - - case PortableUtils.TypeFloat: - TransferBytes(inStream, outStream, 4); - - break; - - case PortableUtils.TypeDouble: - TransferBytes(inStream, outStream, 8); - - break; - - case PortableUtils.TypeChar: - TransferBytes(inStream, outStream, 2); - - break; - - case PortableUtils.TypeBool: - TransferBytes(inStream, outStream, 1); - - break; - - case PortableUtils.TypeDecimal: - TransferBytes(inStream, outStream, 4); // Transfer scale - - int magLen = inStream.ReadInt(); // Transfer magnitude length. - - outStream.WriteInt(magLen); - - TransferBytes(inStream, outStream, magLen); // Transfer magnitude. - - break; - - case PortableUtils.TypeString: - PortableUtils.WriteString(PortableUtils.ReadString(inStream), outStream); - - break; - - case PortableUtils.TypeGuid: - TransferBytes(inStream, outStream, 16); - - break; - - case PortableUtils.TypeDate: - TransferBytes(inStream, outStream, 12); - - break; - - case PortableUtils.TypeArrayByte: - TransferArray(inStream, outStream, 1); - - break; - - case PortableUtils.TypeArrayShort: - TransferArray(inStream, outStream, 2); - - break; - - case PortableUtils.TypeArrayInt: - TransferArray(inStream, outStream, 4); - - break; - - case PortableUtils.TypeArrayLong: - TransferArray(inStream, outStream, 8); - - break; - - case PortableUtils.TypeArrayFloat: - TransferArray(inStream, outStream, 4); - - break; - - case PortableUtils.TypeArrayDouble: - TransferArray(inStream, outStream, 8); - - break; - - case PortableUtils.TypeArrayChar: - TransferArray(inStream, outStream, 2); - - break; - - case PortableUtils.TypeArrayBool: - TransferArray(inStream, outStream, 1); - - break; - - case PortableUtils.TypeArrayDecimal: - case PortableUtils.TypeArrayString: - case PortableUtils.TypeArrayGuid: - case PortableUtils.TypeArrayDate: - case PortableUtils.TypeArrayEnum: - case PortableUtils.TypeArray: - int arrLen = inStream.ReadInt(); - - outStream.WriteInt(arrLen); - - for (int i = 0; i < arrLen; i++) - Mutate0(ctx, inStream, outStream, false, 0, null); - - break; - - case PortableUtils.TypeCollection: - int colLen = inStream.ReadInt(); - - outStream.WriteInt(colLen); - - outStream.WriteByte(inStream.ReadByte()); - - for (int i = 0; i < colLen; i++) - Mutate0(ctx, inStream, outStream, false, 0, EmptyVals); - - break; - - case PortableUtils.TypeDictionary: - int dictLen = inStream.ReadInt(); - - outStream.WriteInt(dictLen); - - outStream.WriteByte(inStream.ReadByte()); - - for (int i = 0; i < dictLen; i++) - { - Mutate0(ctx, inStream, outStream, false, 0, EmptyVals); - Mutate0(ctx, inStream, outStream, false, 0, EmptyVals); - } - - break; - - case PortableUtils.TypeMapEntry: - Mutate0(ctx, inStream, outStream, false, 0, EmptyVals); - Mutate0(ctx, inStream, outStream, false, 0, EmptyVals); - - break; - - case PortableUtils.TypePortable: - TransferArray(inStream, outStream, 1); // Data array. - TransferBytes(inStream, outStream, 4); // Offset in array. - - break; - - case PortableUtils.TypeEnum: - TransferBytes(inStream, outStream, 4); // Integer ordinal. - - break; - - default: - return false; - } - - return true; - } - - /// <summary> - /// Get's metadata field type ID for the given type. - /// </summary> - /// <param name="type">Type.</param> - /// <returns>Type ID.</returns> - private static int TypeId(Type type) - { - int typeId; - - if (TypeIds.TryGetValue(type, out typeId)) - return typeId; - if (type.IsEnum) - return PortableUtils.TypeEnum; - if (type.IsArray) - return type.GetElementType().IsEnum ? PortableUtils.TypeArrayEnum : PortableUtils.TypeArray; - PortableCollectionInfo colInfo = PortableCollectionInfo.Info(type); - - return colInfo.IsAny ? colInfo.IsCollection || colInfo.IsGenericCollection ? - PortableUtils.TypeCollection : PortableUtils.TypeDictionary : PortableUtils.TypeObject; - } - - /// <summary> - /// Transfer bytes from one stream to another. - /// </summary> - /// <param name="inStream">Input stream.</param> - /// <param name="outStream">Output stream.</param> - /// <param name="cnt">Bytes count.</param> - private static void TransferBytes(PortableHeapStream inStream, IPortableStream outStream, int cnt) - { - outStream.Write(inStream.InternalArray, inStream.Position, cnt); - - inStream.Seek(cnt, SeekOrigin.Current); - } - - /// <summary> - /// Transfer array of fixed-size elements from one stream to another. - /// </summary> - /// <param name="inStream">Input stream.</param> - /// <param name="outStream">Output stream.</param> - /// <param name="elemSize">Element size.</param> - private static void TransferArray(PortableHeapStream inStream, IPortableStream outStream, - int elemSize) - { - int len = inStream.ReadInt(); - - outStream.WriteInt(len); - - TransferBytes(inStream, outStream, elemSize * len); - } - - /// <summary> - /// Mutation ocntext. - /// </summary> - private class Context - { - /** Map from object position in old portable to position in new portable. */ - private IDictionary<int, int> _oldToNew; - - /** Parent context. */ - private readonly Context _parent; - - /** Portable writer. */ - private readonly PortableWriterImpl _writer; - - /** Children contexts. */ - private ICollection<Context> _children; - - /** Closed flag; if context is closed, it can no longer be used. */ - private bool _closed; - - /// <summary> - /// Constructor for parent context where writer invocation is not expected. - /// </summary> - public Context() - { - // No-op. - } - - /// <summary> - /// Constructor for parent context. - /// </summary> - /// <param name="writer">Writer</param> - public Context(PortableWriterImpl writer) - { - _writer = writer; - } - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="parent">Parent context.</param> - public Context(Context parent) - { - _parent = parent; - - _writer = parent._writer; - - if (parent._children == null) - parent._children = new List<Context>(); - - parent._children.Add(this); - } - - /// <summary> - /// Add another old-to-new position mapping. - /// </summary> - /// <param name="oldPos">Old position.</param> - /// <param name="newPos">New position.</param> - /// <param name="hndPos">Handle position.</param> - /// <returns><c>True</c> if ampping was added, <c>false</c> if mapping already existed and handle - /// position in the new object is returned.</returns> - public bool AddOldToNew(int oldPos, int newPos, out int hndPos) - { - if (_oldToNew == null) - _oldToNew = new Dictionary<int, int>(); - - if (_oldToNew.TryGetValue(oldPos, out hndPos)) - return false; - _oldToNew[oldPos] = newPos; - - return true; - } - - /// <summary> - /// Get mapping of old position to the new one. - /// </summary> - /// <param name="oldPos">Old position.</param> - /// <param name="newPos">New position.</param> - /// <returns><c>True</c> if mapping exists.</returns> - public bool OldToNew(int oldPos, out int newPos) - { - return _oldToNew.TryGetValue(oldPos, out newPos); - } - - /// <summary> - /// Writer. - /// </summary> - public PortableWriterImpl Writer - { - get { return _writer; } - } - - /// <summary> - /// Closed flag. - /// </summary> - public bool Closed - { - get - { - return _closed; - } - set - { - Context ctx = this; - - while (ctx != null) - { - ctx._closed = value; - - if (_children != null) { - foreach (Context child in _children) - child.Closed = value; - } - - ctx = ctx._parent; - } - } - } - } - } -}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f0bac562/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs deleted file mode 100644 index fc61833..0000000 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs +++ /dev/null @@ -1,251 +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.Concurrent; - using System.Collections.Generic; - using System.Diagnostics; - using System.Reflection; - using Apache.Ignite.Core.Impl.Common; - - /** - * <summary>Collection info helper.</summary> - */ - internal class PortableCollectionInfo - { - /** Flag: none. */ - private const byte FlagNone = 0; - - /** Flag: generic dictionary. */ - private const byte FlagGenericDictionary = 1; - - /** Flag: generic collection. */ - private const byte FlagGenericCollection = 2; - - /** Flag: dictionary. */ - private const byte FlagDictionary = 3; - - /** Flag: collection. */ - private const byte FlagCollection = 4; - - /** Cache "none" value. */ - private static readonly PortableCollectionInfo None = - new PortableCollectionInfo(FlagNone, null, null, null); - - /** Cache "dictionary" value. */ - private static readonly PortableCollectionInfo Dictionary = - new PortableCollectionInfo(FlagDictionary, PortableSystemHandlers.WriteHndDictionary, null, null); - - /** Cache "collection" value. */ - private static readonly PortableCollectionInfo Collection = - new PortableCollectionInfo(FlagCollection, PortableSystemHandlers.WriteHndCollection, null, null); - - /** Cached infos. */ - private static readonly IDictionary<Type, PortableCollectionInfo> Infos = - new ConcurrentDictionary<Type, PortableCollectionInfo>(64, 32); - - /** - * <summary>Get collection info for type.</summary> - * <param name="type">Type.</param> - * <returns>Collection info.</returns> - */ - public static PortableCollectionInfo Info(Type type) - { - PortableCollectionInfo info; - - if (!Infos.TryGetValue(type, out info)) - { - info = Info0(type); - - Infos[type] = info; - } - - return info; - } - - /** - * <summary>Internal routine to get collection info for type.</summary> - * <param name="type">Type.</param> - * <returns>Collection info.</returns> - */ - private static PortableCollectionInfo Info0(Type type) - { - if (type.IsGenericType) - { - if (type.GetGenericTypeDefinition() == PortableUtils.TypGenericDictionary) - { - MethodInfo writeMthd = - PortableUtils.MtdhWriteGenericDictionary.MakeGenericMethod(type.GetGenericArguments()); - MethodInfo readMthd = - PortableUtils.MtdhReadGenericDictionary.MakeGenericMethod(type.GetGenericArguments()); - - return new PortableCollectionInfo(FlagGenericDictionary, - PortableSystemHandlers.WriteHndGenericDictionary, writeMthd, readMthd); - } - - Type genTyp = type.GetInterface(PortableUtils.TypGenericDictionary.FullName); - - if (genTyp != null) - { - MethodInfo writeMthd = - PortableUtils.MtdhWriteGenericDictionary.MakeGenericMethod(genTyp.GetGenericArguments()); - MethodInfo readMthd = - PortableUtils.MtdhReadGenericDictionary.MakeGenericMethod(genTyp.GetGenericArguments()); - - return new PortableCollectionInfo(FlagGenericDictionary, - PortableSystemHandlers.WriteHndGenericDictionary, writeMthd, readMthd); - } - - if (type.GetGenericTypeDefinition() == PortableUtils.TypGenericCollection) - { - MethodInfo writeMthd = - PortableUtils.MtdhWriteGenericCollection.MakeGenericMethod(type.GetGenericArguments()); - MethodInfo readMthd = - PortableUtils.MtdhReadGenericCollection.MakeGenericMethod(type.GetGenericArguments()); - - return new PortableCollectionInfo(FlagGenericCollection, - PortableSystemHandlers.WriteHndGenericCollection, writeMthd, readMthd); - } - - genTyp = type.GetInterface(PortableUtils.TypGenericCollection.FullName); - - if (genTyp != null) - { - MethodInfo writeMthd = - PortableUtils.MtdhWriteGenericCollection.MakeGenericMethod(genTyp.GetGenericArguments()); - MethodInfo readMthd = - PortableUtils.MtdhReadGenericCollection.MakeGenericMethod(genTyp.GetGenericArguments()); - - return new PortableCollectionInfo(FlagGenericCollection, - PortableSystemHandlers.WriteHndGenericCollection, writeMthd, readMthd); - } - } - - if (type == PortableUtils.TypDictionary || type.GetInterface(PortableUtils.TypDictionary.FullName) != null) - return Dictionary; - if (type == PortableUtils.TypCollection || type.GetInterface(PortableUtils.TypCollection.FullName) != null) - return Collection; - return None; - } - - /** Flag. */ - private readonly byte _flag; - - /** Write handler. */ - private readonly PortableSystemWriteDelegate _writeHnd; - - /** Generic write func. */ - private readonly Action<object, PortableWriterImpl> _writeFunc; - - /** Generic read func. */ - private readonly Func<PortableReaderImpl, object, object> _readFunc; - - /** - * <summary>Constructor.</summary> - * <param name="flag0">Flag.</param> - * <param name="writeHnd0">Write handler.</param> - * <param name="writeMthd0">Generic write method.</param> - * <param name="readMthd0">Generic read method.</param> - */ - private PortableCollectionInfo(byte flag0, PortableSystemWriteDelegate writeHnd0, - MethodInfo writeMthd0, MethodInfo readMthd0) - { - _flag = flag0; - _writeHnd = writeHnd0; - - if (writeMthd0 != null) - _writeFunc = DelegateConverter.CompileFunc<Action<object, PortableWriterImpl>>(null, writeMthd0, null, - new[] {true, false, false}); - - if (readMthd0 != null) - _readFunc = DelegateConverter.CompileFunc<Func<PortableReaderImpl, object, object>>(null, readMthd0, - null, new[] {false, true, false}); - } - - /** - * <summary>Generic dictionary flag.</summary> - */ - public bool IsGenericDictionary - { - get { return _flag == FlagGenericDictionary; } - } - - /** - * <summary>Generic collection flag.</summary> - */ - public bool IsGenericCollection - { - get { return _flag == FlagGenericCollection; } - } - - /** - * <summary>Dictionary flag.</summary> - */ - public bool IsDictionary - { - get { return _flag == FlagDictionary; } - } - - /** - * <summary>Collection flag.</summary> - */ - public bool IsCollection - { - get { return _flag == FlagCollection; } - } - - /** - * <summary>Whether at least one flag is set..</summary> - */ - public bool IsAny - { - get { return _flag != FlagNone; } - } - - /** - * <summary>Write handler.</summary> - */ - public PortableSystemWriteDelegate WriteHandler - { - get { return _writeHnd; } - } - - /// <summary> - /// Reads the generic collection. - /// </summary> - public object ReadGeneric(PortableReaderImpl reader) - { - Debug.Assert(reader != null); - Debug.Assert(_readFunc != null); - - return _readFunc(reader, null); - } - - /// <summary> - /// Writes the generic collection. - /// </summary> - public void WriteGeneric(PortableWriterImpl writer, object value) - { - Debug.Assert(writer != null); - Debug.Assert(_writeFunc != null); - - _writeFunc(value, writer); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/f0bac562/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs deleted file mode 100644 index f294cbd..0000000 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs +++ /dev/null @@ -1,203 +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 Apache.Ignite.Core.Portable; - - /// <summary> - /// Full type descriptor. - /// </summary> - internal class PortableFullTypeDescriptor : IPortableTypeDescriptor - { - /** Type. */ - private readonly Type _type; - - /** Type ID. */ - private readonly int _typeId; - - /** Type name. */ - private readonly string _typeName; - - /** User type flag. */ - private readonly bool _userType; - - /** Name converter. */ - private readonly IPortableNameMapper _nameConverter; - - /** Mapper. */ - private readonly IPortableIdMapper _mapper; - - /** Serializer. */ - private readonly IPortableSerializer _serializer; - - /** Metadata enabled flag. */ - private readonly bool _metaEnabled; - - /** Whether to cache deserialized value in IPortableObject */ - private readonly bool _keepDeserialized; - - /** Affinity field key name. */ - private readonly string _affKeyFieldName; - - /** Typed handler. */ - private readonly object _typedHandler; - - /** Untyped handler. */ - private readonly PortableSystemWriteDelegate _untypedHandler; - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="type">Type.</param> - /// <param name="typeId">Type ID.</param> - /// <param name="typeName">Type name.</param> - /// <param name="userType">User type flag.</param> - /// <param name="nameConverter">Name converter.</param> - /// <param name="mapper">Mapper.</param> - /// <param name="serializer">Serializer.</param> - /// <param name="metaEnabled">Metadata enabled flag.</param> - /// <param name="keepDeserialized">Whether to cache deserialized value in IPortableObject</param> - /// <param name="affKeyFieldName">Affinity field key name.</param> - /// <param name="typedHandler">Typed handler.</param> - /// <param name="untypedHandler">Untyped handler.</param> - public PortableFullTypeDescriptor( - Type type, - int typeId, - string typeName, - bool userType, - IPortableNameMapper nameConverter, - IPortableIdMapper mapper, - IPortableSerializer serializer, - bool metaEnabled, - bool keepDeserialized, - string affKeyFieldName, - object typedHandler, - PortableSystemWriteDelegate untypedHandler) - { - _type = type; - _typeId = typeId; - _typeName = typeName; - _userType = userType; - _nameConverter = nameConverter; - _mapper = mapper; - _serializer = serializer; - _metaEnabled = metaEnabled; - _keepDeserialized = keepDeserialized; - _affKeyFieldName = affKeyFieldName; - _typedHandler = typedHandler; - _untypedHandler = untypedHandler; - } - - /// <summary> - /// Type. - /// </summary> - public Type Type - { - get { return _type; } - } - - /// <summary> - /// Type ID. - /// </summary> - public int TypeId - { - get { return _typeId; } - } - - /// <summary> - /// Type name. - /// </summary> - public string TypeName - { - get { return _typeName; } - } - - /// <summary> - /// User type flag. - /// </summary> - public bool UserType - { - get { return _userType; } - } - - /// <summary> - /// Metadata enabled flag. - /// </summary> - public bool MetadataEnabled - { - get { return _metaEnabled; } - } - - /// <summary> - /// Whether to cache deserialized value in IPortableObject - /// </summary> - public bool KeepDeserialized - { - get { return _keepDeserialized; } - } - - /// <summary> - /// Name converter. - /// </summary> - public IPortableNameMapper NameConverter - { - get { return _nameConverter; } - } - - /// <summary> - /// Mapper. - /// </summary> - public IPortableIdMapper Mapper - { - get { return _mapper; } - } - - /// <summary> - /// Serializer. - /// </summary> - public IPortableSerializer Serializer - { - get { return _serializer; } - } - - /// <summary> - /// Affinity key field name. - /// </summary> - public string AffinityKeyFieldName - { - get { return _affKeyFieldName; } - } - - /// <summary> - /// Typed handler. - /// </summary> - public object TypedHandler - { - get { return _typedHandler; } - } - - /// <summary> - /// Untyped handler. - /// </summary> - public PortableSystemWriteDelegate UntypedHandler - { - get { return _untypedHandler; } - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/f0bac562/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableHandleDictionary.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableHandleDictionary.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableHandleDictionary.cs deleted file mode 100644 index 32e1e02..0000000 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableHandleDictionary.cs +++ /dev/null @@ -1,187 +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.Collections.Generic; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - - /// <summary> - /// Object handle dictionary. - /// </summary> - internal class PortableHandleDictionary<TK, TV> - { - /** Initial array sizes. */ - private const int InitialSize = 7; - - /** Dictionary. */ - private Dictionary<TK, TV> _dict; - - /** First key. */ - private readonly TK _key1; - - /** First value. */ - private readonly TV _val1; - - /** Second key. */ - private TK _key2; - - /** Second value. */ - private TV _val2; - - /** Third key. */ - private TK _key3; - - /** Third value. */ - private TV _val3; - - /// <summary> - /// Constructor with initial key-value pair. - /// </summary> - /// <param name="key">Key.</param> - /// <param name="val">Value.</param> - [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors"), - SuppressMessage("ReSharper", "DoNotCallOverridableMethodsInConstructor")] - public PortableHandleDictionary(TK key, TV val) - { - Debug.Assert(!Equals(key, EmptyKey)); - - _key1 = key; - _val1 = val; - - _key2 = EmptyKey; - _key3 = EmptyKey; - } - - /// <summary> - /// Add value to dictionary. - /// </summary> - /// <param name="key">Key.</param> - /// <param name="val">Value.</param> - public void Add(TK key, TV val) - { - Debug.Assert(!Equals(key, EmptyKey)); - - if (Equals(_key2, EmptyKey)) - { - _key2 = key; - _val2 = val; - - return; - } - - if (Equals(_key3, EmptyKey)) - { - _key3 = key; - _val3 = val; - - return; - } - - if (_dict == null) - _dict = new Dictionary<TK, TV>(InitialSize); - - _dict[key] = val; - } - - /// <summary> - /// Try getting value for the given key. - /// </summary> - /// <param name="key">Key.</param> - /// <param name="val">Value.</param> - /// <returns>True if key was found.</returns> - public bool TryGetValue(TK key, out TV val) - { - Debug.Assert(!Equals(key, EmptyKey)); - - if (Equals(key, _key1)) - { - val = _val1; - - return true; - } - - if (Equals(key, _key2)) - { - val = _val2; - - return true; - } - - if (Equals(key, _key3)) - { - val = _val3; - - return true; - } - - if (_dict == null) - { - val = default(TV); - - return false; - } - - return _dict.TryGetValue(key, out val); - } - - /// <summary> - /// Merge data from another dictionary without overwrite. - /// </summary> - /// <param name="that">Other dictionary.</param> - public void Merge(PortableHandleDictionary<TK, TV> that) - { - Debug.Assert(that != null, "that == null"); - - AddIfAbsent(that._key1, that._val1); - AddIfAbsent(that._key2, that._val2); - AddIfAbsent(that._key3, that._val3); - - if (that._dict == null) - return; - - foreach (var pair in that._dict) - AddIfAbsent(pair.Key, pair.Value); - } - - /// <summary> - /// Add key/value pair to the bucket if absent. - /// </summary> - /// <param name="key">Key.</param> - /// <param name="val">Value.</param> - private void AddIfAbsent(TK key, TV val) - { - if (Equals(key, EmptyKey)) - return; - - if (Equals(key, _key1) || Equals(key, _key2) || Equals(key, _key3)) - return; - - if (_dict == null || !_dict.ContainsKey(key)) - Add(key, val); - } - - /// <summary> - /// Gets the empty key. - /// </summary> - protected virtual TK EmptyKey - { - get { return default(TK); } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/f0bac562/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshalAwareSerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshalAwareSerializer.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshalAwareSerializer.cs deleted file mode 100644 index e3c7523..0000000 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshalAwareSerializer.cs +++ /dev/null @@ -1,45 +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 Apache.Ignite.Core.Portable; - - /// <summary> - /// Portable serializer which only supports <see cref="IPortableMarshalAware"/> types with a default ctor. - /// Does not use reflection. - /// </summary> - internal class PortableMarshalAwareSerializer : IPortableSerializer - { - /// <summary> - /// Default instance. - /// </summary> - public static readonly PortableMarshalAwareSerializer Instance = new PortableMarshalAwareSerializer(); - - /** <inheritdoc /> */ - public void WritePortable(object obj, IPortableWriter writer) - { - ((IPortableMarshalAware)obj).WritePortable(writer); - } - - /** <inheritdoc /> */ - public void ReadPortable(object obj, IPortableReader reader) - { - ((IPortableMarshalAware)obj).ReadPortable(reader); - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/f0bac562/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs deleted file mode 100644 index 6286ebb..0000000 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs +++ /dev/null @@ -1,599 +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.Linq; - using Apache.Ignite.Core.Impl.Cache; - using Apache.Ignite.Core.Impl.Cache.Query.Continuous; - using Apache.Ignite.Core.Impl.Common; - using Apache.Ignite.Core.Impl.Compute; - using Apache.Ignite.Core.Impl.Compute.Closure; - using Apache.Ignite.Core.Impl.Datastream; - using Apache.Ignite.Core.Impl.Messaging; - using Apache.Ignite.Core.Impl.Portable.IO; - using Apache.Ignite.Core.Impl.Portable.Metadata; - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Portable marshaller implementation. - /// </summary> - internal class PortableMarshaller - { - /** Portable configuration. */ - private readonly PortableConfiguration _cfg; - - /** Type to descriptor map. */ - private readonly IDictionary<Type, IPortableTypeDescriptor> _typeToDesc = - new Dictionary<Type, IPortableTypeDescriptor>(); - - /** Type name to descriptor map. */ - private readonly IDictionary<string, IPortableTypeDescriptor> _typeNameToDesc = - new Dictionary<string, IPortableTypeDescriptor>(); - - /** ID to descriptor map. */ - private readonly IDictionary<long, IPortableTypeDescriptor> _idToDesc = - new Dictionary<long, IPortableTypeDescriptor>(); - - /** Cached metadatas. */ - private volatile IDictionary<int, PortableMetadataHolder> _metas = - new Dictionary<int, PortableMetadataHolder>(); - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="cfg">Configurtaion.</param> - public PortableMarshaller(PortableConfiguration cfg) - { - // Validation. - if (cfg == null) - cfg = new PortableConfiguration(); - - if (cfg.TypeConfigurations == null) - cfg.TypeConfigurations = new List<PortableTypeConfiguration>(); - - foreach (PortableTypeConfiguration typeCfg in cfg.TypeConfigurations) - { - if (string.IsNullOrEmpty(typeCfg.TypeName)) - throw new PortableException("Type name cannot be null or empty: " + typeCfg); - - if (typeCfg.AssemblyName != null && typeCfg.AssemblyName.Length == 0) - throw new PortableException("Assembly name cannot be empty string: " + typeCfg); - } - - // Define predefined types. - AddPredefinedType(typeof(bool), PortableUtils.TypeBool, PortableSystemHandlers.WriteHndBoolTyped, PortableSystemHandlers.WriteHndBool); - AddPredefinedType(typeof(byte), PortableUtils.TypeByte, PortableSystemHandlers.WriteHndByteTyped, PortableSystemHandlers.WriteHndByte); - AddPredefinedType(typeof(short), PortableUtils.TypeShort, PortableSystemHandlers.WriteHndShortTyped, PortableSystemHandlers.WriteHndShort); - AddPredefinedType(typeof(char), PortableUtils.TypeChar, PortableSystemHandlers.WriteHndCharTyped, PortableSystemHandlers.WriteHndChar); - AddPredefinedType(typeof(int), PortableUtils.TypeInt, PortableSystemHandlers.WriteHndIntTyped, PortableSystemHandlers.WriteHndInt); - AddPredefinedType(typeof(long), PortableUtils.TypeLong, PortableSystemHandlers.WriteHndLongTyped, PortableSystemHandlers.WriteHndLong); - AddPredefinedType(typeof(float), PortableUtils.TypeFloat, PortableSystemHandlers.WriteHndFloatTyped, PortableSystemHandlers.WriteHndFloat); - AddPredefinedType(typeof(double), PortableUtils.TypeDouble, PortableSystemHandlers.WriteHndDoubleTyped, PortableSystemHandlers.WriteHndDouble); - AddPredefinedType(typeof(string), PortableUtils.TypeString, PortableSystemHandlers.WriteHndStringTyped, PortableSystemHandlers.WriteHndString); - AddPredefinedType(typeof(decimal), PortableUtils.TypeDecimal, PortableSystemHandlers.WriteHndDecimalTyped, PortableSystemHandlers.WriteHndDecimal); - AddPredefinedType(typeof(DateTime), PortableUtils.TypeDate, PortableSystemHandlers.WriteHndDateTyped, PortableSystemHandlers.WriteHndDate); - AddPredefinedType(typeof(Guid), PortableUtils.TypeGuid, PortableSystemHandlers.WriteHndGuidTyped, PortableSystemHandlers.WriteHndGuid); - - // TODO: Remove this registration - AddPredefinedType(typeof(PortableUserObject), PortableUtils.TypePortable, PortableSystemHandlers.WriteHndPortableTyped, - PortableSystemHandlers.WriteHndPortable); - - AddPredefinedType(typeof(bool[]), PortableUtils.TypeArrayBool, PortableSystemHandlers.WriteHndBoolArrayTyped, - PortableSystemHandlers.WriteHndBoolArray); - AddPredefinedType(typeof(byte[]), PortableUtils.TypeArrayByte, PortableSystemHandlers.WriteHndByteArrayTyped, - PortableSystemHandlers.WriteHndByteArray); - AddPredefinedType(typeof(short[]), PortableUtils.TypeArrayShort, PortableSystemHandlers.WriteHndShortArrayTyped, - PortableSystemHandlers.WriteHndShortArray); - AddPredefinedType(typeof(char[]), PortableUtils.TypeArrayChar, PortableSystemHandlers.WriteHndCharArrayTyped, - PortableSystemHandlers.WriteHndCharArray); - AddPredefinedType(typeof(int[]), PortableUtils.TypeArrayInt, PortableSystemHandlers.WriteHndIntArrayTyped, - PortableSystemHandlers.WriteHndIntArray); - AddPredefinedType(typeof(long[]), PortableUtils.TypeArrayLong, PortableSystemHandlers.WriteHndLongArrayTyped, - PortableSystemHandlers.WriteHndLongArray); - AddPredefinedType(typeof(float[]), PortableUtils.TypeArrayFloat, PortableSystemHandlers.WriteHndFloatArrayTyped, - PortableSystemHandlers.WriteHndFloatArray); - AddPredefinedType(typeof(double[]), PortableUtils.TypeArrayDouble, PortableSystemHandlers.WriteHndDoubleArrayTyped, - PortableSystemHandlers.WriteHndDoubleArray); - AddPredefinedType(typeof(decimal[]), PortableUtils.TypeArrayDecimal, PortableSystemHandlers.WriteHndDecimalArrayTyped, - PortableSystemHandlers.WriteHndDecimalArray); - AddPredefinedType(typeof(string[]), PortableUtils.TypeArrayString, PortableSystemHandlers.WriteHndStringArrayTyped, - PortableSystemHandlers.WriteHndStringArray); - AddPredefinedType(typeof(DateTime?[]), PortableUtils.TypeArrayDate, PortableSystemHandlers.WriteHndDateArrayTyped, - PortableSystemHandlers.WriteHndDateArray); - AddPredefinedType(typeof(Guid?[]), PortableUtils.TypeArrayGuid, PortableSystemHandlers.WriteHndGuidArrayTyped, - PortableSystemHandlers.WriteHndGuidArray); - - // Define system types. They use internal reflective stuff, so configuration doesn't affect them. - AddSystemTypes(); - - // 2. Define user types. - var dfltSerializer = cfg.DefaultSerializer == null ? new PortableReflectiveSerializer() : null; - - var typeResolver = new TypeResolver(); - - ICollection<PortableTypeConfiguration> typeCfgs = cfg.TypeConfigurations; - - if (typeCfgs != null) - foreach (PortableTypeConfiguration typeCfg in typeCfgs) - AddUserType(cfg, typeCfg, typeResolver, dfltSerializer); - - ICollection<string> types = cfg.Types; - - if (types != null) - foreach (string type in types) - AddUserType(cfg, new PortableTypeConfiguration(type), typeResolver, dfltSerializer); - - if (cfg.DefaultSerializer == null) - cfg.DefaultSerializer = dfltSerializer; - - _cfg = cfg; - } - - /// <summary> - /// Gets or sets the backing grid. - /// </summary> - public Ignite Ignite { get; set; } - - /// <summary> - /// Marshal object. - /// </summary> - /// <param name="val">Value.</param> - /// <returns>Serialized data as byte array.</returns> - public byte[] Marshal(object val) - { - PortableHeapStream stream = new PortableHeapStream(128); - - Marshal(val, stream); - - return stream.ArrayCopy(); - } - - /// <summary> - /// Marshal object. - /// </summary> - /// <param name="val">Value.</param> - /// <param name="stream">Output stream.</param> - /// <returns>Collection of metadatas (if any).</returns> - private void Marshal<T>(T val, IPortableStream stream) - { - PortableWriterImpl writer = StartMarshal(stream); - - writer.Write(val); - - FinishMarshal(writer); - } - - /// <summary> - /// Start marshal session. - /// </summary> - /// <param name="stream">Stream.</param> - /// <returns>Writer.</returns> - public PortableWriterImpl StartMarshal(IPortableStream stream) - { - return new PortableWriterImpl(this, stream); - } - - /// <summary> - /// Finish marshal session. - /// </summary> - /// <param name="writer">Writer.</param> - /// <returns>Dictionary with metadata.</returns> - public void FinishMarshal(IPortableWriter writer) - { - var meta = ((PortableWriterImpl) writer).Metadata(); - - var ignite = Ignite; - - if (ignite != null && meta != null && meta.Count > 0) - ignite.PutMetadata(meta); - } - - /// <summary> - /// Unmarshal object. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="data">Data array.</param> - /// <param name="keepPortable">Whether to keep portables as portables.</param> - /// <returns> - /// Object. - /// </returns> - public T Unmarshal<T>(byte[] data, bool keepPortable) - { - return Unmarshal<T>(new PortableHeapStream(data), keepPortable); - } - - /// <summary> - /// Unmarshal object. - /// </summary> - /// <param name="data">Data array.</param> - /// <param name="mode">The mode.</param> - /// <returns> - /// Object. - /// </returns> - public T Unmarshal<T>(byte[] data, PortableMode mode = PortableMode.Deserialize) - { - return Unmarshal<T>(new PortableHeapStream(data), mode); - } - - /// <summary> - /// Unmarshal object. - /// </summary> - /// <param name="stream">Stream over underlying byte array with correct position.</param> - /// <param name="keepPortable">Whether to keep portables as portables.</param> - /// <returns> - /// Object. - /// </returns> - public T Unmarshal<T>(IPortableStream stream, bool keepPortable) - { - return Unmarshal<T>(stream, keepPortable ? PortableMode.KeepPortable : PortableMode.Deserialize, null); - } - - /// <summary> - /// Unmarshal object. - /// </summary> - /// <param name="stream">Stream over underlying byte array with correct position.</param> - /// <param name="mode">The mode.</param> - /// <returns> - /// Object. - /// </returns> - public T Unmarshal<T>(IPortableStream stream, PortableMode mode = PortableMode.Deserialize) - { - return Unmarshal<T>(stream, mode, null); - } - - /// <summary> - /// Unmarshal object. - /// </summary> - /// <param name="stream">Stream over underlying byte array with correct position.</param> - /// <param name="mode">The mode.</param> - /// <param name="builder">Builder.</param> - /// <returns> - /// Object. - /// </returns> - public T Unmarshal<T>(IPortableStream stream, PortableMode mode, PortableBuilderImpl builder) - { - return new PortableReaderImpl(this, _idToDesc, stream, mode, builder).Deserialize<T>(); - } - - /// <summary> - /// Start unmarshal session. - /// </summary> - /// <param name="stream">Stream.</param> - /// <param name="keepPortable">Whether to keep portables as portables.</param> - /// <returns> - /// Reader. - /// </returns> - public PortableReaderImpl StartUnmarshal(IPortableStream stream, bool keepPortable) - { - return new PortableReaderImpl(this, _idToDesc, stream, - keepPortable ? PortableMode.KeepPortable : PortableMode.Deserialize, null); - } - - /// <summary> - /// Start unmarshal session. - /// </summary> - /// <param name="stream">Stream.</param> - /// <param name="mode">The mode.</param> - /// <returns>Reader.</returns> - public PortableReaderImpl StartUnmarshal(IPortableStream stream, PortableMode mode = PortableMode.Deserialize) - { - return new PortableReaderImpl(this, _idToDesc, stream, mode, null); - } - - /// <summary> - /// Gets metadata for the given type ID. - /// </summary> - /// <param name="typeId">Type ID.</param> - /// <returns>Metadata or null.</returns> - public IPortableMetadata Metadata(int typeId) - { - if (Ignite != null) - { - IPortableMetadata meta = Ignite.Metadata(typeId); - - if (meta != null) - return meta; - } - - return PortableMetadataImpl.EmptyMeta; - } - - /// <summary> - /// Gets metadata handler for the given type ID. - /// </summary> - /// <param name="desc">Type descriptor.</param> - /// <returns>Metadata handler.</returns> - public IPortableMetadataHandler MetadataHandler(IPortableTypeDescriptor desc) - { - PortableMetadataHolder holder; - - if (!_metas.TryGetValue(desc.TypeId, out holder)) - { - lock (this) - { - if (!_metas.TryGetValue(desc.TypeId, out holder)) - { - IDictionary<int, PortableMetadataHolder> metas0 = - new Dictionary<int, PortableMetadataHolder>(_metas); - - holder = desc.MetadataEnabled ? new PortableMetadataHolder(desc.TypeId, - desc.TypeName, desc.AffinityKeyFieldName) : null; - - metas0[desc.TypeId] = holder; - - _metas = metas0; - } - } - } - - if (holder != null) - { - ICollection<int> ids = holder.FieldIds(); - - bool newType = ids.Count == 0 && !holder.Saved(); - - return new PortableHashsetMetadataHandler(ids, newType); - } - return null; - } - - /// <summary> - /// Callback invoked when metadata has been sent to the server and acknowledged by it. - /// </summary> - /// <param name="newMetas"></param> - public void OnMetadataSent(IDictionary<int, IPortableMetadata> newMetas) - { - foreach (KeyValuePair<int, IPortableMetadata> metaEntry in newMetas) - { - PortableMetadataImpl meta = (PortableMetadataImpl) metaEntry.Value; - - IDictionary<int, Tuple<string, int>> mergeInfo = - new Dictionary<int, Tuple<string, int>>(meta.FieldsMap().Count); - - foreach (KeyValuePair<string, int> fieldMeta in meta.FieldsMap()) - { - int fieldId = PortableUtils.FieldId(metaEntry.Key, fieldMeta.Key, null, null); - - mergeInfo[fieldId] = new Tuple<string, int>(fieldMeta.Key, fieldMeta.Value); - } - - _metas[metaEntry.Key].Merge(mergeInfo); - } - } - - /// <summary> - /// Gets descriptor for type. - /// </summary> - /// <param name="type">Type.</param> - /// <returns>Descriptor.</returns> - public IPortableTypeDescriptor Descriptor(Type type) - { - IPortableTypeDescriptor desc; - - _typeToDesc.TryGetValue(type, out desc); - - return desc; - } - - /// <summary> - /// Gets descriptor for type name. - /// </summary> - /// <param name="typeName">Type name.</param> - /// <returns>Descriptor.</returns> - public IPortableTypeDescriptor Descriptor(string typeName) - { - IPortableTypeDescriptor desc; - - return _typeNameToDesc.TryGetValue(typeName, out desc) ? desc : - new PortableSurrogateTypeDescriptor(_cfg, typeName); - } - - /// <summary> - /// - /// </summary> - /// <param name="userType"></param> - /// <param name="typeId"></param> - /// <returns></returns> - public IPortableTypeDescriptor Descriptor(bool userType, int typeId) - { - IPortableTypeDescriptor desc; - - return _idToDesc.TryGetValue(PortableUtils.TypeKey(userType, typeId), out desc) ? desc : - userType ? new PortableSurrogateTypeDescriptor(_cfg, typeId) : null; - } - - /// <summary> - /// Add user type. - /// </summary> - /// <param name="cfg">Configuration.</param> - /// <param name="typeCfg">Type configuration.</param> - /// <param name="typeResolver">The type resolver.</param> - /// <param name="dfltSerializer">The default serializer.</param> - private void AddUserType(PortableConfiguration cfg, PortableTypeConfiguration typeCfg, - TypeResolver typeResolver, IPortableSerializer dfltSerializer) - { - // Get converter/mapper/serializer. - IPortableNameMapper nameMapper = typeCfg.NameMapper ?? cfg.DefaultNameMapper; - - IPortableIdMapper idMapper = typeCfg.IdMapper ?? cfg.DefaultIdMapper; - - bool metaEnabled = typeCfg.MetadataEnabled ?? cfg.DefaultMetadataEnabled; - - bool keepDeserialized = typeCfg.KeepDeserialized ?? cfg.DefaultKeepDeserialized; - - // Try resolving type. - Type type = typeResolver.ResolveType(typeCfg.TypeName, typeCfg.AssemblyName); - - if (type != null) - { - // Type is found. - var typeName = GetTypeName(type); - - int typeId = PortableUtils.TypeId(typeName, nameMapper, idMapper); - - var serializer = typeCfg.Serializer ?? cfg.DefaultSerializer - ?? GetPortableMarshalAwareSerializer(type) ?? dfltSerializer; - - var refSerializer = serializer as PortableReflectiveSerializer; - - if (refSerializer != null) - refSerializer.Register(type, typeId, nameMapper, idMapper); - - AddType(type, typeId, typeName, true, metaEnabled, keepDeserialized, nameMapper, idMapper, serializer, - typeCfg.AffinityKeyFieldName, null, null); - } - else - { - // Type is not found. - string typeName = PortableUtils.SimpleTypeName(typeCfg.TypeName); - - int typeId = PortableUtils.TypeId(typeName, nameMapper, idMapper); - - AddType(null, typeId, typeName, true, metaEnabled, keepDeserialized, nameMapper, idMapper, null, - typeCfg.AffinityKeyFieldName, null, null); - } - } - - /// <summary> - /// Gets the <see cref="PortableMarshalAwareSerializer"/> for a type if it is compatible. - /// </summary> - /// <param name="type">The type.</param> - /// <returns>Resulting <see cref="PortableMarshalAwareSerializer"/>, or null.</returns> - private static IPortableSerializer GetPortableMarshalAwareSerializer(Type type) - { - return type.GetInterfaces().Contains(typeof (IPortableMarshalAware)) - ? PortableMarshalAwareSerializer.Instance - : null; - } - - /// <summary> - /// Add predefined type. - /// </summary> - /// <param name="type">Type.</param> - /// <param name="typeId">Type ID.</param> - /// <param name="typedHandler">Typed handler.</param> - /// <param name="untypedHandler">Untyped handler.</param> - private void AddPredefinedType(Type type, int typeId, object typedHandler, - PortableSystemWriteDelegate untypedHandler) - { - AddType(type, typeId, GetTypeName(type), false, false, false, null, null, null, null, typedHandler, - untypedHandler); - } - - /// <summary> - /// Add type. - /// </summary> - /// <param name="type">Type.</param> - /// <param name="typeId">Type ID.</param> - /// <param name="typeName">Type name.</param> - /// <param name="userType">User type flag.</param> - /// <param name="metaEnabled">Metadata enabled flag.</param> - /// <param name="keepDeserialized">Whether to cache deserialized value in IPortableObject</param> - /// <param name="nameMapper">Name mapper.</param> - /// <param name="idMapper">ID mapper.</param> - /// <param name="serializer">Serializer.</param> - /// <param name="affKeyFieldName">Affinity key field name.</param> - /// <param name="typedHandler">Typed handler.</param> - /// <param name="untypedHandler">Untyped handler.</param> - private void AddType(Type type, int typeId, string typeName, bool userType, bool metaEnabled, - bool keepDeserialized, IPortableNameMapper nameMapper, IPortableIdMapper idMapper, - IPortableSerializer serializer, string affKeyFieldName, object typedHandler, - PortableSystemWriteDelegate untypedHandler) - { - long typeKey = PortableUtils.TypeKey(userType, typeId); - - if (_idToDesc.ContainsKey(typeKey)) - { - string type1 = _idToDesc[typeKey].Type != null ? _idToDesc[typeKey].Type.AssemblyQualifiedName : null; - string type2 = type != null ? type.AssemblyQualifiedName : null; - - throw new PortableException("Conflicting type IDs [type1=" + type1 + ", type2=" + type2 + - ", typeId=" + typeId + ']'); - } - - if (userType && _typeNameToDesc.ContainsKey(typeName)) - throw new PortableException("Conflicting type name: " + typeName); - - IPortableTypeDescriptor descriptor = - new PortableFullTypeDescriptor(type, typeId, typeName, userType, nameMapper, idMapper, serializer, - metaEnabled, keepDeserialized, affKeyFieldName, typedHandler, untypedHandler); - - if (type != null) - _typeToDesc[type] = descriptor; - - if (userType) - _typeNameToDesc[typeName] = descriptor; - - _idToDesc[typeKey] = descriptor; - } - - /// <summary> - /// Adds a predefined system type. - /// </summary> - private void AddSystemType<T>(byte typeId, Func<PortableReaderImpl, T> ctor) where T : IPortableWriteAware - { - var type = typeof(T); - - var serializer = new PortableSystemTypeSerializer<T>(ctor); - - AddType(type, typeId, GetTypeName(type), false, false, false, null, null, serializer, null, null, null); - } - - /// <summary> - /// Adds predefined system types. - /// </summary> - private void AddSystemTypes() - { - AddSystemType(PortableUtils.TypeNativeJobHolder, w => new ComputeJobHolder(w)); - AddSystemType(PortableUtils.TypeComputeJobWrapper, w => new ComputeJobWrapper(w)); - AddSystemType(PortableUtils.TypePortableJobResHolder, w => new PortableResultWrapper(w)); - AddSystemType(PortableUtils.TypeIgniteProxy, w => new IgniteProxy()); - AddSystemType(PortableUtils.TypeComputeOutFuncJob, w => new ComputeOutFuncJob(w)); - AddSystemType(PortableUtils.TypeComputeOutFuncWrapper, w => new ComputeOutFuncWrapper(w)); - AddSystemType(PortableUtils.TypeComputeFuncWrapper, w => new ComputeFuncWrapper(w)); - AddSystemType(PortableUtils.TypeComputeFuncJob, w => new ComputeFuncJob(w)); - AddSystemType(PortableUtils.TypeComputeActionJob, w => new ComputeActionJob(w)); - AddSystemType(PortableUtils.TypeContinuousQueryRemoteFilterHolder, w => new ContinuousQueryFilterHolder(w)); - AddSystemType(PortableUtils.TypeSerializableHolder, w => new SerializableObjectHolder(w)); - AddSystemType(PortableUtils.TypeCacheEntryProcessorHolder, w => new CacheEntryProcessorHolder(w)); - AddSystemType(PortableUtils.TypeCacheEntryPredicateHolder, w => new CacheEntryFilterHolder(w)); - AddSystemType(PortableUtils.TypeMessageFilterHolder, w => new MessageFilterHolder(w)); - AddSystemType(PortableUtils.TypePortableOrSerializableHolder, w => new PortableOrSerializableObjectHolder(w)); - AddSystemType(PortableUtils.TypeStreamReceiverHolder, w => new StreamReceiverHolder(w)); - } - - /// <summary> - /// Gets the name of the type. - /// </summary> - /// <param name="type">The type.</param> - /// <returns> - /// Simple type name for non-generic types; simple type name with appended generic arguments for generic types. - /// </returns> - private static string GetTypeName(Type type) - { - if (!type.IsGenericType) - return type.Name; - - var args = type.GetGenericArguments().Select(GetTypeName).Aggregate((x, y) => x + "," + y); - - return string.Format("{0}[{1}]", type.Name, args); - } - } -}
