http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Io/BinaryStreamAdapter.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Io/BinaryStreamAdapter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Io/BinaryStreamAdapter.cs deleted file mode 100644 index b062689..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Io/BinaryStreamAdapter.cs +++ /dev/null @@ -1,119 +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.Binary.IO -{ - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - - /// <summary> - /// Adapter providing .Net streaming functionality over the binary stream. - /// </summary> - internal class BinaryStreamAdapter : Stream - { - /// <summary> - /// - /// </summary> - private readonly IBinaryStream _stream; - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="stream">Stream.</param> - public BinaryStreamAdapter(IBinaryStream stream) - { - _stream = stream; - } - - /** <inheritDoc /> */ - public override void Write(byte[] buffer, int offset, int count) - { - _stream.Write(buffer, offset, count); - } - - /** <inheritDoc /> */ - public override int Read(byte[] buffer, int offset, int count) - { - _stream.Read(buffer, offset, count); - - return count; - } - - /** <inheritDoc /> */ - public override void Flush() - { - // No-op. - } - - /** <inheritDoc /> */ - public override bool CanRead - { - get { return true; } - } - - /** <inheritDoc /> */ - public override bool CanWrite - { - get { return true; } - } - - /** <inheritDoc /> */ - public override bool CanSeek - { - get { return false; } - } - - /** <inheritDoc /> */ - [ExcludeFromCodeCoverage] - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException("Stream is not seekable."); - } - - /** <inheritDoc /> */ - [ExcludeFromCodeCoverage] - public override long Position - { - get - { - throw new NotSupportedException("Stream is not seekable."); - } - set - { - throw new NotSupportedException("Stream is not seekable."); - } - } - - /** <inheritDoc /> */ - [ExcludeFromCodeCoverage] - public override long Length - { - get - { - throw new NotSupportedException("Stream is not seekable."); - } - } - - /** <inheritDoc /> */ - [ExcludeFromCodeCoverage] - public override void SetLength(long value) - { - throw new NotSupportedException("Stream is not seekable."); - } - } -}
http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs index b929f3a..5effc5c 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs @@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Impl.Binary using System.Collections.Generic; using System.Diagnostics; using System.Linq; + using System.Runtime.Serialization; using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Cache.Affinity; using Apache.Ignite.Core.Common; @@ -33,6 +34,7 @@ namespace Apache.Ignite.Core.Impl.Binary using Apache.Ignite.Core.Impl.Compute.Closure; using Apache.Ignite.Core.Impl.Datastream; using Apache.Ignite.Core.Impl.Messaging; + using Apache.Ignite.Core.Log; /// <summary> /// Marshaller implementation. @@ -43,37 +45,43 @@ namespace Apache.Ignite.Core.Impl.Binary private readonly BinaryConfiguration _cfg; /** Type to descriptor map. */ - private readonly IDictionary<Type, IBinaryTypeDescriptor> _typeToDesc = - new Dictionary<Type, IBinaryTypeDescriptor>(); + private readonly CopyOnWriteConcurrentDictionary<Type, BinaryFullTypeDescriptor> _typeToDesc = + new CopyOnWriteConcurrentDictionary<Type, BinaryFullTypeDescriptor>(); /** Type name to descriptor map. */ - private readonly IDictionary<string, IBinaryTypeDescriptor> _typeNameToDesc = - new Dictionary<string, IBinaryTypeDescriptor>(); + private readonly CopyOnWriteConcurrentDictionary<string, BinaryFullTypeDescriptor> _typeNameToDesc = + new CopyOnWriteConcurrentDictionary<string, BinaryFullTypeDescriptor>(); /** ID to descriptor map. */ - private readonly CopyOnWriteConcurrentDictionary<long, IBinaryTypeDescriptor> _idToDesc = - new CopyOnWriteConcurrentDictionary<long, IBinaryTypeDescriptor>(); + private readonly CopyOnWriteConcurrentDictionary<long, BinaryFullTypeDescriptor> _idToDesc = + new CopyOnWriteConcurrentDictionary<long, BinaryFullTypeDescriptor>(); - /** Cached metadatas. */ - private volatile IDictionary<int, BinaryTypeHolder> _metas = - new Dictionary<int, BinaryTypeHolder>(); + /** Cached binary types. */ + private volatile IDictionary<int, BinaryTypeHolder> _metas = new Dictionary<int, BinaryTypeHolder>(); + + /** */ + private volatile Ignite _ignite; + + /** */ + private readonly ILogger _log; /// <summary> /// Constructor. /// </summary> /// <param name="cfg">Configuration.</param> - public Marshaller(BinaryConfiguration cfg) + /// <param name="log"></param> + public Marshaller(BinaryConfiguration cfg, ILogger log = null) { - // Validation. - if (cfg == null) - cfg = new BinaryConfiguration(); + _cfg = cfg ?? new BinaryConfiguration(); + + _log = log; - CompactFooter = cfg.CompactFooter; + CompactFooter = _cfg.CompactFooter; - if (cfg.TypeConfigurations == null) - cfg.TypeConfigurations = new List<BinaryTypeConfiguration>(); + if (_cfg.TypeConfigurations == null) + _cfg.TypeConfigurations = new List<BinaryTypeConfiguration>(); - foreach (BinaryTypeConfiguration typeCfg in cfg.TypeConfigurations) + foreach (BinaryTypeConfiguration typeCfg in _cfg.TypeConfigurations) { if (string.IsNullOrEmpty(typeCfg.TypeName)) throw new BinaryObjectException("Type name cannot be null or empty: " + typeCfg); @@ -85,25 +93,32 @@ namespace Apache.Ignite.Core.Impl.Binary // 2. Define user types. var typeResolver = new TypeResolver(); - ICollection<BinaryTypeConfiguration> typeCfgs = cfg.TypeConfigurations; + ICollection<BinaryTypeConfiguration> typeCfgs = _cfg.TypeConfigurations; if (typeCfgs != null) foreach (BinaryTypeConfiguration typeCfg in typeCfgs) AddUserType(cfg, typeCfg, typeResolver); - var typeNames = cfg.Types; + var typeNames = _cfg.Types; if (typeNames != null) foreach (string typeName in typeNames) AddUserType(cfg, new BinaryTypeConfiguration(typeName), typeResolver); - - _cfg = cfg; } /// <summary> /// Gets or sets the backing grid. /// </summary> - public Ignite Ignite { get; set; } + public Ignite Ignite + { + get { return _ignite; } + set + { + Debug.Assert(value != null); + + _ignite = value; + } + } /// <summary> /// Gets the compact footer flag. @@ -111,6 +126,12 @@ namespace Apache.Ignite.Core.Impl.Binary public bool CompactFooter { get; set; } /// <summary> + /// Gets or sets a value indicating whether type registration is disabled. + /// This may be desirable for static system marshallers where everything is written in unregistered mode. + /// </summary> + public bool RegistrationDisabled { get; set; } + + /// <summary> /// Marshal object. /// </summary> /// <param name="val">Value.</param> @@ -126,11 +147,10 @@ namespace Apache.Ignite.Core.Impl.Binary } /// <summary> - /// Marshal object. + /// Marshals an 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, IBinaryStream stream) { BinaryWriter writer = StartMarshal(stream); @@ -358,17 +378,20 @@ namespace Apache.Ignite.Core.Impl.Binary _metas[meta.TypeId].Merge(mergeInfo); } } - + /// <summary> /// Gets descriptor for type. /// </summary> /// <param name="type">Type.</param> - /// <returns>Descriptor.</returns> + /// <returns> + /// Descriptor. + /// </returns> public IBinaryTypeDescriptor GetDescriptor(Type type) { - IBinaryTypeDescriptor desc; + BinaryFullTypeDescriptor desc; - _typeToDesc.TryGetValue(type, out desc); + if (!_typeToDesc.TryGetValue(type, out desc) || !desc.IsRegistered) + desc = RegisterType(type, desc); return desc; } @@ -380,10 +403,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// <returns>Descriptor.</returns> public IBinaryTypeDescriptor GetDescriptor(string typeName) { - IBinaryTypeDescriptor desc; + BinaryFullTypeDescriptor desc; - return _typeNameToDesc.TryGetValue(typeName, out desc) ? desc : - new BinarySurrogateTypeDescriptor(_cfg, typeName); + return _typeNameToDesc.TryGetValue(typeName, out desc) + ? (IBinaryTypeDescriptor) desc + : new BinarySurrogateTypeDescriptor(_cfg, typeName); } /// <summary> @@ -391,24 +415,43 @@ namespace Apache.Ignite.Core.Impl.Binary /// </summary> /// <param name="userType">User type flag.</param> /// <param name="typeId">Type id.</param> - /// <returns>Descriptor.</returns> - public IBinaryTypeDescriptor GetDescriptor(bool userType, int typeId) + /// <param name="requiresType"> + /// If set to true, resulting descriptor must have Type property populated. + /// <para /> + /// When working in binary mode, we don't need Type. And there is no Type at all in some cases. + /// So we should not attempt to call BinaryProcessor right away. + /// Only when we really deserialize the value, requiresType is set to true + /// and we attempt to resolve the type by all means. + /// </param> + /// <returns> + /// Descriptor. + /// </returns> + public IBinaryTypeDescriptor GetDescriptor(bool userType, int typeId, bool requiresType = false) { - IBinaryTypeDescriptor desc; + BinaryFullTypeDescriptor desc; var typeKey = BinaryUtils.TypeKey(userType, typeId); - if (_idToDesc.TryGetValue(typeKey, out desc)) + if (_idToDesc.TryGetValue(typeKey, out desc) && (!requiresType || desc.Type != null)) return desc; if (!userType) return null; + if (requiresType) + { + // Check marshaller context for dynamically registered type. + var type = _ignite == null ? null : _ignite.BinaryProcessor.GetType(typeId); + + if (type != null) + return AddUserType(type, typeId, BinaryUtils.GetTypeName(type), true, desc); + } + var meta = GetBinaryType(typeId); if (meta != BinaryType.Empty) { - desc = new BinaryFullTypeDescriptor(null, meta.TypeId, meta.TypeName, true, null, null, null, false, + desc = new BinaryFullTypeDescriptor(null, meta.TypeId, meta.TypeName, true, null, null, null, false, meta.AffinityKeyFieldName, meta.IsEnum, null); _idToDesc.GetOrAdd(typeKey, _ => desc); @@ -416,13 +459,30 @@ namespace Apache.Ignite.Core.Impl.Binary return desc; } - return new BinarySurrogateTypeDescriptor(_cfg, typeId); + return new BinarySurrogateTypeDescriptor(_cfg, typeId, null); + } + + /// <summary> + /// Registers the type. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="desc">Existing descriptor.</param> + private BinaryFullTypeDescriptor RegisterType(Type type, BinaryFullTypeDescriptor desc) + { + Debug.Assert(type != null); + + var typeName = BinaryUtils.GetTypeName(type); + var typeId = BinaryUtils.TypeId(typeName, _cfg.DefaultNameMapper, _cfg.DefaultIdMapper); + + var registered = _ignite != null && _ignite.BinaryProcessor.RegisterType(typeId, type); + + return AddUserType(type, typeId, typeName, registered, desc); } /// <summary> /// Gets the user type descriptors. /// </summary> - public ICollection<IBinaryTypeDescriptor> GetUserTypeDescriptors() + public ICollection<BinaryFullTypeDescriptor> GetUserTypeDescriptors() { return _typeNameToDesc.Values; } @@ -430,18 +490,67 @@ namespace Apache.Ignite.Core.Impl.Binary /// <summary> /// Add user type. /// </summary> - /// <param name="cfg">Configuration.</param> + /// <param name="type">The type.</param> + /// <param name="typeId">The type id.</param> + /// <param name="typeName">Name of the type.</param> + /// <param name="registered">Registered flag.</param> + /// <param name="desc">Existing descriptor.</param> + /// <returns>Descriptor.</returns> + private BinaryFullTypeDescriptor AddUserType(Type type, int typeId, string typeName, bool registered, + BinaryFullTypeDescriptor desc) + { + Debug.Assert(type != null); + Debug.Assert(typeName != null); + + var ser = GetSerializer(_cfg, null, type, typeId, null, null, _log); + + desc = desc == null + ? new BinaryFullTypeDescriptor(type, typeId, typeName, true, _cfg.DefaultNameMapper, + _cfg.DefaultIdMapper, ser, false, null, type.IsEnum, null, registered) + : new BinaryFullTypeDescriptor(desc, type, ser, registered); + + if (RegistrationDisabled) + return desc; + + var typeKey = BinaryUtils.TypeKey(true, typeId); + + var desc0 = _idToDesc.GetOrAdd(typeKey, x => desc); + if (desc0.Type != null && desc0.Type.FullName != type.FullName) + ThrowConflictingTypeError(type, desc0.Type, typeId); + + desc0 = _typeNameToDesc.GetOrAdd(typeName, x => desc); + if (desc0.Type != null && desc0.Type.FullName != type.FullName) + ThrowConflictingTypeError(type, desc0.Type, typeId); + + _typeToDesc.Set(type, desc); + + return desc; + } + + /// <summary> + /// Throws the conflicting type error. + /// </summary> + private static void ThrowConflictingTypeError(object type1, object type2, int typeId) + { + throw new BinaryObjectException(string.Format("Conflicting type IDs [type1='{0}', " + + "type2='{1}', typeId={2}]", type1, type2, typeId)); + } + + /// <summary> + /// Add user type. + /// </summary> + /// <param name="cfg">The binary configuration.</param> /// <param name="typeCfg">Type configuration.</param> /// <param name="typeResolver">The type resolver.</param> - private void AddUserType(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, - TypeResolver typeResolver) + /// <exception cref="BinaryObjectException"></exception> + private void AddUserType(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, TypeResolver typeResolver) { // Get converter/mapper/serializer. - IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? cfg.DefaultNameMapper; + IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? _cfg.DefaultNameMapper; - IBinaryIdMapper idMapper = typeCfg.IdMapper ?? cfg.DefaultIdMapper; + IBinaryIdMapper idMapper = typeCfg.IdMapper ?? _cfg.DefaultIdMapper; - bool keepDeserialized = typeCfg.KeepDeserialized ?? cfg.DefaultKeepDeserialized; + bool keepDeserialized = typeCfg.KeepDeserialized ?? _cfg.DefaultKeepDeserialized; // Try resolving type. Type type = typeResolver.ResolveType(typeCfg.TypeName); @@ -459,7 +568,7 @@ namespace Apache.Ignite.Core.Impl.Binary var typeName = BinaryUtils.GetTypeName(type); int typeId = BinaryUtils.TypeId(typeName, nameMapper, idMapper); var affKeyFld = typeCfg.AffinityKeyFieldName ?? GetAffinityKeyFieldNameFromAttribute(type); - var serializer = GetSerializer(cfg, typeCfg, type, typeId, nameMapper, idMapper); + var serializer = GetSerializer(cfg, typeCfg, type, typeId, nameMapper, idMapper, _log); AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer, affKeyFld, type.IsEnum, typeCfg.EqualityComparer); @@ -479,16 +588,25 @@ namespace Apache.Ignite.Core.Impl.Binary /// <summary> /// Gets the serializer. /// </summary> - private static IBinarySerializerInternal GetSerializer(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, - Type type, int typeId, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper) + private static IBinarySerializerInternal GetSerializer(BinaryConfiguration cfg, + BinaryTypeConfiguration typeCfg, Type type, int typeId, IBinaryNameMapper nameMapper, + IBinaryIdMapper idMapper, ILogger log) { - var serializer = typeCfg.Serializer ?? cfg.DefaultSerializer; + var serializer = (typeCfg != null ? typeCfg.Serializer : null) ?? + (cfg != null ? cfg.DefaultSerializer : null); if (serializer == null) { if (type.GetInterfaces().Contains(typeof(IBinarizable))) return BinarizableSerializer.Instance; + if (type.GetInterfaces().Contains(typeof(ISerializable))) + { + LogSerializableWarning(type, log); + + return new SerializableSerializer(type); + } + serializer = new BinaryReflectiveSerializer(); } @@ -531,14 +649,14 @@ namespace Apache.Ignite.Core.Impl.Binary /// <param name="affKeyFieldName">Affinity key field name.</param> /// <param name="isEnum">Enum flag.</param> /// <param name="comparer">Comparer.</param> - private void AddType(Type type, int typeId, string typeName, bool userType, + private void AddType(Type type, int typeId, string typeName, bool userType, bool keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper, - IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum, + IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum, IEqualityComparer<IBinaryObject> comparer) { long typeKey = BinaryUtils.TypeKey(userType, typeId); - IBinaryTypeDescriptor conflictingType; + BinaryFullTypeDescriptor conflictingType; if (_idToDesc.TryGetValue(typeKey, out conflictingType)) { @@ -548,8 +666,7 @@ namespace Apache.Ignite.Core.Impl.Binary var type2 = type != null ? type.AssemblyQualifiedName : typeName; - throw new BinaryObjectException(string.Format("Conflicting type IDs [type1='{0}', " + - "type2='{1}', typeId={2}]", type1, type2, typeId)); + ThrowConflictingTypeError(type1, type2, typeId); } if (userType && _typeNameToDesc.ContainsKey(typeName)) @@ -559,10 +676,10 @@ namespace Apache.Ignite.Core.Impl.Binary serializer, keepDeserialized, affKeyFieldName, isEnum, comparer); if (type != null) - _typeToDesc[type] = descriptor; + _typeToDesc.GetOrAdd(type, x => descriptor); if (userType) - _typeNameToDesc[typeName] = descriptor; + _typeNameToDesc.GetOrAdd(typeName, x => descriptor); _idToDesc.GetOrAdd(typeKey, _ => descriptor); } @@ -570,7 +687,7 @@ namespace Apache.Ignite.Core.Impl.Binary /// <summary> /// Adds a predefined system type. /// </summary> - private void AddSystemType<T>(int typeId, Func<BinaryReader, T> ctor, string affKeyFldName = null, + private void AddSystemType<T>(int typeId, Func<BinaryReader, T> ctor, string affKeyFldName = null, IBinarySerializerInternal serializer = null) where T : IBinaryWriteAware { @@ -599,10 +716,6 @@ namespace Apache.Ignite.Core.Impl.Binary AddSystemType(BinaryUtils.TypeComputeFuncJob, r => new ComputeFuncJob(r)); AddSystemType(BinaryUtils.TypeComputeActionJob, r => new ComputeActionJob(r)); AddSystemType(BinaryUtils.TypeContinuousQueryRemoteFilterHolder, r => new ContinuousQueryFilterHolder(r)); - AddSystemType(BinaryUtils.TypeSerializableHolder, r => new SerializableObjectHolder(r), - serializer: new SerializableSerializer()); - AddSystemType(BinaryUtils.TypeDateTimeHolder, r => new DateTimeHolder(r), - serializer: new DateTimeSerializer()); AddSystemType(BinaryUtils.TypeCacheEntryProcessorHolder, r => new CacheEntryProcessorHolder(r)); AddSystemType(BinaryUtils.TypeCacheEntryPredicateHolder, r => new CacheEntryFilterHolder(r)); AddSystemType(BinaryUtils.TypeMessageListenerHolder, r => new MessageListenerHolder(r)); @@ -612,5 +725,20 @@ namespace Apache.Ignite.Core.Impl.Binary AddSystemType(0, r => new ObjectInfoHolder(r)); AddSystemType(BinaryUtils.TypeIgniteUuid, r => new IgniteGuid(r)); } + + /// <summary> + /// Logs the warning about ISerializable pitfalls. + /// </summary> + private static void LogSerializableWarning(Type type, ILogger log) + { + if (log == null) + return; + + log.GetLogger(typeof(Marshaller).Name) + .Warn("Type '{0}' implements '{1}'. It will be written in Ignite binary format, however, " + + "the following limitations apply: " + + "DateTime fields would not work in SQL; " + + "sbyte, ushort, uint, ulong fields would not work in DML.", type, typeof(ISerializable)); + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/ReflectionUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/ReflectionUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/ReflectionUtils.cs new file mode 100644 index 0000000..50c51a7 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/ReflectionUtils.cs @@ -0,0 +1,50 @@ +/* + * 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.Binary +{ + using System; + using System.Collections.Generic; + using System.Reflection; + + /// <summary> + /// Reflection utils. + /// </summary> + internal static class ReflectionUtils + { + /// <summary> + /// Gets all fields, including base classes. + /// </summary> + public static IEnumerable<FieldInfo> GetAllFields(Type type) + { + const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | + BindingFlags.NonPublic | BindingFlags.DeclaredOnly; + + var curType = type; + + while (curType != null) + { + foreach (var field in curType.GetFields(flags)) + { + yield return field; + } + + curType = curType.BaseType; + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableObjectHolder.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableObjectHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableObjectHolder.cs deleted file mode 100644 index 26b1d5f..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableObjectHolder.cs +++ /dev/null @@ -1,96 +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.Binary -{ - using System.Diagnostics; - using System.Runtime.Serialization.Formatters.Binary; - using Apache.Ignite.Core.Binary; - using Apache.Ignite.Core.Impl.Binary.IO; - - /// <summary> - /// Wraps Serializable item in a binarizable. - /// </summary> - internal class SerializableObjectHolder : IBinaryWriteAware - { - /** */ - 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 WriteBinary(IBinaryWriter writer) - { - Debug.Assert(writer != null); - - var writer0 = (BinaryWriter)writer.GetRawWriter(); - - writer0.WithDetach(w => - { - using (var streamAdapter = new BinaryStreamAdapter(w.Stream)) - { - new BinaryFormatter().Serialize(streamAdapter, Item); - } - }); - } - - /// <summary> - /// Initializes a new instance of the <see cref="SerializableObjectHolder"/> class. - /// </summary> - /// <param name="reader">The reader.</param> - public SerializableObjectHolder(BinaryReader reader) - { - Debug.Assert(reader != null); - - using (var streamAdapter = new BinaryStreamAdapter(reader.Stream)) - { - _item = new BinaryFormatter().Deserialize(streamAdapter, null); - } - } - - /** <inheritdoc /> */ - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - - return Equals(_item, ((SerializableObjectHolder) obj)._item); - } - - /** <inheritdoc /> */ - public override int GetHashCode() - { - return _item != null ? _item.GetHashCode() : 0; - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs index 55ac3c0..6c7076a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs @@ -1,4 +1,4 @@ -/* +/* * 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. @@ -18,31 +18,667 @@ namespace Apache.Ignite.Core.Impl.Binary { using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Runtime.Serialization; + using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Impl.Binary.Metadata; using Apache.Ignite.Core.Impl.Common; /// <summary> - /// Serializable serializer. + /// Serializes classes that implement <see cref="ISerializable"/>. /// </summary> internal class SerializableSerializer : IBinarySerializerInternal { + /** */ + private readonly SerializableTypeDescriptor _serializableTypeDesc; + + /// <summary> + /// Initializes a new instance of the <see cref="SerializableSerializer"/> class. + /// </summary> + public SerializableSerializer(Type type) + { + IgniteArgumentCheck.NotNull(type, "type"); + + _serializableTypeDesc = SerializableTypeDescriptor.Get(type); + } + /** <inheritdoc /> */ - public void WriteBinary<T>(T obj, BinaryWriter writer) + public bool SupportsHandles { - TypeCaster<SerializableObjectHolder>.Cast(obj).WriteBinary(writer); + get { return true; } } /** <inheritdoc /> */ - public T ReadBinary<T>(BinaryReader reader, Type type, int pos) + public void WriteBinary<T>(T obj, BinaryWriter writer) { - var holder = new SerializableObjectHolder(reader); + var ctx = GetStreamingContext(writer); + _serializableTypeDesc.OnSerializing(obj, ctx); + + var serializable = (ISerializable) obj; + var objType = obj.GetType(); + + // Get field values and write them. + var serInfo = new SerializationInfo(objType, new FormatterConverter()); + serializable.GetObjectData(serInfo, ctx); - return TypeCaster<T>.Cast(holder.Item); + var dotNetFields = WriteSerializationInfo(writer, serInfo); + + // Check if there is any additional information to be written. + var customType = GetCustomType(serInfo, serializable); + + if (dotNetFields != null || writer.Marshaller.Ignite == null || customType != null) + { + // Set custom type flag in object header. + writer.SetCustomTypeDataFlag(true); + + // Write additional information in raw mode. + writer.GetRawWriter(); + + WriteFieldNames(writer, serInfo); + + WriteCustomTypeInfo(writer, customType); + + WriteDotNetFields(writer, dotNetFields); + } + + _serializableTypeDesc.OnSerialized(obj, ctx); } /** <inheritdoc /> */ - public bool SupportsHandles + public T ReadBinary<T>(BinaryReader reader, IBinaryTypeDescriptor desc, int pos) + { + object res; + var ctx = GetStreamingContext(reader); + var callbackPushed = false; + + // Read additional information from raw part, if flag is set. + IEnumerable<string> fieldNames; + Type customType = null; + ICollection<int> dotNetFields = null; + + if (reader.GetCustomTypeDataFlag()) + { + var oldPos = reader.Stream.Position; + reader.SeekToRaw(); + + fieldNames = ReadFieldNames(reader, desc); + customType = ReadCustomTypeInfo(reader); + dotNetFields = ReadDotNetFields(reader); + + // Restore stream position. + reader.Stream.Seek(oldPos, SeekOrigin.Begin); + } + else + { + fieldNames = GetBinaryTypeFields(reader, desc); + } + + try + { + if (customType != null) + { + // Custom type is present, which returns original type via IObjectReference. + var serInfo = ReadSerializationInfo(reader, fieldNames, desc, dotNetFields); + + res = ReadAsCustomType(customType, serInfo, ctx); + + // Handle is added after entire object is deserialized, + // because handles should not point to a custom type wrapper. + reader.AddHandle(pos, res); + + DeserializationCallbackProcessor.Push(res); + callbackPushed = true; + } + else + { + res = FormatterServices.GetUninitializedObject(desc.Type); + + _serializableTypeDesc.OnDeserializing(res, ctx); + + DeserializationCallbackProcessor.Push(res); + callbackPushed = true; + + reader.AddHandle(pos, res); + + // Read actual data and call constructor. + var serInfo = ReadSerializationInfo(reader, fieldNames, desc, dotNetFields); + _serializableTypeDesc.SerializationCtorUninitialized(res, serInfo, ctx); + } + + _serializableTypeDesc.OnDeserialized(res, ctx); + } + finally + { + if (callbackPushed) + DeserializationCallbackProcessor.Pop(); + } + + return (T) res; + } + + /// <summary> + /// Writes .NET-specific fields. + /// </summary> + private static void WriteDotNetFields(IBinaryRawWriter writer, ICollection<string> dotNetFields) { - get { return false; } + if (dotNetFields == null) + { + writer.WriteInt(0); + + return; + } + + writer.WriteInt(dotNetFields.Count); + + foreach (var dotNetField in dotNetFields) + { + writer.WriteInt(BinaryUtils.GetStringHashCode(dotNetField)); + } + } + + /// <summary> + /// Writes .NET-specific fields. + /// </summary> + private static ICollection<int> ReadDotNetFields(IBinaryRawReader reader) + { + int count = reader.ReadInt(); + + if (count <= 0) + return null; + + var res = new HashSet<int>(); + + for (int i = 0; i < count; i++) + { + res.Add(reader.ReadInt()); + } + + return res; + } + + /// <summary> + /// Writes the field names. + /// </summary> + private static void WriteFieldNames(BinaryWriter writer, SerializationInfo serInfo) + { + if (writer.Marshaller.Ignite != null) + { + // Online mode: field names are in binary metadata. + writer.WriteInt(-1); + return; + } + + // Offline mode: write all field names. + // Even if MemberCount is 0, write empty array to denote offline mode. + writer.WriteInt(serInfo.MemberCount); + + foreach (var entry in serInfo) + { + writer.WriteString(entry.Name); + } + } + + /// <summary> + /// Gets the field names. + /// </summary> + private static IEnumerable<string> ReadFieldNames(BinaryReader reader, IBinaryTypeDescriptor desc) + { + var fieldCount = reader.ReadInt(); + + if (fieldCount == 0) + return Enumerable.Empty<string>(); + + if (fieldCount > 0) + { + var fieldNames = new string[fieldCount]; + + for (var i = 0; i < fieldCount; i++) + { + fieldNames[i] = reader.ReadString(); + } + + return fieldNames; + } + + // Negative field count: online mode. + return GetBinaryTypeFields(reader, desc); + } + + /// <summary> + /// Gets the binary type fields. + /// </summary> + private static IEnumerable<string> GetBinaryTypeFields(BinaryReader reader, IBinaryTypeDescriptor desc) + { + var binaryType = reader.Marshaller.GetBinaryType(desc.TypeId); + + if (binaryType == BinaryType.Empty) + { + // Object without fields. + return Enumerable.Empty<string>(); + } + + return binaryType.Fields; + } + + /// <summary> + /// Writes the custom type information. + /// </summary> + private static void WriteCustomTypeInfo(BinaryWriter writer, Type customType) + { + var raw = writer.GetRawWriter(); + + if (customType != null) + { + raw.WriteBoolean(true); + + var desc = writer.Marshaller.GetDescriptor(customType); + + if (desc.IsRegistered) + { + raw.WriteBoolean(true); + raw.WriteInt(desc.TypeId); + } + else + { + raw.WriteBoolean(false); + raw.WriteString(customType.FullName); + } + } + else + { + raw.WriteBoolean(false); + } + } + + /// <summary> + /// Gets the custom serialization type. + /// </summary> + private static Type GetCustomType(SerializationInfo serInfo, ISerializable serializable) + { + // ISerializable implementor may call SerializationInfo.SetType() or FullTypeName setter. + // In that case there is no serialization ctor on objType. + // Instead, we should instantiate specified custom type and then call IObjectReference.GetRealObject(). + if (serInfo.IsFullTypeNameSetExplicit) + { + return new TypeResolver().ResolveType(serInfo.FullTypeName, serInfo.AssemblyName); + } + + if (serInfo.ObjectType != serializable.GetType()) + { + return serInfo.ObjectType; + } + + return null; + } + + /// <summary> + /// Reads the custom type information. + /// </summary> + private static Type ReadCustomTypeInfo(BinaryReader reader) + { + if (!reader.ReadBoolean()) + return null; + + Type customType; + + if (reader.ReadBoolean()) + { + // Registered type written as type id. + var typeId = reader.ReadInt(); + customType = reader.Marshaller.GetDescriptor(true, typeId, true).Type; + + if (customType == null) + { + throw new BinaryObjectException(string.Format( + "Failed to resolve custom type provided by SerializationInfo: [typeId={0}]", typeId)); + } + } + else + { + // Unregistered type written as type name. + var typeName = reader.ReadString(); + customType = new TypeResolver().ResolveType(typeName); + + if (customType == null) + { + throw new BinaryObjectException(string.Format( + "Failed to resolve custom type provided by SerializationInfo: [typeName={0}]", typeName)); + } + } + + return customType; + } + + /// <summary> + /// Writes the serialization information. + /// </summary> + private static List<string> WriteSerializationInfo(IBinaryWriter writer, SerializationInfo serInfo) + { + List<string> dotNetFields = null; + + // Write fields. + foreach (var entry in GetEntries(serInfo).OrderBy(x => x.Name)) + { + WriteEntry(writer, entry); + + var type = entry.Value == null ? null : entry.Value.GetType(); + + if (type == typeof(sbyte) || type == typeof(ushort) || type == typeof(uint) || type == typeof(ulong) + || type == typeof(sbyte[]) || type == typeof(ushort[]) + || type == typeof(uint[]) || type == typeof(ulong[])) + { + // Denote .NET-specific type. + dotNetFields = dotNetFields ?? new List<string>(); + + dotNetFields.Add(entry.Name); + } + } + + return dotNetFields; + } + + /// <summary> + /// Writes the serialization entry. + /// </summary> + private static void WriteEntry(IBinaryWriter writer, SerializationEntry entry) + { + unchecked + { + var type = entry.ObjectType; + + if (type == typeof(byte)) + { + writer.WriteByte(entry.Name, (byte) entry.Value); + } + else if (type == typeof(byte[])) + { + writer.WriteByteArray(entry.Name, (byte[]) entry.Value); + } + if (type == typeof(sbyte)) + { + writer.WriteByte(entry.Name, (byte) (sbyte) entry.Value); + } + else if (type == typeof(sbyte[])) + { + writer.WriteByteArray(entry.Name, (byte[]) (Array) entry.Value); + } + else if (type == typeof(bool)) + { + writer.WriteBoolean(entry.Name, (bool) entry.Value); + } + else if (type == typeof(bool[])) + { + writer.WriteBooleanArray(entry.Name, (bool[]) entry.Value); + } + else if (type == typeof(char)) + { + writer.WriteChar(entry.Name, (char) entry.Value); + } + else if (type == typeof(char[])) + { + writer.WriteCharArray(entry.Name, (char[]) entry.Value); + } + else if (type == typeof(short)) + { + writer.WriteShort(entry.Name, (short) entry.Value); + } + else if (type == typeof(short[])) + { + writer.WriteShortArray(entry.Name, (short[]) entry.Value); + } + else if (type == typeof(ushort)) + { + writer.WriteShort(entry.Name, (short) (ushort) entry.Value); + } + else if (type == typeof(ushort[])) + { + writer.WriteShortArray(entry.Name, (short[]) (Array) entry.Value); + } + else if (type == typeof(int)) + { + writer.WriteInt(entry.Name, (int) entry.Value); + } + else if (type == typeof(int[])) + { + writer.WriteIntArray(entry.Name, (int[]) entry.Value); + } + else if (type == typeof(uint)) + { + writer.WriteInt(entry.Name, (int) (uint) entry.Value); + } + else if (type == typeof(uint[])) + { + writer.WriteIntArray(entry.Name, (int[]) (Array) entry.Value); + } + else if (type == typeof(long)) + { + writer.WriteLong(entry.Name, (long) entry.Value); + } + else if (type == typeof(long[])) + { + writer.WriteLongArray(entry.Name, (long[]) entry.Value); + } + else if (type == typeof(ulong)) + { + writer.WriteLong(entry.Name, (long) (ulong) entry.Value); + } + else if (type == typeof(ulong[])) + { + writer.WriteLongArray(entry.Name, (long[]) (Array) entry.Value); + } + else if (type == typeof(float)) + { + writer.WriteFloat(entry.Name, (float) entry.Value); + } + else if (type == typeof(float[])) + { + writer.WriteFloatArray(entry.Name, (float[]) entry.Value); + } + else if (type == typeof(double)) + { + writer.WriteDouble(entry.Name, (double) entry.Value); + } + else if (type == typeof(double[])) + { + writer.WriteDoubleArray(entry.Name, (double[]) entry.Value); + } + else if (type == typeof(decimal)) + { + writer.WriteDecimal(entry.Name, (decimal) entry.Value); + } + else if (type == typeof(decimal?)) + { + writer.WriteDecimal(entry.Name, (decimal?) entry.Value); + } + else if (type == typeof(decimal?[])) + { + writer.WriteDecimalArray(entry.Name, (decimal?[]) entry.Value); + } + else if (type == typeof(string)) + { + writer.WriteString(entry.Name, (string) entry.Value); + } + else if (type == typeof(string[])) + { + writer.WriteStringArray(entry.Name, (string[]) entry.Value); + } + else if (type == typeof(Guid)) + { + writer.WriteGuid(entry.Name, (Guid) entry.Value); + } + else if (type == typeof(Guid?)) + { + writer.WriteGuid(entry.Name, (Guid?) entry.Value); + } + else if (type == typeof(Guid?[])) + { + writer.WriteGuidArray(entry.Name, (Guid?[]) entry.Value); + } + else + { + writer.WriteObject(entry.Name, entry.Value); + } + } + } + + /// <summary> + /// Gets the entries. + /// </summary> + private static IEnumerable<SerializationEntry> GetEntries(SerializationInfo serInfo) + { + foreach (var entry in serInfo) + { + yield return entry; + } + } + + /// <summary> + /// Reads the serialization information. + /// </summary> + private static SerializationInfo ReadSerializationInfo(BinaryReader reader, + IEnumerable<string> fieldNames, IBinaryTypeDescriptor desc, ICollection<int> dotNetFields) + { + var serInfo = new SerializationInfo(desc.Type, new FormatterConverter()); + + if (dotNetFields == null) + { + foreach (var fieldName in fieldNames) + { + var fieldVal = reader.ReadObject<object>(fieldName); + + serInfo.AddValue(fieldName, fieldVal); + } + } + else + { + foreach (var fieldName in fieldNames) + { + var fieldVal = ReadField(reader, fieldName, dotNetFields); + + serInfo.AddValue(fieldName, fieldVal); + } + } + + return serInfo; + } + + /// <summary> + /// Reads the object as a custom type. + /// </summary> + private static object ReadAsCustomType(Type customType, SerializationInfo serInfo, StreamingContext ctx) + { + var ctorFunc = SerializableTypeDescriptor.Get(customType).SerializationCtor; + + var customObj = ctorFunc(serInfo, ctx); + + var wrapper = customObj as IObjectReference; + + return wrapper == null + ? customObj + : wrapper.GetRealObject(ctx); + } + + /// <summary> + /// Gets the streaming context. + /// </summary> + private static StreamingContext GetStreamingContext(IBinaryReader reader) + { + return new StreamingContext(StreamingContextStates.All, reader); + } + + /// <summary> + /// Gets the streaming context. + /// </summary> + private static StreamingContext GetStreamingContext(IBinaryWriter writer) + { + return new StreamingContext(StreamingContextStates.All, writer); + } + + /// <summary> + /// Reads the field. + /// <para /> + /// Java side does not have counterparts for byte, ushort, uint, ulong. + /// For such fields we write a special boolean field indicating the type. + /// If special field is present, then the value has to be converted to .NET-specific type. + /// </summary> + private static object ReadField(IBinaryReader reader, string fieldName, ICollection<int> dotNetFields) + { + var fieldVal = reader.ReadObject<object>(fieldName); + + if (fieldVal == null) + return null; + + var fieldType = fieldVal.GetType(); + + unchecked + { + if (fieldType == typeof(byte)) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? (sbyte) (byte) fieldVal : fieldVal; + } + + if (fieldType == typeof(short)) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? (ushort) (short) fieldVal : fieldVal; + } + + if (fieldType == typeof(int)) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? (uint) (int) fieldVal : fieldVal; + } + + if (fieldType == typeof(long)) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? (ulong) (long) fieldVal : fieldVal; + } + + if (fieldType == typeof(byte[])) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? ConvertArray<byte, sbyte>((byte[]) fieldVal) : fieldVal; + } + + if (fieldType == typeof(short[])) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? ConvertArray<short, ushort>((short[]) fieldVal) : fieldVal; + } + + if (fieldType == typeof(int[])) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? ConvertArray<int, uint>((int[]) fieldVal) : fieldVal; + } + + if (fieldType == typeof(long[])) + { + return dotNetFields.Contains(BinaryUtils.GetStringHashCode(fieldName)) + ? ConvertArray<long, ulong>((long[]) fieldVal) : fieldVal; + } + } + + return fieldVal; + } + + /// <summary> + /// Converts the array. + /// </summary> + private static TU[] ConvertArray<T, TU>(T[] arr) + { + var res = new TU[arr.Length]; + + for (var i = 0; i < arr.Length; i++) + { + res[i] = TypeCaster<TU>.Cast(arr[i]); + } + + return res; } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs index 340dac4..36dde4b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs @@ -50,6 +50,13 @@ namespace Apache.Ignite.Core.Impl.Binary { Debug.Assert(!string.IsNullOrEmpty(typeName)); + // Fully-qualified name can be resolved with system mechanism. + var type = Type.GetType(typeName, false); + + if (type != null) + return type; + + // Partial names should be resolved by scanning assemblies. return ResolveType(assemblyName, typeName, AppDomain.CurrentDomain.GetAssemblies()) ?? ResolveTypeInReferencedAssemblies(assemblyName, typeName); } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/UserSerializerProxy.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/UserSerializerProxy.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/UserSerializerProxy.cs index de25e32..b0d393d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/UserSerializerProxy.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/UserSerializerProxy.cs @@ -17,7 +17,6 @@ namespace Apache.Ignite.Core.Impl.Binary { - using System; using System.Diagnostics; using System.Runtime.Serialization; using Apache.Ignite.Core.Binary; @@ -48,9 +47,9 @@ namespace Apache.Ignite.Core.Impl.Binary } /** <inheritdoc /> */ - public T ReadBinary<T>(BinaryReader reader, Type type, int pos) + public T ReadBinary<T>(BinaryReader reader, IBinaryTypeDescriptor desc, int pos) { - var obj = FormatterServices.GetUninitializedObject(type); + var obj = FormatterServices.GetUninitializedObject(desc.Type); reader.AddHandle(pos, obj); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Affinity/AffinityFunctionSerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Affinity/AffinityFunctionSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Affinity/AffinityFunctionSerializer.cs index 5d940c5..73afe38 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Affinity/AffinityFunctionSerializer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Affinity/AffinityFunctionSerializer.cs @@ -255,9 +255,6 @@ namespace Apache.Ignite.Core.Impl.Cache.Affinity return; } - if (func != null && !func.GetType().IsSerializable) - throw new IgniteException("AffinityFunction should be serializable."); - writer.WriteObject(func); } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs index a387e1b..2523cf7 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs @@ -150,7 +150,8 @@ namespace Apache.Ignite.Core.Impl.Cache /** <inheritDoc /> */ public CacheConfiguration GetConfiguration() { - return DoInOp((int) CacheOp.GetConfig, stream => new CacheConfiguration(Marshaller.StartUnmarshal(stream))); + return DoInOp((int) CacheOp.GetConfig, stream => new CacheConfiguration( + BinaryUtils.Marshaller.StartUnmarshal(stream))); } /** <inheritDoc /> */ http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/CopyOnWriteConcurrentDictionary.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/CopyOnWriteConcurrentDictionary.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/CopyOnWriteConcurrentDictionary.cs index 01fc8a9..78cb8b6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/CopyOnWriteConcurrentDictionary.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/CopyOnWriteConcurrentDictionary.cs @@ -15,6 +15,7 @@ * limitations under the License. */ +// ReSharper disable InconsistentlySynchronizedField namespace Apache.Ignite.Core.Impl.Common { using System; @@ -69,5 +70,39 @@ namespace Apache.Ignite.Core.Impl.Common return res; } } + + /// <summary> + /// Sets a value for the key unconditionally. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")] + public void Set(TKey key, TValue value) + { + lock (this) + { + var dict0 = new Dictionary<TKey, TValue>(_dict); + + dict0[key] = value; + + _dict = dict0; + } + } + + /// <summary> + /// Determines whether the specified key exists in the dictionary. + /// </summary> + public bool ContainsKey(TKey key) + { + return _dict.ContainsKey(key); + } + + /// <summary> + /// Gets the values. + /// </summary> + public ICollection<TValue> Values + { + get { return _dict.Values; } + } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs index ff61e28..0407b62 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs @@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Impl.Common using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; + using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; @@ -203,13 +204,16 @@ namespace Apache.Ignite.Core.Impl.Common /// <typeparam name="T">Result func type.</typeparam> /// <param name="ctor">Contructor info.</param> /// <param name="argTypes">Argument types.</param> - /// <param name="convertResultToObject">if set to <c>true</c> [convert result to object]. + /// <param name="convertResultToObject"> /// Flag that indicates whether ctor return value should be converted to object.</param> + /// <param name="convertParamsFromObject"> + /// Flag that indicates whether ctor args are object and should be converted to concrete type.</param> /// <returns> /// Compiled generic constructor. /// </returns> [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")] - public static T CompileCtor<T>(ConstructorInfo ctor, Type[] argTypes, bool convertResultToObject = true) + public static T CompileCtor<T>(ConstructorInfo ctor, Type[] argTypes, bool convertResultToObject = true, + bool convertParamsFromObject = true) { Debug.Assert(ctor != null); @@ -218,9 +222,16 @@ namespace Apache.Ignite.Core.Impl.Common for (var i = 0; i < argTypes.Length; i++) { - var arg = Expression.Parameter(typeof(object)); - args[i] = arg; - argsConverted[i] = Expression.Convert(arg, argTypes[i]); + if (convertParamsFromObject) + { + var arg = Expression.Parameter(typeof(object)); + args[i] = arg; + argsConverted[i] = Expression.Convert(arg, argTypes[i]); + } + else + { + argsConverted[i] = args[i] = Expression.Parameter(argTypes[i]); + } } Expression ctorExpr = Expression.New(ctor, argsConverted); // ctor takes args of specific types @@ -232,6 +243,50 @@ namespace Apache.Ignite.Core.Impl.Common } /// <summary> + /// Compiles a generic ctor with arbitrary number of arguments + /// that takes an uninitialized object as a first arguments. + /// </summary> + /// <typeparam name="T">Result func type.</typeparam> + /// <param name="ctor">Contructor info.</param> + /// <param name="argTypes">Argument types.</param> + /// <returns> + /// Compiled generic constructor. + /// </returns> + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")] + public static T CompileUninitializedObjectCtor<T>(ConstructorInfo ctor, Type[] argTypes) + { + Debug.Assert(ctor != null); + Debug.Assert(ctor.DeclaringType != null); + Debug.Assert(argTypes != null); + + argTypes = new[] {typeof(object)}.Concat(argTypes).ToArray(); + + var helperMethod = new DynamicMethod(string.Empty, typeof(void), argTypes, ctor.Module, true); + var il = helperMethod.GetILGenerator(); + + il.Emit(OpCodes.Ldarg_0); + + if (ctor.DeclaringType.IsValueType) + il.Emit(OpCodes.Unbox, ctor.DeclaringType); // modify boxed copy + + if (argTypes.Length > 1) + il.Emit(OpCodes.Ldarg_1); + + if (argTypes.Length > 2) + il.Emit(OpCodes.Ldarg_2); + + if (argTypes.Length > 3) + throw new NotSupportedException("Not supported: too many ctor args."); + + il.Emit(OpCodes.Call, ctor); + il.Emit(OpCodes.Ret); + + var constructorInvoker = helperMethod.CreateDelegate(typeof(T)); + + return (T) (object) constructorInvoker; + } + + /// <summary> /// Compiles a generic ctor with arbitrary number of arguments. /// </summary> /// <typeparam name="T">Result func type.</typeparam> @@ -440,5 +495,30 @@ namespace Apache.Ignite.Core.Impl.Common return method; } + + /// <summary> + /// Gets the constructor with exactly matching signature. + /// <para /> + /// Type.GetConstructor matches compatible ones (i.e. taking object instead of concrete type). + /// </summary> + /// <param name="type">The type.</param> + /// <param name="types">The argument types.</param> + /// <returns>Constructor info.</returns> + public static ConstructorInfo GetConstructorExact(Type type, Type[] types) + { + Debug.Assert(type != null); + Debug.Assert(types != null); + + foreach (var constructorInfo in type.GetConstructors( + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) + { + var ctorTypes = constructorInfo.GetParameters().Select(x => x.ParameterType); + + if (ctorTypes.SequenceEqual(types)) + return constructorInfo; + } + + return null; + } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateTypeDescriptor.cs index 2e837c4..4cd0678 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateTypeDescriptor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateTypeDescriptor.cs @@ -19,7 +19,6 @@ namespace Apache.Ignite.Core.Impl.Common { using System; using System.Globalization; - using Apache.Ignite.Core.Cache; using Apache.Ignite.Core.Cache.Event; using Apache.Ignite.Core.Compute; @@ -37,7 +36,7 @@ namespace Apache.Ignite.Core.Impl.Common /// </summary> internal class DelegateTypeDescriptor { - /** Cached decriptors. */ + /** Cached descriptors. */ private static readonly CopyOnWriteConcurrentDictionary<Type, DelegateTypeDescriptor> Descriptors = new CopyOnWriteConcurrentDictionary<Type, DelegateTypeDescriptor>(); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/SerializableTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/SerializableTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/SerializableTypeDescriptor.cs new file mode 100644 index 0000000..f16e32a --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/SerializableTypeDescriptor.cs @@ -0,0 +1,222 @@ +/* + * 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.Common +{ + using System; + using System.Diagnostics; + using System.Reflection; + using System.Runtime.Serialization; + + /// <summary> + /// Type descriptor with precompiled delegates to call serialization-related methods. + /// </summary> + internal class SerializableTypeDescriptor + { + /** Cached descriptors. */ + private static readonly CopyOnWriteConcurrentDictionary<Type, SerializableTypeDescriptor> Descriptors + = new CopyOnWriteConcurrentDictionary<Type, SerializableTypeDescriptor>(); + + /** */ + private readonly Type _type; + + /** */ + private readonly Func<SerializationInfo, StreamingContext, object> _serializationCtor; + + /** */ + private readonly Action<object, SerializationInfo, StreamingContext> _serializationCtorUninitialized; + + /** */ + private readonly Action<object, StreamingContext> _onSerializing; + + /** */ + private readonly Action<object, StreamingContext> _onSerialized; + + /** */ + private readonly Action<object, StreamingContext> _onDeserializing; + + /** */ + private readonly Action<object, StreamingContext> _onDeserialized; + + /// <summary> + /// Initializes a new instance of the <see cref="SerializableTypeDescriptor"/> class. + /// </summary> + /// <param name="type">The type.</param> + private SerializableTypeDescriptor(Type type) + { + Debug.Assert(type != null); + + _type = type; + + // Check if there is a serialization ctor. + var argTypes = new[] {typeof(SerializationInfo), typeof(StreamingContext)}; + + var serializationCtorInfo = DelegateConverter.GetConstructorExact(type, argTypes); + + if (serializationCtorInfo != null) + { + _serializationCtor = DelegateConverter.CompileCtor<Func<SerializationInfo, StreamingContext, object>>( + serializationCtorInfo, argTypes, convertParamsFromObject: false); + + _serializationCtorUninitialized = DelegateConverter.CompileUninitializedObjectCtor< + Action<object, SerializationInfo, StreamingContext>>(serializationCtorInfo, argTypes); + } + + // Scan methods for callback attributes. + // Initialize to empty delegates to avoid null checks. + _onSerializing = _onSerialized = _onDeserializing = _onDeserialized = (o, c) => { }; + + var baseType = type; + + while (baseType != typeof(object) && baseType != null) + { + var methods = baseType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance + | BindingFlags.NonPublic | BindingFlags.Public); + + foreach (var method in methods) + { + if (method.IsDefined(typeof(OnSerializingAttribute), false)) + { + _onSerializing += CompileCallbackMethod(method); + } + + if (method.IsDefined(typeof(OnSerializedAttribute), false)) + { + _onSerialized += CompileCallbackMethod(method); + } + + if (method.IsDefined(typeof(OnDeserializingAttribute), false)) + { + _onDeserializing += CompileCallbackMethod(method); + } + + if (method.IsDefined(typeof(OnDeserializedAttribute), false)) + { + _onDeserialized += CompileCallbackMethod(method); + } + } + + baseType = baseType.BaseType; + } + } + + /// <summary> + /// Gets the serialization ctor. + /// </summary> + public Func<SerializationInfo, StreamingContext, object> SerializationCtor + { + get + { + if (_serializationCtor == null) + throw GetMissingCtorException(); + + return _serializationCtor; + } + } + + /// <summary> + /// Gets the serialization ctor to call on an uninitialized instance. + /// </summary> + public Action<object, SerializationInfo, StreamingContext> SerializationCtorUninitialized + { + get + { + if (_serializationCtorUninitialized == null) + throw GetMissingCtorException(); + + return _serializationCtorUninitialized; + } + } + + /// <summary> + /// Gets the OnSerializing callback action. + /// </summary> + public Action<object, StreamingContext> OnSerializing + { + get { return _onSerializing; } + } + + /// <summary> + /// Gets the OnSerialized callback action. + /// </summary> + public Action<object, StreamingContext> OnSerialized + { + get { return _onSerialized; } + } + + /// <summary> + /// Gets the OnDeserializing callback action. + /// </summary> + public Action<object, StreamingContext> OnDeserializing + { + get { return _onDeserializing; } + } + + /// <summary> + /// Gets the OnDeserialized callback action. + /// </summary> + public Action<object, StreamingContext> OnDeserialized + { + get { return _onDeserialized; } + } + + /// <summary> + /// Gets the <see cref="DelegateTypeDescriptor" /> by type. + /// </summary> + public static SerializableTypeDescriptor Get(Type type) + { + SerializableTypeDescriptor result; + + return Descriptors.TryGetValue(type, out result) + ? result + : Descriptors.GetOrAdd(type, t => new SerializableTypeDescriptor(t)); + } + + /// <summary> + /// Gets the missing ctor exception. + /// </summary> + private SerializationException GetMissingCtorException() + { + // Same exception as .NET code throws. + return new SerializationException( + string.Format("The constructor to deserialize an object of type '{0}' was not found.", _type)); + } + + /// <summary> + /// Checks that callback method has signature "void (StreamingContext)" and compiles it. + /// </summary> + private static Action<object, StreamingContext> CompileCallbackMethod(MethodInfo method) + { + Debug.Assert(method != null); + Debug.Assert(method.DeclaringType != null); + + var parameters = method.GetParameters(); + + if (method.ReturnType != typeof(void) || parameters.Length != 1 || + parameters[0].ParameterType != typeof(StreamingContext)) + { + throw new TypeLoadException( + string.Format("Type '{0}' in assembly '{1}' has method '{2}' with an incorrect " + + "signature for the serialization attribute that it is decorated with.", + method.DeclaringType, method.DeclaringType.Assembly, method.Name)); + } + + return DelegateConverter.CompileFunc<Action<object, StreamingContext>>( + method.DeclaringType, method, new[] {typeof(StreamingContext)}, new[] {false, false}); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs index f79822d..c38cd95 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs @@ -157,7 +157,7 @@ namespace Apache.Ignite.Core.Impl { if (!string.IsNullOrEmpty(_cfg.SpringConfigUrl)) { - // If there is a Spring config, use setting from Spring, + // If there is a Spring config, use setting from Spring, // since we ignore .NET config in legacy mode. var cfg0 = GetConfiguration().BinaryConfiguration; @@ -424,7 +424,7 @@ namespace Apache.Ignite.Core.Impl using (var stream = IgniteManager.Memory.Allocate().GetStream()) { - var writer = Marshaller.StartMarshal(stream); + var writer = BinaryUtils.Marshaller.StartMarshal(stream); configuration.Write(writer); @@ -463,7 +463,8 @@ namespace Apache.Ignite.Core.Impl using (var stream = IgniteManager.Memory.Allocate().GetStream()) { - var writer = Marshaller.StartMarshal(stream); + // Use system marshaller: full footers, always unregistered mode. + var writer = BinaryUtils.Marshaller.StartMarshal(stream); configuration.Write(writer); @@ -639,6 +640,8 @@ namespace Apache.Ignite.Core.Impl writer.Write(initialValue); + Marshaller.FinishMarshal(writer); + var memPtr = stream.SynchronizeOutput(); return UU.ProcessorAtomicReference(_proc, name, memPtr, true); @@ -654,7 +657,7 @@ namespace Apache.Ignite.Core.Impl stream.SynchronizeInput(); - return new IgniteConfiguration(_marsh.StartUnmarshal(stream), _cfg); + return new IgniteConfiguration(BinaryUtils.Marshaller.StartUnmarshal(stream), _cfg); } } @@ -724,7 +727,7 @@ namespace Apache.Ignite.Core.Impl using (var stream = IgniteManager.Memory.Allocate().GetStream()) { - var writer = Marshaller.StartMarshal(stream); + var writer = BinaryUtils.Marshaller.StartMarshal(stream); configuration.Write(writer); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs index 8e44360..2fd020e 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs @@ -118,6 +118,8 @@ namespace Apache.Ignite.Core.Impl.Services var writer = marsh.StartMarshal(stream); BinaryUtils.WriteInvocationResult(writer, invocationError == null, invocationError ?? methodResult); + + marsh.FinishMarshal(writer); } /// <summary> @@ -182,7 +184,7 @@ namespace Apache.Ignite.Core.Impl.Services var handler = BinarySystemHandlers.GetWriteHandler(type); - if (handler != null && !handler.IsSerializable) + if (handler != null) return null; if (type.IsArray) http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs index 91ffabb..3028f08 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs @@ -376,7 +376,11 @@ namespace Apache.Ignite.Core.Impl.Unmanaged { stream.Reset(); - _ignite.Marshaller.StartMarshal(stream).WriteObject(e); + var writer = _ignite.Marshaller.StartMarshal(stream); + + writer.WriteObject(e); + + _ignite.Marshaller.FinishMarshal(writer); return -1; } @@ -1164,7 +1168,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged { using (var stream = IgniteManager.Memory.Get(memPtr).GetStream()) { - var reader = _ignite.Marshaller.StartUnmarshal(stream); + var reader = BinaryUtils.Marshaller.StartUnmarshal(stream); var func = reader.ReadObjectEx<IAffinityFunction>(); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/ComputeExample.linq ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/ComputeExample.linq b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/ComputeExample.linq index 2ed0493..6886ddb 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/ComputeExample.linq +++ b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/ComputeExample.linq @@ -57,7 +57,6 @@ void Main() /// <summary> /// Closure counting characters in a string. /// </summary> -[Serializable] public class CharacterCountClosure : IComputeFunc<string, int> { /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/PutGetExample.linq ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/PutGetExample.linq b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/PutGetExample.linq index 7c77d09..ea396da 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/PutGetExample.linq +++ b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/PutGetExample.linq @@ -35,11 +35,8 @@ void Main() // Force new LINQPad query process to reinit JVM Util.NewProcess = true; - // Configure cacheable types - var cfg = new IgniteConfiguration {BinaryConfiguration = new BinaryConfiguration(typeof(Organization))}; - // Start instance - using (var ignite = Ignition.Start(cfg)) + using (var ignite = Ignition.Start()) { // Create new cache var cache = ignite.GetOrCreateCache<int, Organization>("orgs"); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq index 2a2454e..8a7dd10 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq +++ b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq @@ -38,11 +38,8 @@ void Main() // Force new LINQPad query process to reinit JVM Util.NewProcess = true; - // Configure cacheable types - var cfg = new IgniteConfiguration { BinaryConfiguration = new BinaryConfiguration(typeof(Organization), typeof(Person)) }; - // Start instance - using (var ignite = Ignition.Start(cfg)) + using (var ignite = Ignition.Start()) { // Create and populate organization cache var orgs = ignite.GetOrCreateCache<int, Organization>(new CacheConfiguration("orgs-sql", http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Linq/NuGet/LINQPad/QueryExample.linq ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/NuGet/LINQPad/QueryExample.linq b/modules/platforms/dotnet/Apache.Ignite.Linq/NuGet/LINQPad/QueryExample.linq index 6a28f1f..fb44b12 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Linq/NuGet/LINQPad/QueryExample.linq +++ b/modules/platforms/dotnet/Apache.Ignite.Linq/NuGet/LINQPad/QueryExample.linq @@ -39,11 +39,8 @@ void Main() // Force new LINQPad query process to reinit JVM Util.NewProcess = true; - // Configure cacheable types - var cfg = new IgniteConfiguration { BinaryConfiguration = new BinaryConfiguration(typeof(Organization), typeof(Person)) }; - // Start instance - using (var ignite = Ignition.Start(cfg)) + using (var ignite = Ignition.Start()) { // Create and populate organization cache var orgs = ignite.GetOrCreateCache<int, Organization>(new CacheConfiguration("orgs-linq", http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/examples/Apache.Ignite.Examples/App.config ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/App.config b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/App.config index 13f0d86..e3bc79d 100644 --- a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/App.config +++ b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/App.config @@ -27,22 +27,8 @@ </runtime> <igniteConfiguration xmlns="http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection"> - <binaryConfiguration> - <typeConfigurations> - <binaryTypeConfiguration typeName="Apache.Ignite.ExamplesDll.Binary.OrganizationType" isEnum="true" /> - </typeConfigurations> - <types> - <string>Apache.Ignite.ExamplesDll.Binary.Account</string> - <string>Apache.Ignite.ExamplesDll.Binary.Address</string> - <string>Apache.Ignite.ExamplesDll.Binary.Employee</string> - <string>Apache.Ignite.ExamplesDll.Binary.EmployeeKey</string> - <string>Apache.Ignite.ExamplesDll.Binary.Organization</string> - <string>Apache.Ignite.ExamplesDll.Compute.AverageSalaryJob</string> - </types> - </binaryConfiguration> - <atomicConfiguration atomicSequenceReserveSize="10" /> - + <discoverySpi type="TcpDiscoverySpi"> <ipFinder type="TcpDiscoveryMulticastIpFinder"> <endpoints>
