IGNITE-1282: Refactoring.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3548457c Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3548457c Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3548457c Branch: refs/heads/ignite-1282-opto Commit: 3548457c234456f1a3695dac497ceb452c4971ed Parents: b34084e Author: vozerov-gridgain <voze...@gridgain.com> Authored: Wed Oct 7 13:00:05 2015 +0300 Committer: vozerov-gridgain <voze...@gridgain.com> Committed: Wed Oct 7 13:00:05 2015 +0300 ---------------------------------------------------------------------- .../Apache.Ignite.Core.Tests.csproj | 1 + .../Portable/PortableStructureTest.cs | 260 +++++++++++++++++++ .../Impl/Portable/IPortableTypeDescriptor.cs | 2 +- .../Impl/Portable/PortableFullTypeDescriptor.cs | 2 +- .../Portable/PortableSurrogateTypeDescriptor.cs | 2 +- .../Impl/Portable/PortableWriterImpl.cs | 2 +- .../Portable/Structure/PortableStructure.cs | 30 ++- .../Structure/PortableStructureEntry.cs | 8 +- .../Structure/PortableStructureJumpTable.cs | 4 +- 9 files changed, 295 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj index 90f3481..7cbe784 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj @@ -111,6 +111,7 @@ <Compile Include="MarshallerTest.cs" /> <Compile Include="MessagingTest.cs" /> <Compile Include="PortableConfigurationTest.cs" /> + <Compile Include="Portable\PortableStructureTest.cs" /> <Compile Include="SerializationTest.cs" /> <Compile Include="IgniteStartStopTest.cs" /> <Compile Include="TestUtils.cs" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableStructureTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableStructureTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableStructureTest.cs new file mode 100644 index 0000000..46c9539 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableStructureTest.cs @@ -0,0 +1,260 @@ +/* + * 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.Portable +{ + using System; + using System.Collections.Generic; + using Apache.Ignite.Core.Impl; + using Apache.Ignite.Core.Impl.Portable; + using Apache.Ignite.Core.Impl.Portable.Structure; + using Apache.Ignite.Core.Portable; + using NUnit.Framework; + + /// <summary> + /// Contains tests for portable type structure. + /// </summary> + [TestFixture] + public class PortableStructureTest + { + /** Repeat count. */ + public static readonly int RepeatCnt = 10; + + public static readonly int ObjectsPerMode = 5; + + /// <summary> + /// Test object write with different structures. + /// </summary> + [Test] + public void TestStructure() + { + for (int i = 1; i <= RepeatCnt; i++) + { + Console.WriteLine(">>> Iteration started: " + i); + + // 1. Generate and shuffle objects. + IList<BranchedType> objs = new List<BranchedType>(); + + for (int j = 0; j < 6 * ObjectsPerMode; j++) + objs.Add(new BranchedType((j%6) + 1)); + + objs = IgniteUtils.Shuffle(objs); + + // 2. Create new marshaller. + PortableTypeConfiguration typeCfg = new PortableTypeConfiguration(typeof(BranchedType)); + + PortableConfiguration cfg = new PortableConfiguration + { + TypeConfigurations = new List<PortableTypeConfiguration> { typeCfg } + }; + + PortableMarshaller marsh = new PortableMarshaller(cfg); + + // 3. Marshal all data and ensure deserialized object is fine. + foreach (BranchedType obj in objs) + { + Console.WriteLine(">>> Write object [mode=" + obj.mode + ']'); + + byte[] data = marsh.Marshal(obj); + + BranchedType other = marsh.Unmarshal<BranchedType>(data); + + Assert.IsTrue(obj.Equals(other)); + } + + Console.WriteLine(); + + // 4. Ensure that all fields are recorded. + IPortableTypeDescriptor desc = marsh.Descriptor(typeof (BranchedType)); + + PortableStructure typeStruct = desc.TypeStructure; + + IDictionary<string, byte> fields = typeStruct.FieldTypes; + + Assert.IsTrue(fields.Count == 8); + + Assert.IsTrue(fields.ContainsKey("mode")); + Assert.IsTrue(fields.ContainsKey("f2")); + Assert.IsTrue(fields.ContainsKey("f3")); + Assert.IsTrue(fields.ContainsKey("f4")); + Assert.IsTrue(fields.ContainsKey("f5")); + Assert.IsTrue(fields.ContainsKey("f6")); + Assert.IsTrue(fields.ContainsKey("f7")); + Assert.IsTrue(fields.ContainsKey("f8")); + } + } + } + + public class BranchedType : IPortableMarshalAware + { + public int mode; + public int f2; + public int f3; + public int f4; + public int f5; + public int f6; + public int f7; + public int f8; + + public BranchedType(int mode) + { + this.mode = mode; + + switch (mode) + { + case 1: + f2 = 2; + + break; + + case 2: + f2 = 2; + f3 = 3; + f4 = 4; + + break; + + case 3: + f2 = 2; + f3 = 3; + f5 = 5; + + break; + + case 4: + f2 = 2; + f3 = 3; + f5 = 5; + f6 = 6; + + break; + + case 5: + f2 = 2; + f3 = 3; + f7 = 7; + + break; + + case 6: + f8 = 8; + + break; + } + } + + public void WritePortable(IPortableWriter writer) + { + writer.WriteInt("mode", mode); + + switch (mode) + { + case 1: + writer.WriteInt("f2", f2); + + break; + + case 2: + writer.WriteInt("f2", f2); + writer.WriteInt("f3", f3); + writer.WriteInt("f4", f4); + + break; + + case 3: + writer.WriteInt("f2", f2); + writer.WriteInt("f3", f3); + writer.WriteInt("f5", f5); + + break; + + case 4: + writer.WriteInt("f2", f2); + writer.WriteInt("f3", f3); + writer.WriteInt("f5", f5); + writer.WriteInt("f6", f6); + + break; + + case 5: + writer.WriteInt("f2", f2); + writer.WriteInt("f3", f3); + writer.WriteInt("f7", f7); + + break; + + case 6: + writer.WriteInt("f8", f8); + + break; + } + } + + public void ReadPortable(IPortableReader reader) + { + mode = reader.ReadInt("mode"); + + switch (mode) + { + case 1: + f2 = reader.ReadInt("f2"); + + break; + + case 2: + f2 = reader.ReadInt("f2"); + f3 = reader.ReadInt("f3"); + f4 = reader.ReadInt("f4"); + + break; + + case 3: + f2 = reader.ReadInt("f2"); + f3 = reader.ReadInt("f3"); + f5 = reader.ReadInt("f5"); + + break; + + case 4: + f2 = reader.ReadInt("f2"); + f3 = reader.ReadInt("f3"); + f5 = reader.ReadInt("f5"); + f6 = reader.ReadInt("f6"); + + break; + + case 5: + f2 = reader.ReadInt("f2"); + f3 = reader.ReadInt("f3"); + f7 = reader.ReadInt("f7"); + + break; + + case 6: + f8 = reader.ReadInt("f8"); + + break; + } + } + + public bool Equals(BranchedType other) + { + return mode == other.mode && f2 == other.f2 && f3 == other.f3 && f4 == other.f4 && f5 == other.f5 && + f6 == other.f6 && f7 == other.f7 && f8 == other.f8; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs index 8a84daf..d4bde4f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs @@ -118,6 +118,6 @@ namespace Apache.Ignite.Core.Impl.Portable /// <param name="exp">Expected type structure.</param> /// <param name="pathIdx">Path index.</param> /// <param name="updates">Recorded updates.</param> - void UpdateStrcuture(PortableStructure exp, int pathIdx, IList<PortableStructureUpdate> updates); + void UpdateStructure(PortableStructure exp, int pathIdx, IList<PortableStructureUpdate> updates); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs index 247a0b0..701147d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs @@ -184,7 +184,7 @@ namespace Apache.Ignite.Core.Impl.Portable } /** <inheritDoc /> */ - public void UpdateStrcuture(PortableStructure exp, int pathIdx, + public void UpdateStructure(PortableStructure exp, int pathIdx, IList<PortableStructureUpdate> updates) { lock (this) http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs index 103dd75..e786746 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs @@ -131,7 +131,7 @@ namespace Apache.Ignite.Core.Impl.Portable } /** <inheritDoc /> */ - public void UpdateStrcuture(PortableStructure exp, int pathIdx, + public void UpdateStructure(PortableStructure exp, int pathIdx, IList<PortableStructureUpdate> updates) { lock (this) http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs index cafc69d..09ca45e 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs @@ -1345,7 +1345,7 @@ namespace Apache.Ignite.Core.Impl.Portable // Apply structure updates if any. if (_curStructUpdates != null) { - desc.UpdateStrcuture(_curStruct, _curStructPath, _curStructUpdates); + desc.UpdateStructure(_curStruct, _curStructPath, _curStructUpdates); IPortableMetadataHandler metaHnd = _marsh.MetadataHandler(desc); http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs index c434110..aaeaadd 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs @@ -99,9 +99,9 @@ namespace Apache.Ignite.Core.Impl.Portable.Structure if (pathIdx0 < 0) return 0; - Debug.Assert(pathIdx < _paths.Length); + Debug.Assert(pathIdx0 < _paths.Length); - entry = _paths[pathIdx][actionIdx]; + entry = _paths[pathIdx0][actionIdx]; entry.ValidateType(fieldType); @@ -219,7 +219,12 @@ namespace Apache.Ignite.Core.Impl.Portable.Structure { newPaths[oldPathIdx][i] = newPaths[pathIdx][i]; - newPaths[pathIdx][i] = new PortableStructureEntry(); + if (i == firstUpdate.Index) + // Jump table must be placed here. + newPaths[pathIdx][i] = new PortableStructureEntry(newJumpIdx); + else + // Just nullify. + newPaths[pathIdx][i] = new PortableStructureEntry(); } // Apply updats to the new path. @@ -246,11 +251,12 @@ namespace Apache.Ignite.Core.Impl.Portable.Structure int newPathLen = Math.Max(_paths[0].Length, minLen); - for (int i = 0; i < _paths.Length; i++) + for (int i = 0; i < newPaths.Length; i++) { newPaths[i] = new PortableStructureEntry[newPathLen]; - Array.Copy(_paths[i], newPaths[i], _paths[i].Length); + if (i < _paths.Length) + Array.Copy(_paths[i], newPaths[i], _paths[i].Length); } return newPaths; @@ -265,8 +271,12 @@ namespace Apache.Ignite.Core.Impl.Portable.Structure { var newJumps = new PortableStructureJumpTable[_jumps.Length + additionalJumps]; - for (int i = 0; i < _jumps.Length; i++) + for (int i = 1; i < _jumps.Length; i++) + { + // The very first jump is always null so that we can distinguish jump table + // and empty value in PortableStructureEntry. newJumps[i] = _jumps[i].Copy(); + } return newJumps; } @@ -313,5 +323,13 @@ namespace Apache.Ignite.Core.Impl.Portable.Structure return newFieldTypes.Count == _fieldTypes.Count ? this : new PortableStructure(_paths, _jumps, newFieldTypes); } + + /// <summary> + /// Recorded field types. + /// </summary> + internal IDictionary<string, byte> FieldTypes + { + get { return _fieldTypes; } + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs index 5229a95..e3efc2a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs @@ -66,12 +66,12 @@ namespace Apache.Ignite.Core.Impl.Portable.Structure /// <summary> /// Check whether current field entry matches passed arguments. /// </summary> - /// <param name="name"></param> - /// <param name="type"></param> - /// <returns></returns> + /// <param name="name">Field name.</param> + /// <param name="type">Field type.</param> + /// <returns>True if expected.</returns> public bool IsExpected(string name, byte type) { - if (!ReferenceEquals(_name, name) && !_name.Equals(name)) + if (!ReferenceEquals(_name, name) && !name.Equals(_name)) return false; ValidateType(type); http://git-wip-us.apache.org/repos/asf/ignite/blob/3548457c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs index 85e71c4..9eab9d4 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs @@ -52,8 +52,8 @@ namespace Apache.Ignite.Core.Impl.Portable.Structure /// <param name="pathIdxs">Path indexes.</param> private PortableStructureJumpTable(string[] names, int[] pathIdxs) { - Debug.Assert(_names.Length > 1); - Debug.Assert(_names.Length == pathIdxs.Length); + Debug.Assert(names.Length > 1); + Debug.Assert(names.Length == pathIdxs.Length); _names = names; _pathIdxs = pathIdxs;