Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 4D3BE200C48 for ; Thu, 6 Apr 2017 15:31:19 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 4C031160B83; Thu, 6 Apr 2017 13:31:19 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id C0B3D160BAC for ; Thu, 6 Apr 2017 15:31:13 +0200 (CEST) Received: (qmail 95632 invoked by uid 500); 6 Apr 2017 13:31:13 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 94825 invoked by uid 99); 6 Apr 2017 13:31:10 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Apr 2017 13:31:10 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 3149CE9690; Thu, 6 Apr 2017 13:31:09 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: sboikov@apache.org To: commits@ignite.apache.org Date: Thu, 06 Apr 2017 13:31:20 -0000 Message-Id: <17bb2b9491f14bb98077c1e2b04e4e08@git.apache.org> In-Reply-To: <358816612602444bb6656810c8375230@git.apache.org> References: <358816612602444bb6656810c8375230@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [13/50] [abbrv] ignite git commit: IGNITE-2703 .NET: Dynamic type registration archived-at: Thu, 06 Apr 2017 13:31:19 -0000 http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs index 19e68a6..56a17a3 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs @@ -131,7 +131,7 @@ namespace Apache.Ignite.Core.Tests.Examples var proc = new IgniteProcess(args.ToArray()); - Assert.IsTrue(ignite.WaitTopology(2), + Assert.IsTrue(ignite.WaitTopology(2), string.Format("Standalone node failed to join topology: [{0}]", proc.GetInfo())); Assert.IsTrue(proc.Alive, string.Format("Standalone node stopped unexpectedly: [{0}]", http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs index 636e0fe..0aebd78 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs @@ -49,28 +49,6 @@ namespace Apache.Ignite.Core.Tests private IIgnite _grid; /// - /// Test fixture set-up routine. - /// - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - TestUtils.KillProcesses(); - - _grid = Ignition.Start(Configuration(SpringCfgPath)); - } - - /// - /// Test fixture tear-down routine. - /// - [TestFixtureTearDown] - public void TestFixtureTearDown() - { - Ignition.StopAll(true); - - TestUtils.KillProcesses(); - } - - /// /// Set-up routine. /// [SetUp] @@ -78,6 +56,8 @@ namespace Apache.Ignite.Core.Tests { TestUtils.KillProcesses(); + _grid = Ignition.Start(Configuration(SpringCfgPath)); + Assert.IsTrue(_grid.WaitTopology(1)); IgniteProcess.SaveConfigurationBackup(); @@ -89,6 +69,10 @@ namespace Apache.Ignite.Core.Tests [TearDown] public void TearDown() { + Ignition.StopAll(true); + + TestUtils.KillProcesses(); + IgniteProcess.RestoreConfigurationBackup(); } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/SerializationTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/SerializationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/SerializationTest.cs deleted file mode 100644 index 2812468..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/SerializationTest.cs +++ /dev/null @@ -1,240 +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.Tests -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - using System.Reflection.Emit; - using System.Runtime.Serialization; - using System.Xml; - using Apache.Ignite.Core.Cluster; - using Apache.Ignite.Core.Compute; - using Apache.Ignite.Core.Impl; - using NUnit.Framework; - - /// - /// Tests for native serialization. - /// - public class SerializationTest - { - /** Grid name. */ - private const string GridName = "SerializationTest"; - - /// - /// Set up routine. - /// - [TestFixtureSetUp] - public void SetUp() - { - var cfg = new IgniteConfiguration - { - IgniteInstanceName = GridName, - JvmClasspath = TestUtils.CreateTestClasspath(), - JvmOptions = TestUtils.TestJavaOptions(), - SpringConfigUrl = "config\\native-client-test-cache.xml" - }; - - Ignition.Start(cfg); - } - - /// - /// Tear down routine. - /// - [TestFixtureTearDown] - public void TearDown() - { - Ignition.StopAll(true); - } - - /// - /// Test complex file serialization. - /// - [Test] - public void TestSerializableXmlDoc() - { - var grid = Ignition.GetIgnite(GridName); - var cache = grid.GetCache("replicated"); - - var doc = new SerializableXmlDoc(); - - doc.LoadXml("val"); - - for (var i = 0; i < 50; i++) - { - // Test cache - cache.Put(i, doc); - - var resultDoc = cache.Get(i); - - Assert.AreEqual(doc.OuterXml, resultDoc.OuterXml); - - // Test task with document arg - CheckTask(grid, doc); - } - } - - /// - /// Checks task execution. - /// - /// Grid. - /// Task arg. - private static void CheckTask(IIgnite grid, object arg) - { - var jobResult = grid.GetCompute().Execute(new CombineStringsTask(), arg); - - var nodeCount = grid.GetCluster().GetNodes().Count; - - var expectedRes = - CombineStringsTask.CombineStrings(Enumerable.Range(0, nodeCount).Select(x => arg.ToString())); - - Assert.AreEqual(expectedRes, jobResult.InnerXml); - } - - /// - /// Tests custom serialization binder. - /// - [Test] - public void TestSerializationBinder() - { - const int count = 50; - - var cache = Ignition.GetIgnite(GridName).GetCache("local"); - - // Put multiple objects from muliple same-named assemblies to cache - for (var i = 0; i < count; i++) - { - dynamic val = Activator.CreateInstance(GenerateDynamicType()); - - val.Id = i; - val.Name = "Name_" + i; - - cache.Put(i, val); - } - - // Verify correct deserialization - for (var i = 0; i < count; i++) - { - dynamic val = cache.Get(i); - - Assert.AreEqual(val.Id, i); - Assert.AreEqual(val.Name, "Name_" + i); - } - } - - /// - /// Generates a Type in runtime, puts it into a dynamic assembly. - /// - /// - public static Type GenerateDynamicType() - { - var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( - new AssemblyName("GridSerializationTestDynamicAssembly"), AssemblyBuilderAccess.Run); - - var moduleBuilder = asmBuilder.DefineDynamicModule("GridSerializationTestDynamicModule"); - - var typeBuilder = moduleBuilder.DefineType("GridSerializationTestDynamicType", - TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Serializable); - - typeBuilder.DefineField("Id", typeof (int), FieldAttributes.Public); - - typeBuilder.DefineField("Name", typeof (string), FieldAttributes.Public); - - return typeBuilder.CreateType(); - } - } - - [Serializable] - [DataContract] - public sealed class SerializableXmlDoc : XmlDocument, ISerializable - { - /// - /// Default ctor. - /// - public SerializableXmlDoc() - { - // No-op - } - - /// - /// Serialization ctor. - /// - private SerializableXmlDoc(SerializationInfo info, StreamingContext context) - { - LoadXml(info.GetString("xmlDocument")); - } - - /** */ - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("xmlDocument", OuterXml, typeof(string)); - } - } - - [Serializable] - public class CombineStringsTask : IComputeTask - { - public IDictionary, IClusterNode> Map(IList subgrid, object arg) - { - return subgrid.ToDictionary(x => (IComputeJob) new ToStringJob {Arg = arg}, x => x); - } - - public ComputeJobResultPolicy OnResult(IComputeJobResult res, IList> rcvd) - { - return ComputeJobResultPolicy.Wait; - } - - public SerializableXmlDoc Reduce(IList> results) - { - var result = new SerializableXmlDoc(); - - result.LoadXml(CombineStrings(results.Select(x => x.Data))); - - return result; - } - - public static string CombineStrings(IEnumerable strings) - { - var text = string.Concat(strings.Select(x => string.Format("{0}", x))); - - return string.Format("{0}", text); - } - } - - [Serializable] - public class ToStringJob : IComputeJob - { - /// - /// Job argument. - /// - public object Arg { get; set; } - - /** */ - public string Execute() - { - return Arg.ToString(); - } - - /** */ - public void Cancel() - { - // No-op. - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs index dcb5393..eb6192d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs @@ -110,8 +110,13 @@ namespace Apache.Ignite.Core.Tests.Services Assert.IsNull(_svc.ObjProp); prx.ObjProp = new TestClass {Prop = "prop2"}; - Assert.AreEqual("prop2", ((TestClass)prx.ObjProp).Prop); - Assert.AreEqual("prop2", ((TestClass)_svc.ObjProp).Prop); + + var propVal = KeepBinary + ? ((IBinaryObject) prx.ObjProp).Deserialize().Prop + : ((TestClass) prx.ObjProp).Prop; + + Assert.AreEqual("prop2", propVal); + Assert.AreEqual("prop2", ((TestClass) _svc.ObjProp).Prop); } /// @@ -191,10 +196,19 @@ namespace Apache.Ignite.Core.Tests.Services var prx = GetProxy(); var err = Assert.Throws(prx.ExceptionMethod); - Assert.AreEqual("Expected exception", err.InnerException.Message); - var ex = Assert.Throws(() => prx.CustomExceptionMethod()); - Assert.IsTrue(ex.ToString().Contains("+CustomException")); + if (KeepBinary) + { + Assert.IsNotNull(err.BinaryCause); + Assert.AreEqual("Expected exception", err.BinaryCause.Deserialize().Message); + } + else + { + Assert.IsNotNull(err.InnerException); + Assert.AreEqual("Expected exception", err.InnerException.Message); + } + + Assert.Throws(() => prx.CustomExceptionMethod()); } [Test] @@ -243,7 +257,7 @@ namespace Apache.Ignite.Core.Tests.Services /// /// Creates the proxy. /// - protected T GetProxy() + private T GetProxy() { _svc = new TestIgniteService(Binary); @@ -591,9 +605,19 @@ namespace Apache.Ignite.Core.Tests.Services /// /// Custom non-serializable exception. /// - private class CustomException : Exception + private class CustomException : Exception, IBinarizable { - + /** */ + public void WriteBinary(IBinaryWriter writer) + { + throw new BinaryObjectException("Expected"); + } + + /** */ + public void ReadBinary(IBinaryReader reader) + { + throw new BinaryObjectException("Expected"); + } } /// http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs index 8360bf1..0bb3b7f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs @@ -27,6 +27,7 @@ namespace Apache.Ignite.Core.Tests using Apache.Ignite.Core.Discovery.Tcp; using Apache.Ignite.Core.Discovery.Tcp.Static; using Apache.Ignite.Core.Impl; + using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Tests.Process; using NUnit.Framework; @@ -370,5 +371,15 @@ namespace Apache.Ignite.Core.Tests Assert.IsTrue(proc.WaitForExit(15000)); Assert.AreEqual(0, proc.ExitCode); } + + /// + /// Serializes and deserializes back an object. + /// + public static T SerializeDeserialize(T obj) + { + var marsh = new Marshaller(null) {CompactFooter = false}; + + return marsh.Unmarshal(marsh.Marshal(obj)); + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index 333b9bc..2a174eb 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -186,11 +186,12 @@ - + + @@ -319,6 +320,7 @@ + @@ -385,11 +387,9 @@ - - @@ -419,7 +419,6 @@ - http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs index 29d2ee3..4f48ea5 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs @@ -235,6 +235,9 @@ namespace Apache.Ignite.Core.Cache.Configuration /// The reader. internal CacheConfiguration(IBinaryRawReader reader) { + // Make sure system marshaller is used. + Debug.Assert(((BinaryReader) reader).Marshaller == BinaryUtils.Marshaller); + AtomicityMode = (CacheAtomicityMode) reader.ReadInt(); AtomicWriteOrderMode = (CacheAtomicWriteOrderMode) reader.ReadInt(); Backups = reader.ReadInt(); @@ -297,6 +300,9 @@ namespace Apache.Ignite.Core.Cache.Configuration /// The writer. internal void Write(IBinaryRawWriter writer) { + // Make sure system marshaller is used. + Debug.Assert(((BinaryWriter) writer).Marshaller == BinaryUtils.Marshaller); + writer.WriteInt((int) AtomicityMode); writer.WriteInt((int) AtomicWriteOrderMode); writer.WriteInt(Backups); @@ -740,7 +746,7 @@ namespace Apache.Ignite.Core.Cache.Configuration public IAffinityFunction AffinityFunction { get; set; } /// - /// Gets or sets the factory for to be used for all cache operations, + /// Gets or sets the factory for to be used for all cache operations, /// unless is called. /// /// Default is null, which means no expiration. http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs index d3bd50c..28842e9 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs @@ -159,7 +159,7 @@ using (var stream = IgniteManager.Memory.Allocate().GetStream()) { - var marsh = new Marshaller(configuration.BinaryConfiguration); + var marsh = BinaryUtils.Marshaller; configuration.Write(marsh.StartMarshal(stream)); @@ -276,15 +276,26 @@ // Send only descriptors with non-null EqualityComparer to preserve old behavior where // remote nodes can have no BinaryConfiguration. - var types = writer.Marshaller.GetUserTypeDescriptors().Where(x => x.EqualityComparer != null).ToList(); - writer.WriteInt(types.Count); + if (BinaryConfiguration.TypeConfigurations != null && + BinaryConfiguration.TypeConfigurations.Any(x => x.EqualityComparer != null)) + { + // Create a new marshaller to reuse type name resolver mechanism. + var types = new Marshaller(BinaryConfiguration).GetUserTypeDescriptors() + .Where(x => x.EqualityComparer != null).ToList(); + + writer.WriteInt(types.Count); - foreach (var type in types) + foreach (var type in types) + { + writer.WriteString(BinaryUtils.SimpleTypeName(type.TypeName)); + writer.WriteBoolean(type.IsEnum); + BinaryEqualityComparerSerializer.Write(writer, type.EqualityComparer); + } + } + else { - writer.WriteString(BinaryUtils.SimpleTypeName(type.TypeName)); - writer.WriteBoolean(type.IsEnum); - BinaryEqualityComparerSerializer.Write(writer, type.EqualityComparer); + writer.WriteInt(0); } } else http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs index 1190c14..f590794 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs @@ -359,11 +359,11 @@ namespace Apache.Ignite.Core if (cfg.BinaryConfiguration == null) cfg.BinaryConfiguration = binaryCfg; - _startup.Marshaller = new Marshaller(cfg.BinaryConfiguration); + _startup.Marshaller = new Marshaller(cfg.BinaryConfiguration, log); // 3. Send configuration details to Java cfg.Validate(log); - cfg.Write(_startup.Marshaller.StartMarshal(outStream)); + cfg.Write(BinaryUtils.Marshaller.StartMarshal(outStream)); // Use system marshaller. } /// http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs index dcb261f..2273a93 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs @@ -17,7 +17,6 @@ namespace Apache.Ignite.Core.Impl.Binary { - using System; using System.Runtime.Serialization; using Apache.Ignite.Core.Binary; @@ -39,9 +38,9 @@ namespace Apache.Ignite.Core.Impl.Binary } /** */ - public T ReadBinary(BinaryReader reader, Type type, int pos) + public T ReadBinary(BinaryReader reader, IBinaryTypeDescriptor desc, int pos) { - var obj = (T) FormatterServices.GetUninitializedObject(type); + var obj = (T) 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/Binary/BinaryFullTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs index d88e7a9..6a911ad 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs @@ -62,7 +62,7 @@ namespace Apache.Ignite.Core.Impl.Binary private volatile BinaryStructure _readerTypeStructure = BinaryStructure.CreateEmpty(); /** Type schema. */ - private readonly BinaryObjectSchema _schema = new BinaryObjectSchema(); + private readonly BinaryObjectSchema _schema; /** Enum flag. */ private readonly bool _isEnum; @@ -70,6 +70,9 @@ namespace Apache.Ignite.Core.Impl.Binary /** Comparer. */ private readonly IBinaryEqualityComparer _equalityComparer; + /** Register flag. */ + private readonly bool _isRegistered; + /// /// Constructor. /// @@ -84,6 +87,7 @@ namespace Apache.Ignite.Core.Impl.Binary /// Affinity field key name. /// Enum flag. /// Equality comparer. + /// Registered flag. public BinaryFullTypeDescriptor( Type type, int typeId, @@ -94,8 +98,9 @@ namespace Apache.Ignite.Core.Impl.Binary IBinarySerializerInternal serializer, bool keepDeserialized, string affKeyFieldName, - bool isEnum, - IEqualityComparer comparer) + bool isEnum, + IEqualityComparer comparer, + bool isRegistered = true) { _type = type; _typeId = typeId; @@ -114,6 +119,38 @@ namespace Apache.Ignite.Core.Impl.Binary throw new IgniteException(string.Format("Unsupported IEqualityComparer " + "implementation: {0}. Only predefined implementations " + "are supported.", comparer.GetType())); + + _isRegistered = isRegistered; + _schema = new BinaryObjectSchema(); + } + + /// + /// Initializes a new instance of the class, + /// copying values from specified descriptor. + /// + /// The descriptor to copy from. + /// Type. + /// Serializer. + /// Registered flag. + public BinaryFullTypeDescriptor(BinaryFullTypeDescriptor desc, Type type, + IBinarySerializerInternal serializer, bool isRegistered) + { + _type = type; + _typeId = desc._typeId; + _typeName = desc._typeName; + _userType = desc._userType; + _nameMapper = desc._nameMapper; + _idMapper = desc._idMapper; + _serializer = serializer; + _keepDeserialized = desc._keepDeserialized; + _affKeyFieldName = desc._affKeyFieldName; + _isEnum = desc._isEnum; + _equalityComparer = desc._equalityComparer; + _isRegistered = isRegistered; + + _schema = desc._schema; + _writerTypeStruct = desc._writerTypeStruct; + _readerTypeStructure = desc._readerTypeStructure; } /// @@ -237,5 +274,11 @@ namespace Apache.Ignite.Core.Impl.Binary { get { return _schema; } } + + /** */ + public bool IsRegistered + { + get { return _isRegistered; } + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs index e77cbae..e4fb10a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs @@ -676,6 +676,9 @@ namespace Apache.Ignite.Core.Impl.Binary ? BinaryObjectHeader.Flag.UserType : BinaryObjectHeader.Flag.None; + if (inHeader.IsCustomDotNetType) + flags |= BinaryObjectHeader.Flag.CustomDotNetType; + // Write raw data. int outRawOff = outStream.Position - outStartPos; @@ -936,8 +939,6 @@ namespace Apache.Ignite.Core.Impl.Binary case BinaryUtils.TypeArrayString: case BinaryUtils.TypeArrayGuid: case BinaryUtils.TypeArrayTimestamp: - case BinaryUtils.TypeArrayEnum: - case BinaryUtils.TypeArray: int arrLen = inStream.ReadInt(); outStream.WriteInt(arrLen); @@ -947,6 +948,28 @@ namespace Apache.Ignite.Core.Impl.Binary break; + case BinaryUtils.TypeArrayEnum: + case BinaryUtils.TypeArray: + int type = inStream.ReadInt(); + + outStream.WriteInt(type); + + if (type == BinaryUtils.TypeUnregistered) + { + outStream.WriteByte(inStream.ReadByte()); // String header. + + BinaryUtils.WriteString(BinaryUtils.ReadString(inStream), outStream); // String data. + } + + arrLen = inStream.ReadInt(); + + outStream.WriteInt(arrLen); + + for (int i = 0; i < arrLen; i++) + Mutate0(ctx, inStream, outStream, false, EmptyVals); + + break; + case BinaryUtils.TypeCollection: int colLen = inStream.ReadInt(); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs index 636b177..0f0fafe 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs @@ -58,7 +58,10 @@ namespace Apache.Ignite.Core.Impl.Binary OffsetTwoBytes = 0x10, /** Flag: compact footer, no field IDs. */ - CompactFooter = 0x20 + CompactFooter = 0x20, + + /** Flag: raw data contains .NET type information. */ + CustomDotNetType = 0x40 } /** Actual header layout */ @@ -164,6 +167,14 @@ namespace Apache.Ignite.Core.Impl.Binary } /// + /// Gets the custom .NET type flag. + /// + public bool IsCustomDotNetType + { + get { return (Flags & Flag.CustomDotNetType) == Flag.CustomDotNetType; } + } + + /// /// Gets the size of the schema field offset (1, 2 or 4 bytes). /// public int SchemaFieldOffsetSize http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectSchemaSerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectSchemaSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectSchemaSerializer.cs index f1d2f6a..e2f9ea7 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectSchemaSerializer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectSchemaSerializer.cs @@ -249,6 +249,8 @@ namespace Apache.Ignite.Core.Impl.Binary if (fieldIds == null) { + Debug.Assert(hdr.TypeId != BinaryUtils.TypeUnregistered); + if (marsh.Ignite != null) fieldIds = marsh.Ignite.BinaryProcessor.GetSchema(hdr.TypeId, hdr.SchemaId); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs index f5bc370..555a042 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs @@ -17,6 +17,7 @@ namespace Apache.Ignite.Core.Impl.Binary { + using System; using System.Collections.Generic; using System.Diagnostics; using Apache.Ignite.Core.Binary; @@ -36,7 +37,9 @@ namespace Apache.Ignite.Core.Impl.Binary GetMeta = 1, GetAllMeta = 2, PutMeta = 3, - GetSchema = 4 + GetSchema = 4, + RegisterType = 5, + GetType = 6 } /// @@ -101,7 +104,7 @@ namespace Apache.Ignite.Core.Impl.Binary /// Put binary types to Grid. /// /// Binary types. - internal void PutBinaryTypes(ICollection types) + public void PutBinaryTypes(ICollection types) { DoOutOp((int) Op.PutMeta, w => { @@ -153,5 +156,36 @@ namespace Apache.Ignite.Core.Impl.Binary Marshaller.OnBinaryTypesSent(types); } + + /// + /// Registers the type. + /// + /// The identifier. + /// The type. + /// True if registration succeeded; otherwise, false. + public bool RegisterType(int id, Type type) + { + Debug.Assert(type != null); + Debug.Assert(id != BinaryUtils.TypeUnregistered); + + return DoOutOp((int) Op.RegisterType, w => + { + w.WriteInt(id); + w.WriteString(type.AssemblyQualifiedName); + }) == True; + } + + /// + /// Gets the type by id. + /// + /// The identifier. + /// Type or null. + public Type GetType(int id) + { + var typeName = DoOutInOp((int) Op.GetType, w => w.WriteInt(id), + r => Marshaller.StartUnmarshal(r).ReadString()); + + return new TypeResolver().ResolveType(typeName); + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs index 092eb72..49bab77 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs @@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.Impl.Binary using System; using System.Collections; using System.Collections.Generic; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using Apache.Ignite.Core.Binary; @@ -79,6 +80,14 @@ namespace Apache.Ignite.Core.Impl.Binary get { return _marsh; } } + /// + /// Gets the mode. + /// + public BinaryMode Mode + { + get { return _mode; } + } + /** */ public IBinaryRawReader GetRawReader() { @@ -572,6 +581,14 @@ namespace Apache.Ignite.Core.Impl.Binary throw new BinaryObjectException("Invalid header on deserialization [pos=" + pos + ", hdr=" + hdr + ']'); } + + /// + /// Gets the flag indicating that there is custom type information in raw region. + /// + public bool GetCustomTypeDataFlag() + { + return _frame.Hdr.IsCustomDotNetType; + } /// /// Reads the binary object. @@ -676,7 +693,9 @@ namespace Apache.Ignite.Core.Impl.Binary else { // Find descriptor. - var desc = _marsh.GetDescriptor(hdr.IsUserType, hdr.TypeId); + var desc = hdr.TypeId == BinaryUtils.TypeUnregistered + ? _marsh.GetDescriptor(Type.GetType(ReadString(), true)) + : _marsh.GetDescriptor(hdr.IsUserType, hdr.TypeId, true); // Instantiate object. if (desc.Type == null) @@ -707,7 +726,7 @@ namespace Apache.Ignite.Core.Impl.Binary _frame.Raw = false; // Read object. - var obj = desc.Serializer.ReadBinary(this, desc.Type, pos); + var obj = desc.Serializer.ReadBinary(this, desc, pos); _frame.Struct.UpdateReaderStructure(); @@ -758,8 +777,10 @@ namespace Apache.Ignite.Core.Impl.Binary // Get schema from Java var ignite = Marshaller.Ignite; - var schema = ignite == null - ? null + Debug.Assert(typeId != BinaryUtils.TypeUnregistered); + + var schema = ignite == null + ? null : ignite.BinaryProcessor.GetSchema(_frame.Hdr.TypeId, _frame.Hdr.SchemaId); if (schema == null) @@ -850,6 +871,14 @@ namespace Apache.Ignite.Core.Impl.Binary } /// + /// Seeks to raw data. + /// + internal void SeekToRaw() + { + Stream.Seek(_frame.Pos + _frame.Hdr.GetRawOffset(Stream, _frame.Pos), SeekOrigin.Begin); + } + + /// /// Mark current output as raw. /// private void MarkRaw() @@ -858,7 +887,7 @@ namespace Apache.Ignite.Core.Impl.Binary { _frame.Raw = true; - Stream.Seek(_frame.Pos + _frame.Hdr.GetRawOffset(Stream, _frame.Pos), SeekOrigin.Begin); + SeekToRaw(); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs index 795f8ac..907b465 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs @@ -722,7 +722,7 @@ namespace Apache.Ignite.Core.Impl.Binary // Assign field value var targetParam = Expression.Parameter(typeof(object)); - var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); + var targetParamConverted = Expression.Convert(targetParam, typeof(object)); var assignExpr = Expression.Call(DelegateConverter.GetWriteFieldMethod(field), targetParamConverted, readExpr); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs index c9fd3cc..e160559 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs @@ -20,19 +20,17 @@ namespace Apache.Ignite.Core.Impl.Binary using System; using System.Collections.Generic; using System.Diagnostics; + using System.Linq; using System.Reflection; using System.Runtime.Serialization; using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Impl.Common; /// /// Internal reflective serializer. /// internal sealed class BinaryReflectiveSerializerInternal : IBinarySerializerInternal { - /** Cached binding flags. */ - private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | - BindingFlags.NonPublic | BindingFlags.DeclaredOnly; - /** Raw mode flag. */ private readonly bool _rawMode; @@ -42,6 +40,9 @@ namespace Apache.Ignite.Core.Impl.Binary /** Read actions to be performed. */ private readonly BinaryReflectiveReadAction[] _rActions; + /** Callback type descriptor. */ + private readonly SerializableTypeDescriptor _serializableDescriptor; + /// /// Initializes a new instance of the class. /// @@ -53,36 +54,64 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Initializes a new instance of the class. /// - private BinaryReflectiveSerializerInternal(BinaryReflectiveWriteAction[] wActions, BinaryReflectiveReadAction[] rActions, bool raw) + private BinaryReflectiveSerializerInternal(BinaryReflectiveWriteAction[] wActions, + BinaryReflectiveReadAction[] rActions, bool raw, SerializableTypeDescriptor serializableDescriptor) { Debug.Assert(wActions != null); Debug.Assert(rActions != null); + Debug.Assert(serializableDescriptor != null); _wActions = wActions; _rActions = rActions; _rawMode = raw; + _serializableDescriptor = serializableDescriptor; } /** */ void IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) { Debug.Assert(_wActions != null); + Debug.Assert(writer != null); + + var ctx = GetStreamingContext(writer); + + _serializableDescriptor.OnSerializing(obj, ctx); foreach (var action in _wActions) action(obj, writer); + + _serializableDescriptor.OnSerialized(obj, ctx); } /** */ - T IBinarySerializerInternal.ReadBinary(BinaryReader reader, Type type, int pos) + T IBinarySerializerInternal.ReadBinary(BinaryReader reader, IBinaryTypeDescriptor desc, int pos) { Debug.Assert(_rActions != null); + Debug.Assert(reader != null); + Debug.Assert(desc != null); + + var obj = FormatterServices.GetUninitializedObject(desc.Type); + + var ctx = GetStreamingContext(reader); + + _serializableDescriptor.OnDeserializing(obj, ctx); - var obj = FormatterServices.GetUninitializedObject(type); + DeserializationCallbackProcessor.Push(obj); - reader.AddHandle(pos, obj); + try + { + reader.AddHandle(pos, obj); + + foreach (var action in _rActions) + action(obj, reader); - foreach (var action in _rActions) - action(obj, reader); + _serializableDescriptor.OnDeserialized(obj, ctx); + + } + finally + { + DeserializationCallbackProcessor.Pop(); + } return (T) obj; } @@ -103,20 +132,7 @@ namespace Apache.Ignite.Core.Impl.Binary { Debug.Assert(_wActions == null && _rActions == null); - List fields = new List(); - - Type curType = type; - - while (curType != null) - { - foreach (FieldInfo field in curType.GetFields(Flags)) - { - if (!field.IsNotSerialized) - fields.Add(field); - } - - curType = curType.BaseType; - } + var fields = ReflectionUtils.GetAllFields(type).Where(x => !x.IsNotSerialized).ToList(); IDictionary idMap = new Dictionary(); @@ -152,7 +168,9 @@ namespace Apache.Ignite.Core.Impl.Binary rActions[i] = readAction; } - return new BinaryReflectiveSerializerInternal(wActions, rActions, _rawMode); + var serDesc = SerializableTypeDescriptor.Get(type); + + return new BinaryReflectiveSerializerInternal(wActions, rActions, _rawMode, serDesc); } /// @@ -165,5 +183,21 @@ namespace Apache.Ignite.Core.Impl.Binary return string.Compare(name1, name2, StringComparison.OrdinalIgnoreCase); } + + /// + /// Gets the streaming context. + /// + private static StreamingContext GetStreamingContext(IBinaryReader reader) + { + return new StreamingContext(StreamingContextStates.All, reader); + } + + /// + /// Gets the streaming context. + /// + private static StreamingContext GetStreamingContext(IBinaryWriter writer) + { + return new StreamingContext(StreamingContextStates.All, writer); + } } } \ 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/BinarySurrogateTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs index adba577..8c7e5e9 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs @@ -19,6 +19,7 @@ namespace Apache.Ignite.Core.Impl.Binary { using System; using System.Collections.Generic; + using System.Diagnostics; using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Impl.Binary.Structure; @@ -51,10 +52,14 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Configuration. /// Type ID. - public BinarySurrogateTypeDescriptor(BinaryConfiguration cfg, int id) + /// Name of the type. + public BinarySurrogateTypeDescriptor(BinaryConfiguration cfg, int id, string typeName) { + Debug.Assert(cfg != null); + _cfg = cfg; _id = id; + _name = typeName; } /// @@ -170,5 +175,11 @@ namespace Apache.Ignite.Core.Impl.Binary { get { return _schema; } } + + /** */ + public bool IsRegistered + { + get { return false; } + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs index beb2668..60bbb46 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs @@ -22,7 +22,6 @@ namespace Apache.Ignite.Core.Impl.Binary using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; - using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Impl.Binary.IO; using Apache.Ignite.Core.Impl.Common; @@ -169,8 +168,7 @@ namespace Apache.Ignite.Core.Impl.Binary var handler = FindWriteHandler(t, out supportsHandles); - return handler == null ? null : new BinarySystemWriteHandler(handler, supportsHandles, - handler == WriteSerializable); + return handler == null ? null : new BinarySystemWriteHandler(handler, supportsHandles); }); } @@ -191,8 +189,6 @@ namespace Apache.Ignite.Core.Impl.Binary return WriteString; if (type == typeof(decimal)) return WriteDecimal; - if (type == typeof(DateTime)) - return WriteDate; if (type == typeof(Guid)) return WriteGuid; if (type == typeof (BinaryObject)) @@ -251,16 +247,11 @@ namespace Apache.Ignite.Core.Impl.Binary // Enums. if (elemType.IsEnum || elemType == typeof(BinaryEnum)) return WriteEnumArray; - + // Object array. - if (elemType == typeof (object) || elemType == typeof (IBinaryObject) || - elemType == typeof (BinaryObject)) - return WriteArray; + return WriteArray; } - if (type.IsSerializable) - return WriteSerializable; - return null; } @@ -315,16 +306,6 @@ namespace Apache.Ignite.Core.Impl.Binary } /// - /// Write date. - /// - /// Context. - /// Value. - private static void WriteDate(BinaryWriter ctx, object obj) - { - ctx.Write(new DateTimeHolder((DateTime) obj)); - } - - /// /// Write string. /// /// Context. @@ -535,21 +516,17 @@ namespace Apache.Ignite.Core.Impl.Binary { ctx.Stream.WriteByte(BinaryUtils.TypeArrayEnum); - var desc = ctx.Marshaller.GetDescriptor(obj.GetType()); - - int typeId = desc == null ? BinaryUtils.ObjTypeId : desc.TypeId; - - BinaryUtils.WriteArray((Array)obj, ctx, typeId); + BinaryUtils.WriteArray((Array) obj, ctx); } - /** - * Write array. - */ + /// + /// Writes the array. + /// private static void WriteArray(BinaryWriter ctx, object obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArray); - BinaryUtils.WriteArray((Array)obj, ctx); + BinaryUtils.WriteArray((Array) obj, ctx); } /** @@ -603,16 +580,6 @@ namespace Apache.Ignite.Core.Impl.Binary ctx.WriteInt(binEnum.EnumValue); } - /// - /// Writes serializable. - /// - /// The writer. - /// The object. - private static void WriteSerializable(BinaryWriter writer, object o) - { - writer.Write(new SerializableObjectHolder(o)); - } - /** * Read enum array. */ @@ -623,13 +590,36 @@ namespace Apache.Ignite.Core.Impl.Binary return BinaryUtils.ReadTypedArray(ctx, true, elemType); } - /** - * Read array. - */ + /// + /// Reads the array. + /// private static object ReadArray(BinaryReader ctx, Type type) { - var elemType = type.GetElementType() ?? typeof(object); + var elemType = type.GetElementType(); + + if (elemType == null) + { + if (ctx.Mode == BinaryMode.ForceBinary) + { + // Forced binary mode: use object because primitives are not represented as IBinaryObject. + elemType = typeof(object); + } + else + { + // Infer element type from typeId. + var typeId = ctx.ReadInt(); + + if (typeId != BinaryUtils.ObjTypeId) + { + elemType = ctx.Marshaller.GetDescriptor(true, typeId, true).Type; + } + + return BinaryUtils.ReadTypedArray(ctx, false, elemType ?? typeof(object)); + } + } + // Element type is known, no need to check typeId. + // In case of incompatible types we'll get exception either way. return BinaryUtils.ReadTypedArray(ctx, true, elemType); } @@ -798,23 +788,17 @@ namespace Apache.Ignite.Core.Impl.Binary /** */ private readonly bool _supportsHandles; - /** */ - private readonly bool _isSerializable; - /// /// Initializes a new instance of the class. /// /// The write action. /// Handles flag. - /// Determines whether this handler writes objects as serializable. - public BinarySystemWriteHandler(Action writeAction, bool supportsHandles, - bool isSerializable) + public BinarySystemWriteHandler(Action writeAction, bool supportsHandles) { Debug.Assert(writeAction != null); _writeAction = writeAction; _supportsHandles = supportsHandles; - _isSerializable = isSerializable; } /// @@ -834,13 +818,5 @@ namespace Apache.Ignite.Core.Impl.Binary { get { return _supportsHandles; } } - - /// - /// Gets or sets a value indicating whether this handler writes objects as serializable - /// - public bool IsSerializable - { - get { return _isSerializable; } - } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs index b416848..1ea1f0b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs @@ -48,7 +48,7 @@ namespace Apache.Ignite.Core.Impl.Binary } /** */ - public T1 ReadBinary(BinaryReader reader, Type type, int pos) + public T1 ReadBinary(BinaryReader reader, IBinaryTypeDescriptor desc, int pos) { return TypeCaster.Cast(_ctor(reader)); } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs index 2050f67..bb58ea5 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs @@ -52,6 +52,9 @@ namespace Apache.Ignite.Core.Impl.Binary /** Type: object. */ public const byte TypeObject = HdrFull; + /** Type: unregistered. */ + public const byte TypeUnregistered = 0; + /** Type: unsigned byte. */ public const byte TypeByte = 1; @@ -166,12 +169,6 @@ namespace Apache.Ignite.Core.Impl.Binary /** Type: Compute job wrapper. */ public const byte TypeComputeJobWrapper = 86; - /** Type: Serializable wrapper. */ - public const byte TypeSerializableHolder = 87; - - /** Type: DateTime wrapper. */ - public const byte TypeDateTimeHolder = 93; - /** Type: action wrapper. */ public const byte TypeComputeActionJob = 88; @@ -235,8 +232,12 @@ namespace Apache.Ignite.Core.Impl.Binary /** Bindig flags for static search. */ private const BindingFlags BindFlagsStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - /** Default poratble marshaller. */ - private static readonly Marshaller Marsh = new Marshaller(null); + /** System marshaller. */ + private static readonly Marshaller Marsh = new Marshaller( + new BinaryConfiguration {CompactFooter = false}) + { + RegistrationDisabled = true + }; /** Method: ReadArray. */ public static readonly MethodInfo MtdhReadArray = @@ -1265,14 +1266,31 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Array. /// Write context. - /// Type of the array element. - public static void WriteArray(Array val, BinaryWriter ctx, int elementType = ObjTypeId) + /// The element type id. + public static void WriteArray(Array val, BinaryWriter ctx, int? elemTypeId = null) { Debug.Assert(val != null && ctx != null); IBinaryStream stream = ctx.Stream; - stream.WriteInt(elementType); + if (elemTypeId != null && elemTypeId != TypeUnregistered) + { + stream.WriteInt(elemTypeId.Value); + } + else + { + var elemType = val.GetType().GetElementType(); + + var typeId = ObjTypeId; + + if (elemType != typeof(object)) + typeId = ctx.Marshaller.GetDescriptor(elemType).TypeId; + + stream.WriteInt(typeId); + + if (typeId == TypeUnregistered) + ctx.WriteString(elemType.FullName); + } stream.WriteInt(val.Length); @@ -1313,7 +1331,12 @@ namespace Apache.Ignite.Core.Impl.Binary var pos = stream.Position; if (typed) - stream.ReadInt(); + { + int typeId = stream.ReadInt(); + + if (typeId == TypeUnregistered) + ctx.ReadString(); + } int len = stream.ReadInt(); @@ -1538,7 +1561,7 @@ namespace Apache.Ignite.Core.Impl.Binary { var desc = marshaller.GetDescriptor(enumType); - return desc == null ? ObjTypeId : desc.TypeId; + return desc.TypeId; } throw new BinaryObjectException("Only Int32 underlying type is supported for enums: " + @@ -1559,10 +1582,10 @@ namespace Apache.Ignite.Core.Impl.Binary return TypeCaster.Cast(value); // All enums are user types - var desc = marsh.GetDescriptor(true, typeId); + var desc = marsh.GetDescriptor(true, typeId, true); if (desc == null || desc.Type == null) - throw new BinaryObjectException("Unknown enum type id: " + typeId); + return TypeCaster.Cast(value); return (T)Enum.ToObject(desc.Type, value); } @@ -1743,7 +1766,6 @@ namespace Apache.Ignite.Core.Impl.Binary public static int FieldId(int typeId, string fieldName, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper) { - Debug.Assert(typeId != 0); Debug.Assert(fieldName != null); fieldName = ConvertFieldName(fieldName, nameMapper); http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs index 0490ec8..1388d16 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs @@ -48,27 +48,12 @@ namespace Apache.Ignite.Core.Impl.Binary /** Metadatas collected during this write session. */ private IDictionary _metas; - /** Current type ID. */ - private int _curTypeId; - - /** Current name converter */ - private IBinaryNameMapper _curConverter; - - /** Current mapper. */ - private IBinaryIdMapper _curMapper; - - /** Current object start position. */ - private int _curPos; - - /** Current raw position. */ - private int _curRawPos; + /** Current stack frame. */ + private Frame _frame; /** Whether we are currently detaching an object. */ private bool _detaching; - /** Current type structure tracker, */ - private BinaryStructureTracker _curStruct; - /** Schema holder. */ private readonly BinaryObjectSchemaHolder _schema = BinaryObjectSchemaHolder.Current; @@ -150,7 +135,7 @@ namespace Apache.Ignite.Core.Impl.Binary /// Byte value. public void WriteByte(string fieldName, byte val) { - WriteFieldId(fieldName, BinaryUtils.TypeBool); + WriteFieldId(fieldName, BinaryUtils.TypeByte); WriteByteField(val); } @@ -875,23 +860,13 @@ namespace Apache.Ignite.Core.Impl.Binary { var desc = _marsh.GetDescriptor(val.GetType()); - if (desc != null) - { - var metaHnd = _marsh.GetBinaryTypeHandler(desc); + var metaHnd = _marsh.GetBinaryTypeHandler(desc); - _stream.WriteByte(BinaryUtils.TypeEnum); + _stream.WriteByte(BinaryUtils.TypeEnum); - BinaryUtils.WriteEnum(this, val); + BinaryUtils.WriteEnum(this, val); - SaveMetadata(desc, metaHnd.OnObjectWriteFinished()); - } - else - { - // Unregistered enum, write with object type id. - _stream.WriteByte(BinaryUtils.TypeEnum); - _stream.WriteInt(BinaryUtils.ObjTypeId); - _stream.WriteInt(TypeCaster.Cast(val)); - } + SaveMetadata(desc, metaHnd.OnObjectWriteFinished()); } } @@ -931,9 +906,7 @@ namespace Apache.Ignite.Core.Impl.Binary { _stream.WriteByte(BinaryUtils.TypeArrayEnum); - var elTypeId = elementTypeId ?? BinaryUtils.GetEnumTypeId(val.GetType().GetElementType(), Marshaller); - - BinaryUtils.WriteArray(val, this, elTypeId); + BinaryUtils.WriteArray(val, this, elementTypeId); } } @@ -1089,8 +1062,8 @@ namespace Apache.Ignite.Core.Impl.Binary /// public IBinaryRawWriter GetRawWriter() { - if (_curRawPos == 0) - _curRawPos = _stream.Position; + if (_frame.RawPos == 0) + _frame.RawPos = _stream.Position; return this; } @@ -1159,121 +1132,122 @@ namespace Apache.Ignite.Core.Impl.Binary if (WriteBuilderSpecials(obj)) return; - // Suppose that we faced normal object and perform descriptor lookup. - IBinaryTypeDescriptor desc = _marsh.GetDescriptor(type); + // Are we dealing with a well-known type? + var handler = BinarySystemHandlers.GetWriteHandler(type); - if (desc != null) + if (handler != null) { - // Writing normal object. - var pos = _stream.Position; - - // Dealing with handles. - if (desc.Serializer.SupportsHandles && WriteHandle(pos, obj)) + if (handler.SupportsHandles && WriteHandle(_stream.Position, obj)) return; - // Skip header length as not everything is known now - _stream.Seek(BinaryObjectHeader.Size, SeekOrigin.Current); - - // Preserve old frame. - int oldTypeId = _curTypeId; - IBinaryNameMapper oldConverter = _curConverter; - IBinaryIdMapper oldMapper = _curMapper; - int oldRawPos = _curRawPos; - var oldPos = _curPos; - - var oldStruct = _curStruct; + handler.Write(this, obj); - // Push new frame. - _curTypeId = desc.TypeId; - _curConverter = desc.NameMapper; - _curMapper = desc.IdMapper; - _curRawPos = 0; - _curPos = pos; + return; + } - _curStruct = new BinaryStructureTracker(desc, desc.WriterTypeStructure); - var schemaIdx = _schema.PushSchema(); + // Suppose that we faced normal object and perform descriptor lookup. + var desc = _marsh.GetDescriptor(type); - try - { - // Write object fields. - desc.Serializer.WriteBinary(obj, this); - var dataEnd = _stream.Position; + // Writing normal object. + var pos = _stream.Position; - // Write schema - var schemaOffset = dataEnd - pos; + // Dealing with handles. + if (desc.Serializer.SupportsHandles && WriteHandle(pos, obj)) + return; - int schemaId; - - var flags = desc.UserType - ? BinaryObjectHeader.Flag.UserType - : BinaryObjectHeader.Flag.None; + // Skip header length as not everything is known now + _stream.Seek(BinaryObjectHeader.Size, SeekOrigin.Current); - if (Marshaller.CompactFooter && desc.UserType) - flags |= BinaryObjectHeader.Flag.CompactFooter; + // Write type name for unregistered types + if (!desc.IsRegistered) + WriteString(type.AssemblyQualifiedName); - var hasSchema = _schema.WriteSchema(_stream, schemaIdx, out schemaId, ref flags); + var headerSize = _stream.Position - pos; - if (hasSchema) - { - flags |= BinaryObjectHeader.Flag.HasSchema; + // Preserve old frame. + var oldFrame = _frame; - // Calculate and write header. - if (_curRawPos > 0) - _stream.WriteInt(_curRawPos - pos); // raw offset is in the last 4 bytes + // Push new frame. + _frame.RawPos = 0; + _frame.Pos = pos; + _frame.Struct = new BinaryStructureTracker(desc, desc.WriterTypeStructure); + _frame.HasCustomTypeData = false; - // Update schema in type descriptor - if (desc.Schema.Get(schemaId) == null) - desc.Schema.Add(schemaId, _schema.GetSchema(schemaIdx)); - } - else - schemaOffset = BinaryObjectHeader.Size; + var schemaIdx = _schema.PushSchema(); - if (_curRawPos > 0) - flags |= BinaryObjectHeader.Flag.HasRaw; + try + { + // Write object fields. + desc.Serializer.WriteBinary(obj, this); + var dataEnd = _stream.Position; - var len = _stream.Position - pos; + // Write schema + var schemaOffset = dataEnd - pos; - var comparer = BinaryUtils.GetEqualityComparer(desc); + int schemaId; + + var flags = desc.UserType + ? BinaryObjectHeader.Flag.UserType + : BinaryObjectHeader.Flag.None; - var hashCode = comparer.GetHashCode(Stream, pos + BinaryObjectHeader.Size, - dataEnd - pos - BinaryObjectHeader.Size, _schema, schemaIdx, _marsh, desc); + if (_frame.HasCustomTypeData) + flags |= BinaryObjectHeader.Flag.CustomDotNetType; - var header = new BinaryObjectHeader(desc.TypeId, hashCode, len, schemaId, schemaOffset, flags); + if (Marshaller.CompactFooter && desc.UserType) + flags |= BinaryObjectHeader.Flag.CompactFooter; - BinaryObjectHeader.Write(header, _stream, pos); + var hasSchema = _schema.WriteSchema(_stream, schemaIdx, out schemaId, ref flags); - Stream.Seek(pos + len, SeekOrigin.Begin); // Seek to the end - } - finally + if (hasSchema) { - _schema.PopSchema(schemaIdx); + flags |= BinaryObjectHeader.Flag.HasSchema; + + // Calculate and write header. + if (_frame.RawPos > 0) + _stream.WriteInt(_frame.RawPos - pos); // raw offset is in the last 4 bytes + + // Update schema in type descriptor + if (desc.Schema.Get(schemaId) == null) + desc.Schema.Add(schemaId, _schema.GetSchema(schemaIdx)); } + else + schemaOffset = headerSize; + + if (_frame.RawPos > 0) + flags |= BinaryObjectHeader.Flag.HasRaw; + + var len = _stream.Position - pos; + + var comparer = BinaryUtils.GetEqualityComparer(desc); + + var hashCode = comparer.GetHashCode(Stream, pos + BinaryObjectHeader.Size, + dataEnd - pos - BinaryObjectHeader.Size, _schema, schemaIdx, _marsh, desc); - // Apply structure updates if any. - _curStruct.UpdateWriterStructure(this); + var header = new BinaryObjectHeader(desc.IsRegistered ? desc.TypeId : BinaryUtils.TypeUnregistered, + hashCode, len, schemaId, schemaOffset, flags); - // Restore old frame. - _curTypeId = oldTypeId; - _curConverter = oldConverter; - _curMapper = oldMapper; - _curRawPos = oldRawPos; - _curPos = oldPos; + BinaryObjectHeader.Write(header, _stream, pos); - _curStruct = oldStruct; + Stream.Seek(pos + len, SeekOrigin.Begin); // Seek to the end } - else + finally { - // Are we dealing with a well-known type? - var handler = BinarySystemHandlers.GetWriteHandler(type); + _schema.PopSchema(schemaIdx); + } - if (handler == null) // We did our best, object cannot be marshalled. - throw BinaryUtils.GetUnsupportedTypeException(type, obj); - - if (handler.SupportsHandles && WriteHandle(_stream.Position, obj)) - return; + // Apply structure updates if any. + _frame.Struct.UpdateWriterStructure(this); - handler.Write(this, obj); - } + // Restore old frame. + _frame = oldFrame; + } + + /// + /// Marks current object with a custom type data flag. + /// + public void SetCustomTypeDataFlag(bool hasCustomTypeData) + { + _frame.HasCustomTypeData = hasCustomTypeData; } /// @@ -1455,12 +1429,12 @@ namespace Apache.Ignite.Core.Impl.Binary /// Field type ID. private void WriteFieldId(string fieldName, byte fieldTypeId) { - if (_curRawPos != 0) + if (_frame.RawPos != 0) throw new BinaryObjectException("Cannot write named fields after raw data is written."); - var fieldId = _curStruct.GetFieldId(fieldName, fieldTypeId); + var fieldId = _frame.Struct.GetFieldId(fieldName, fieldTypeId); - _schema.PushField(fieldId, _stream.Position - _curPos); + _schema.PushField(fieldId, _stream.Position - _frame.Pos); } /// @@ -1489,5 +1463,23 @@ namespace Apache.Ignite.Core.Impl.Binary _metas[desc.TypeId] = new BinaryType(desc, fields); } } + + /// + /// Stores current writer stack frame. + /// + private struct Frame + { + /** Current object start position. */ + public int Pos; + + /** Current raw position. */ + public int RawPos; + + /** Current type structure tracker. */ + public BinaryStructureTracker Struct; + + /** Custom type data. */ + public bool HasCustomTypeData; + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeHolder.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeHolder.cs deleted file mode 100644 index 21c56a9..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeHolder.cs +++ /dev/null @@ -1,101 +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; - using System.Diagnostics; - using Apache.Ignite.Core.Binary; - - /// - /// Wraps DateTime item in a binarizable. - /// - internal struct DateTimeHolder : IBinaryWriteAware - { - /** */ - private readonly DateTime _item; - - /// - /// Constructor. - /// - /// The item to wrap. - public DateTimeHolder(DateTime item) - { - _item = item; - } - - /// - /// Constructor. - /// - /// The reader. - public DateTimeHolder(IBinaryRawReader reader) - { - Debug.Assert(reader != null); - - _item = DateTime.FromBinary(reader.ReadLong()); - } - - /// - /// Gets the item to wrap. - /// - public DateTime Item - { - get { return _item; } - } - - /** */ - public void WriteBinary(IBinaryWriter writer) - { - Debug.Assert(writer != null); - - writer.GetRawWriter().WriteLong(_item.ToBinary()); - } - - /** */ - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - return obj is DateTimeHolder && Equals((DateTimeHolder) obj); - } - - /** */ - public override int GetHashCode() - { - return _item.GetHashCode(); - } - - /** */ - public static bool operator ==(DateTimeHolder left, DateTimeHolder right) - { - return left.Equals(right); - } - - /** */ - public static bool operator !=(DateTimeHolder left, DateTimeHolder right) - { - return !left.Equals(right); - } - - /// - /// Checks equality. - /// - private bool Equals(DateTimeHolder other) - { - return _item.Equals(other._item); - } - } -} \ 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/DateTimeSerializer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeSerializer.cs deleted file mode 100644 index bea7d58..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeSerializer.cs +++ /dev/null @@ -1,48 +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; - using Apache.Ignite.Core.Impl.Common; - - /// - /// DateTime serializer. - /// - internal class DateTimeSerializer : IBinarySerializerInternal - { - /** */ - public void WriteBinary(T obj, BinaryWriter writer) - { - TypeCaster.Cast(obj).WriteBinary(writer); - } - - /** */ - public T ReadBinary(BinaryReader reader, Type type, int pos) - { - var holder = new DateTimeHolder(reader); - - return TypeCaster.Cast(holder.Item); - } - - /** */ - public bool SupportsHandles - { - get { return false; } - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DeserializationCallbackProcessor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DeserializationCallbackProcessor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DeserializationCallbackProcessor.cs new file mode 100644 index 0000000..3b21946 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DeserializationCallbackProcessor.cs @@ -0,0 +1,102 @@ +/* + * 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.Collections.Generic; + using System.Runtime.Serialization; + using System.Threading; + + /// + /// Tracks object graph and invokes . + /// + /// must be called after entire object graph has been + /// deserialized. We preserve all objects in a thread-local list and invoke callbacks once all objects + /// are fully deserialized. + /// + internal static class DeserializationCallbackProcessor + { + /// + /// Object graph for current thread. + /// + private static readonly ThreadLocal Graph + = new ThreadLocal(() => new ObjectGraph()); + + /// + /// Register an object for deserialization callback. + /// + /// The object. + /// Id of the object. + public static void Push(object obj) + { + var graph = Graph.Value; + + graph.Depth++; + + var cb = obj as IDeserializationCallback; + + if (cb != null) + { + graph.Objects.Add(cb); + } + } + + /// + /// Called when deserialization of an object has completed. + /// When Pop() has been called for all registered objects, all callbacks are invoked. + /// + public static void Pop() + { + var graph = Graph.Value; + + graph.Depth--; + + if (graph.Depth == 0) + { + // Entire graph has been deserialized: invoke callbacks in direct order (like BinaryFormatter does). + foreach (var obj in graph.Objects) + { + obj.OnDeserialization(null); + } + + graph.Objects.Clear(); + } + } + + /// + /// Object graph. + /// + private class ObjectGraph + { + /** */ + private readonly List _objects = new List(); + + /// + /// Gets or sets the depth. + /// + public int Depth { get; set; } + + /// + /// Gets the objects. + /// + public List Objects + { + get { return _objects; } + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs index 58844d6..b775999 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs @@ -17,8 +17,6 @@ namespace Apache.Ignite.Core.Impl.Binary { - using System; - /// /// Internal generic serializer interface. /// @@ -32,7 +30,7 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Read binary object. /// - T ReadBinary(BinaryReader reader, Type type, int pos); + T ReadBinary(BinaryReader reader, IBinaryTypeDescriptor desc, int pos); /// /// Gets a value indicating whether this serializer supports handles. http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs index 6c7e360..6bec70f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs @@ -112,5 +112,13 @@ namespace Apache.Ignite.Core.Impl.Binary /// Gets the schema. /// BinaryObjectSchema Schema { get; } + + /// + /// Gets a value indicating whether this descriptor is registered in the cluster. + /// + /// + /// true if this instance is registered; otherwise, false. + /// + bool IsRegistered { get; } } }