You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/10/07 11:59:28 UTC
[1/4] ignite git commit: IGNITE-1282: WIP on optos.
Repository: ignite
Updated Branches:
refs/heads/ignite-1282-opto [created] 3548457c2
IGNITE-1282: WIP on optos.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9da45ed3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9da45ed3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9da45ed3
Branch: refs/heads/ignite-1282-opto
Commit: 9da45ed3e6f7c79a47bbd71fa3db64094cb96e68
Parents: 49c495b
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Wed Oct 7 10:36:29 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Wed Oct 7 10:36:29 2015 +0300
----------------------------------------------------------------------
.../Apache.Ignite.Core.csproj | 5 +
.../Impl/Portable/IPortableTypeDescriptor.cs | 15 +
.../Metadata/Opto/PortableTypeStructure.cs | 317 +++++++++++++++++++
.../Metadata/Opto/PortableTypeStructureEntry.cs | 127 ++++++++
.../Opto/PortableTypeStructureJumpTable.cs | 115 +++++++
.../Opto/PortableTypeStructureUpdate.cs | 84 +++++
.../Impl/Portable/PortableFullTypeDescriptor.cs | 21 ++
.../Portable/PortableSurrogateTypeDescriptor.cs | 24 +-
.../Impl/Portable/PortableUtils.cs | 4 +
.../Impl/Portable/PortableWriterImpl.cs | 61 +++-
10 files changed, 770 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/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 855dda8..d412181 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -250,6 +250,10 @@
<Compile Include="Impl\Portable\IPortableTypeDescriptor.cs" />
<Compile Include="Impl\Portable\IPortableWriteAware.cs" />
<Compile Include="Impl\Portable\Metadata\IPortableMetadataHandler.cs" />
+ <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructureEntry.cs" />
+ <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructure.cs" />
+ <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructureJumpTable.cs" />
+ <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructureUpdate.cs" />
<Compile Include="Impl\Portable\Metadata\PortableHashsetMetadataHandler.cs" />
<Compile Include="Impl\Portable\Metadata\PortableMetadataHolder.cs" />
<Compile Include="Impl\Portable\Metadata\PortableMetadataImpl.cs" />
@@ -367,6 +371,7 @@
<Link>resources\release\x86\ignite.common.dll</Link>
</EmbeddedResource>
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/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 62597d5..389238c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
@@ -18,6 +18,8 @@
namespace Apache.Ignite.Core.Impl.Portable
{
using System;
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
using Apache.Ignite.Core.Portable;
/// <summary>
@@ -104,5 +106,18 @@ namespace Apache.Ignite.Core.Impl.Portable
{
get;
}
+
+ /// <summary>
+ /// Type structure.
+ /// </summary>
+ PortableTypeStructure TypeStructure { get; }
+
+ /// <summary>
+ /// Update type structure.
+ /// </summary>
+ /// <param name="exp">Expected type structure.</param>
+ /// <param name="pathIdx">Path index.</param>
+ /// <param name="updates">Recorded updates.</param>
+ void UpdateStrcuture(PortableTypeStructure exp, int pathIdx, IList<PortableTypeStructureUpdate> updates);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs
new file mode 100644
index 0000000..cdc0859
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Portable type structure. Cache field IDs and metadata to improve marshalling performance.
+ /// Every object write contains a set of field writes. Every unique ordered set of written fields
+ /// produce write "path". We cache these paths allowing for very fast traverse over object structure
+ /// without expensive map lookups and field ID calculations.
+ /// </summary>
+ internal class PortableTypeStructure
+ {
+ /// <summary>
+ /// Create empty type structure.
+ /// </summary>
+ /// <returns>Empty type structure.</returns>
+ public static PortableTypeStructure CreateEmpty()
+ {
+ return new PortableTypeStructure(new[] { new PortableTypeStructureEntry[0] },
+ new PortableTypeStructureJumpTable[1], new Dictionary<string, byte>());
+ }
+
+ /** Entries. */
+ private readonly PortableTypeStructureEntry[][] _paths;
+
+ /** Jumps. */
+ private readonly PortableTypeStructureJumpTable[] _jumps;
+
+ /** Field types. */
+ private readonly IDictionary<string, byte> _fieldTypes;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="paths">Paths.</param>
+ /// <param name="jumps">Jumps.</param>
+ /// <param name="fieldTypes">Field types.</param>
+ private PortableTypeStructure(PortableTypeStructureEntry[][] paths,
+ PortableTypeStructureJumpTable[] jumps, IDictionary<string, byte> fieldTypes)
+ {
+ _paths = paths;
+ _jumps = jumps;
+ _fieldTypes = fieldTypes;
+ }
+
+ /// <summary>
+ /// Gets field ID if possible.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="fieldType">Field type.</param>
+ /// <param name="pathIdx">Path index, changes during jumps.</param>
+ /// <param name="actionIdx">Action index.</param>
+ /// <returns>Field ID or zero in case there are no matching path.</returns>
+ public int GetFieldId(string fieldName, byte fieldType, ref int pathIdx, int actionIdx)
+ {
+ Debug.Assert(pathIdx <= _paths.Length);
+
+ // Get path.
+ PortableTypeStructureEntry[] path = _paths[pathIdx];
+
+ if (actionIdx < path.Length)
+ {
+ // Get entry matching the action index.
+ PortableTypeStructureEntry entry = path[actionIdx];
+
+ if (entry.IsExpected(fieldName, fieldType))
+ // Entry matches our expectations, return.
+ return entry.Id;
+ else if (entry.IsJumpTable)
+ {
+ // Entry is a pointer to a jump table.
+ Debug.Assert(entry.Id < _jumps.Length);
+
+ PortableTypeStructureJumpTable jmpTbl = _jumps[entry.Id];
+
+ int pathIdx0 = jmpTbl.GetPathIndex(fieldName);
+
+ if (pathIdx0 < 0)
+ return 0;
+
+ Debug.Assert(pathIdx < _paths.Length);
+
+ entry = _paths[pathIdx][actionIdx];
+
+ entry.ValidateType(fieldType);
+
+ pathIdx = pathIdx0;
+
+ return entry.Id;
+ }
+ }
+
+ // Failed to find anything because this is a new field.
+ return 0;
+ }
+
+ /// <summary>
+ /// Merge updates into a new type structure.
+ /// </summary>
+ /// <param name="exp">Expected type structure to apply updates to </param>
+ /// <param name="pathIdx">Path index.</param>
+ /// <param name="updates">Updates.</param>
+ /// <returns>New type structure with updates.</returns>
+ public PortableTypeStructure Merge(PortableTypeStructure exp, int pathIdx,
+ IList<PortableTypeStructureUpdate> updates)
+ {
+ if (updates.Count == 0)
+ return this;
+
+ // Algorithm ensures that updates are applied to the same type structure,
+ // where they were initially observed. This allow us to keep structure
+ // internals simpler and more efficient. On the other hand, this imposes
+ // some performance hit because in case of concurrent update, recorded
+ // changes will be discarded and recorded again during the next write
+ // on the same path. This should occur only during application warmup.
+
+ // Note that field types are merged anyway to avoid metadata clashes.
+ PortableTypeStructure res = MergeFieldTypes(updates);
+
+ if (ReferenceEquals(exp, this))
+ {
+ PortableTypeStructureUpdate firstUpdate = updates[0];
+
+ if (firstUpdate.Index == 0)
+ {
+ // Special case: the very first structure update. Simply attach all updates.
+ Debug.Assert(_paths.Length == 1);
+ Debug.Assert(_paths[0].Length == 0);
+ Debug.Assert(pathIdx == 0);
+
+ PortableTypeStructureEntry[][] newPaths = CopyPaths(updates.Count, 0);
+
+ ApplyUpdatesToPath(newPaths[0], updates);
+
+ res = new PortableTypeStructure(newPaths, _jumps, res._fieldTypes);
+ }
+ else
+ {
+ // Get entry where updates should start.
+ PortableTypeStructureEntry[] path = _paths[pathIdx];
+
+ PortableTypeStructureEntry startEntry = default(PortableTypeStructureEntry);
+
+ if (firstUpdate.Index < path.Length)
+ startEntry = path[firstUpdate.Index];
+
+ if (startEntry.IsEmpty)
+ {
+ // We are on the empty/non-existend entry. Continue the path without branching.
+ var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 0);
+
+ ApplyUpdatesToPath(newPaths[pathIdx], updates);
+
+ res = new PortableTypeStructure(newPaths, _jumps, res._fieldTypes);
+ }
+ else if (startEntry.IsJumpTable)
+ {
+ // We are on the jump table. Add a new path and record it in the jump table.
+
+ // 1. Preapare new structures.
+ var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 1);
+ var newJumps = CopyJumps(0);
+
+ // New path will be the last one.
+ int newPathIdx = newPaths.Length - 1;
+
+ // Apply updats to the new path.
+ ApplyUpdatesToPath(newPaths[newPathIdx], updates);
+
+ // Add new jump to the table.
+ newJumps[startEntry.Id] =
+ newJumps[startEntry.Id].CopyAndAdd(firstUpdate.FieldName, newPathIdx);
+
+ res = new PortableTypeStructure(newPaths, newJumps, res._fieldTypes);
+ }
+ else
+ {
+ // We are on existing entry. Need to create a new jump table here and two new paths.
+
+ // 1. Preapare new structures.
+ var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 2);
+ var newJumps = CopyJumps(1);
+
+ // Old path will be moved here.
+ int oldPathIdx = newPaths.Length - 2;
+
+ // New path will reside here.
+ int newPathIdx = newPaths.Length - 1;
+
+ // Create new jump table.
+ int newJumpIdx = newJumps.Length - 1;
+
+ newJumps[newJumpIdx] = new PortableTypeStructureJumpTable(startEntry.Name, oldPathIdx,
+ firstUpdate.FieldName, newPathIdx);
+
+ // Re-create old path in two steps: move old path to the new place, then clean the old path.
+ for (int i = firstUpdate.Index; i < path.Length; i++)
+ {
+ newPaths[oldPathIdx][i] = newPaths[pathIdx][i];
+
+ newPaths[pathIdx][i] = new PortableTypeStructureEntry();
+ }
+
+ // Apply updats to the new path.
+ ApplyUpdatesToPath(newPaths[newPaths.Length - 1], updates);
+
+ res = new PortableTypeStructure(newPaths, newJumps, res._fieldTypes);
+ }
+
+ }
+ }
+
+ return res;
+ }
+
+ /// <summary>
+ /// Copy and possible expand paths.
+ /// </summary>
+ /// <param name="minLen">Minimum length.</param>
+ /// <param name="additionalPaths">Amount of additional paths required.</param>
+ /// <returns>Result.</returns>
+ private PortableTypeStructureEntry[][] CopyPaths(int minLen, int additionalPaths)
+ {
+ var newPaths = new PortableTypeStructureEntry[_paths.Length + additionalPaths][];
+
+ int newPathLen = Math.Max(_paths[0].Length, minLen);
+
+ for (int i = 0; i < _paths.Length; i++)
+ {
+ newPaths[i] = new PortableTypeStructureEntry[newPathLen];
+
+ Array.Copy(_paths[i], newPaths[i], _paths[i].Length);
+ }
+
+ return newPaths;
+ }
+
+ /// <summary>
+ /// Copy and possible expand jump tables.
+ /// </summary>
+ /// <param name="additionalJumps">Additional jumps.</param>
+ /// <returns>Result.</returns>
+ private PortableTypeStructureJumpTable[] CopyJumps(int additionalJumps)
+ {
+ var newJumps = new PortableTypeStructureJumpTable[_jumps.Length + additionalJumps];
+
+ for (int i = 0; i < _jumps.Length; i++)
+ newJumps[i] = _jumps[i].Copy();
+
+ return newJumps;
+ }
+
+ /// <summary>
+ /// Apply updates to path.
+ /// </summary>
+ /// <param name="path">Path.</param>
+ /// <param name="updates">Updates.</param>
+ private static void ApplyUpdatesToPath(IList<PortableTypeStructureEntry> path,
+ IEnumerable<PortableTypeStructureUpdate> updates)
+ {
+ foreach (var u in updates)
+ path[u.Index] = new PortableTypeStructureEntry(u.FieldName, u.FieldId, u.FieldType);
+ }
+
+ /// <summary>
+ /// Merge field types.
+ /// </summary>
+ /// <param name="updates">Updates.</param>
+ /// <returns>Type structure with applied updates.</returns>
+ private PortableTypeStructure MergeFieldTypes(IList<PortableTypeStructureUpdate> updates)
+ {
+ IDictionary<string, byte> newFieldTypes = new Dictionary<string, byte>(_fieldTypes);
+
+ foreach (PortableTypeStructureUpdate update in updates)
+ {
+ byte expType;
+
+ if (_fieldTypes.TryGetValue(update.FieldName, out expType))
+ {
+ // This is an old field.
+ if (expType != update.FieldType)
+ {
+ throw new PortableException("Field type mismatch detected [fieldName=" + update.FieldName +
+ ", expectedType=" + expType + ", actualType=" + update.FieldType + ']');
+ }
+ }
+ else
+ // This is a new field.
+ newFieldTypes[update.FieldName] = update.FieldType;
+ }
+
+ return newFieldTypes.Count == _fieldTypes.Count ?
+ this : new PortableTypeStructure(_paths, _jumps, newFieldTypes);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs
new file mode 100644
index 0000000..e939d56
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
+{
+ using System.Diagnostics;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Portable type structure entry. Might be either a normal field or a reference to jump table.
+ /// </summary>
+ internal struct PortableTypeStructureEntry
+ {
+ /** Field name. */
+ private readonly string _name;
+
+ /** Field ID. */
+ private readonly int _id;
+
+ /** Field type. */
+ private readonly byte _type;
+
+ /// <summary>
+ /// Constructor for jump table entry.
+ /// </summary>
+ /// <param name="jumpTblIdx"></param>
+ public PortableTypeStructureEntry(int jumpTblIdx)
+ {
+ Debug.Assert(jumpTblIdx > 0);
+
+ _name = null;
+ _id = jumpTblIdx;
+ _type = 0;
+ }
+
+ /// <summary>
+ /// Constructor for field entry.
+ /// </summary>
+ /// <param name="name">Field name.</param>
+ /// <param name="id">Field ID.</param>
+ /// <param name="type">Field type.</param>
+ public PortableTypeStructureEntry(string name, int id, byte type)
+ {
+ Debug.Assert(name != null);
+
+ _name = name;
+ _id = id;
+ _type = type;
+ }
+
+ /// <summary>
+ /// Check whether current field entry matches passed arguments.
+ /// </summary>
+ /// <param name="name"></param>
+ /// <param name="type"></param>
+ /// <returns></returns>
+ public bool IsExpected(string name, byte type)
+ {
+ if (!ReferenceEquals(_name, name) && !_name.Equals(name))
+ return false;
+
+ ValidateType(type);
+
+ return true;
+ }
+
+ /// <summary>
+ /// Valide field type.
+ /// </summary>
+ /// <param name="type">Expected type.</param>
+ public void ValidateType(byte type)
+ {
+ if (_type != type)
+ {
+ throw new PortableException("Field type mismatch detected [fieldName=" + _name +
+ ", expectedType=" + _type + ", actualType=" + type + ']');
+ }
+ }
+
+ /// <summary>
+ /// Whether this is an empty entry.
+ /// </summary>
+ /// <returns></returns>
+ public bool IsEmpty
+ {
+ get { return _id == 0; }
+ }
+
+ /// <summary>
+ /// Whether this is a jump table.
+ /// </summary>
+ public bool IsJumpTable
+ {
+ get { return _name == null && _id >= 0; }
+ }
+
+ /// <summary>
+ /// Field name.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+
+ /// <summary>
+ /// Field ID.
+ /// </summary>
+ public int Id
+ {
+ get { return _id; }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs
new file mode 100644
index 0000000..b2409db
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
+{
+ using System;
+ using System.Diagnostics;
+
+ /// <summary>
+ /// Jump table.
+ /// </summary>
+ internal class PortableTypeStructureJumpTable
+ {
+ /** Names. */
+ private readonly string[] _names;
+
+ /** Path indexes. */
+ private readonly int[] _pathIdxs;
+
+ /// <summary>
+ /// Create jump table with two entries.
+ /// </summary>
+ /// <param name="firstName">First name.</param>
+ /// <param name="firstPathIdx">First path index.</param>
+ /// <param name="secondName">Second name.</param>
+ /// <param name="secondPathIdx">Second path index.</param>
+ public PortableTypeStructureJumpTable(string firstName, int firstPathIdx,
+ string secondName, int secondPathIdx)
+ {
+ _names = new[] { firstName, secondName };
+ _pathIdxs = new[] { firstPathIdx, secondPathIdx };
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="names">Field names.</param>
+ /// <param name="pathIdxs">Path indexes.</param>
+ private PortableTypeStructureJumpTable(string[] names, int[] pathIdxs)
+ {
+ Debug.Assert(_names.Length > 1);
+ Debug.Assert(_names.Length == pathIdxs.Length);
+
+ _names = names;
+ _pathIdxs = pathIdxs;
+ }
+
+ /// <summary>
+ /// Get path index for the given field.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <returns>Path index.</returns>
+ public int GetPathIndex(string fieldName)
+ {
+ Debug.Assert(fieldName != null);
+
+ // Optimistically assume that field name is a literal.
+ for (var i = 0; i < _names.Length; i++)
+ {
+ if (ReferenceEquals(fieldName, _names[i]))
+ return _pathIdxs[i];
+ }
+
+ // Fallback to slow-path with normal string comparison.
+ for (var i = 0; i < _names.Length; i++)
+ {
+ if (fieldName.Equals(_names[i]))
+ return _pathIdxs[i];
+ }
+
+ // No path found for the field.
+ return -1;
+ }
+
+ /// <summary>
+ /// Copy jump table.
+ /// </summary>
+ /// <returns>New jump table.</returns>
+ public PortableTypeStructureJumpTable Copy()
+ {
+ return new PortableTypeStructureJumpTable(_names, _pathIdxs);
+ }
+
+ /// <summary>
+ /// Copy jump table with additional jump.
+ /// </summary>
+ /// <param name="name">Field name.</param>
+ /// <param name="pathIdx">Path index.</param>
+ /// <returns>New jump table.</returns>
+ public PortableTypeStructureJumpTable CopyAndAdd(string name, int pathIdx)
+ {
+ var newNames = new string[_names.Length + 1];
+ var pathIdxs = new int[_pathIdxs.Length + 1];
+
+ Array.Copy(_names, newNames, _names.Length);
+ Array.Copy(_pathIdxs, pathIdxs, _pathIdxs.Length);
+
+ return new PortableTypeStructureJumpTable(newNames, pathIdxs);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs
new file mode 100644
index 0000000..56e0c12
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
+{
+ /// <summary>
+ /// Portable type structure update descriptor.
+ /// </summary>
+ class PortableTypeStructureUpdate
+ {
+ /** Field name. */
+ private readonly string _fieldName;
+
+ /** Field ID. */
+ private readonly int _fieldId;
+
+ /** Field type. */
+ private readonly byte _fieldType;
+
+ /** Field index. */
+ private readonly int _idx;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="fieldId">Field ID.</param>
+ /// <param name="fieldType">Field type.</param>
+ /// <param name="idx">Index.</param>
+ public PortableTypeStructureUpdate(string fieldName, int fieldId, byte fieldType, int idx)
+ {
+ _fieldName = fieldName;
+ _fieldId = fieldId;
+ _fieldType = fieldType;
+ _idx = idx;
+ }
+
+ /// <summary>
+ /// Field name.
+ /// </summary>
+ public string FieldName
+ {
+ get { return _fieldName; }
+ }
+
+ /// <summary>
+ /// Field ID.
+ /// </summary>
+ public int FieldId
+ {
+ get { return _fieldId; }
+ }
+
+ /// <summary>
+ /// Field type.
+ /// </summary>
+ public byte FieldType
+ {
+ get { return _fieldType; }
+ }
+
+ /// <summary>
+ /// Index.
+ /// </summary>
+ public int Index
+ {
+ get { return _idx; }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/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 79b860f..d1a714b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
@@ -18,6 +18,8 @@
namespace Apache.Ignite.Core.Impl.Portable
{
using System;
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
using Apache.Ignite.Core.Portable;
/// <summary>
@@ -55,6 +57,9 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Affinity field key name. */
private readonly string _affKeyFieldName;
+ /** Type structure. */
+ private volatile PortableTypeStructure _typeStruct = PortableTypeStructure.CreateEmpty();
+
/// <summary>
/// Constructor.
/// </summary>
@@ -171,5 +176,21 @@ namespace Apache.Ignite.Core.Impl.Portable
{
get { return _affKeyFieldName; }
}
+
+ /** <inheritDoc /> */
+ public PortableTypeStructure TypeStructure
+ {
+ get { return _typeStruct; }
+ }
+
+ /** <inheritDoc /> */
+ public void UpdateStrcuture(PortableTypeStructure exp, int pathIdx,
+ IList<PortableTypeStructureUpdate> updates)
+ {
+ lock (this)
+ {
+ _typeStruct = _typeStruct.Merge(exp, pathIdx, updates);
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/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 9842c46..adbb6bb 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
@@ -18,10 +18,13 @@
namespace Apache.Ignite.Core.Impl.Portable
{
using System;
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
using Apache.Ignite.Core.Portable;
/// <summary>
- /// Surrogate type descriptor. Used in cases when type if identified by name and is not provided in configuration.
+ /// Surrogate type descriptor. Used in cases when type if identified by name and
+ /// is not provided in configuration.
/// </summary>
internal class PortableSurrogateTypeDescriptor : IPortableTypeDescriptor
{
@@ -34,6 +37,9 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Type name. */
private readonly string _name;
+ /** Type structure. */
+ private volatile PortableTypeStructure _typeStruct = PortableTypeStructure.CreateEmpty();
+
/// <summary>
/// Constructor.
/// </summary>
@@ -117,5 +123,21 @@ namespace Apache.Ignite.Core.Impl.Portable
{
get { return null; }
}
+
+ /** <inheritDoc /> */
+ public PortableTypeStructure TypeStructure
+ {
+ get { return _typeStruct; }
+ }
+
+ /** <inheritDoc /> */
+ public void UpdateStrcuture(PortableTypeStructure exp, int pathIdx,
+ IList<PortableTypeStructureUpdate> updates)
+ {
+ lock (this)
+ {
+ _typeStruct = _typeStruct.Merge(exp, pathIdx, updates);
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
index 2344db2..fb0b195 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
@@ -1799,6 +1799,10 @@ namespace Apache.Ignite.Core.Impl.Portable
if (id == 0)
id = StringHashCode(fieldName);
+ if (id == 0)
+ throw new PortableException("Field ID is zero (please provide ID mapper or change field name) " +
+ "[typeId=" + typeId + ", fieldName=" + fieldName + ", idMapper=" + idMapper + ']');
+
return id;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9da45ed3/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 69523c9..6a0917a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -24,6 +24,7 @@ namespace Apache.Ignite.Core.Impl.Portable
using Apache.Ignite.Core.Impl.Portable.IO;
using Apache.Ignite.Core.Impl.Portable.Metadata;
+ using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
using Apache.Ignite.Core.Portable;
using PU = PortableUtils;
@@ -62,6 +63,12 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Current raw position. */
private long _curRawPos;
+
+ private PortableTypeStructure _curTypeStruct;
+ private int _curPathIdx;
+ private int _curActionIdx;
+ private bool _curNewStruct;
+ private List<PortableTypeStructureUpdate> _curUpdates;
/** Whether we are currently detaching an object. */
private bool _detaching;
@@ -1303,6 +1310,12 @@ namespace Apache.Ignite.Core.Impl.Portable
IPortableIdMapper oldMapper = _curMapper;
IPortableMetadataHandler oldMetaHnd = _curMetaHnd;
long oldRawPos = _curRawPos;
+
+ PortableTypeStructure oldTypeStruct = _curTypeStruct;
+ int oldPathIdx = _curPathIdx;
+ int oldActionIdx = _curActionIdx;
+ bool oldNewStruct = _curNewStruct;
+ var oldUpdates = _curUpdates;
// Push new frame.
_curTypeId = desc.TypeId;
@@ -1311,6 +1324,12 @@ namespace Apache.Ignite.Core.Impl.Portable
_curMetaHnd = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
_curRawPos = 0;
+ _curTypeStruct = desc.TypeStructure;
+ _curPathIdx = 0;
+ _curActionIdx = 0;
+ _curNewStruct = false;
+ _curUpdates = null;
+
// Write object fields.
desc.Serializer.WritePortable(obj, this);
@@ -1333,12 +1352,22 @@ namespace Apache.Ignite.Core.Impl.Portable
SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
}
+ // 14. Apply structure updates
+ if (_curUpdates != null)
+ desc.UpdateStrcuture(_curTypeStruct, _curPathIdx, _curUpdates);
+
// Restore old frame.
_curTypeId = oldTypeId;
_curConverter = oldConverter;
_curMapper = oldMapper;
_curMetaHnd = oldMetaHnd;
_curRawPos = oldRawPos;
+
+ _curTypeStruct = oldTypeStruct;
+ _curPathIdx = oldPathIdx;
+ _curActionIdx = oldActionIdx;
+ _curNewStruct = oldNewStruct;
+ _curUpdates = oldUpdates;
}
else
{
@@ -1595,10 +1624,38 @@ namespace Apache.Ignite.Core.Impl.Portable
if (_curRawPos != 0)
throw new PortableException("Cannot write named fields after raw data is written.");
- int fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+ int actionIdx = _curActionIdx++;
- _stream.WriteInt(fieldId);
+ int fieldId;
+
+ if (!_curNewStruct)
+ {
+ fieldId = _curTypeStruct.GetFieldId(fieldName, fieldTypeId, ref _curPathIdx, actionIdx);
+
+ if (fieldId == 0)
+ {
+ _curNewStruct = true;
+
+ fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+
+ if (_curUpdates == null)
+ _curUpdates = new List<PortableTypeStructureUpdate>();
+ _curUpdates.Add(new PortableTypeStructureUpdate(fieldName, fieldId, fieldTypeId, actionIdx));
+ }
+ }
+ else
+ {
+ fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+
+ if (_curUpdates == null)
+ _curUpdates = new List<PortableTypeStructureUpdate>();
+
+ _curUpdates.Add(new PortableTypeStructureUpdate(fieldName, fieldId, fieldTypeId, actionIdx));
+ }
+
+ _stream.WriteInt(fieldId);
+
if (_curMetaHnd != null)
_curMetaHnd.OnFieldWrite(fieldId, fieldName, fieldTypeId);
}
[4/4] ignite git commit: IGNITE-1282: Refactoring.
Posted by vo...@apache.org.
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 <vo...@gridgain.com>
Authored: Wed Oct 7 13:00:05 2015 +0300
Committer: vozerov-gridgain <vo...@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;
[3/4] ignite git commit: IGNITE-1282: Refactoring.
Posted by vo...@apache.org.
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/b34084eb
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b34084eb
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b34084eb
Branch: refs/heads/ignite-1282-opto
Commit: b34084eb053f4f2bd249bf5a51f487988e3030ac
Parents: 11f7d09
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Wed Oct 7 11:44:24 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Wed Oct 7 11:44:24 2015 +0300
----------------------------------------------------------------------
.../Apache.Ignite.Core.csproj | 8 +-
.../Impl/Portable/IPortableTypeDescriptor.cs | 6 +-
.../Metadata/Opto/PortableTypeStructure.cs | 317 -------------------
.../Metadata/Opto/PortableTypeStructureEntry.cs | 127 --------
.../Opto/PortableTypeStructureJumpTable.cs | 115 -------
.../Opto/PortableTypeStructureUpdate.cs | 84 -----
.../Impl/Portable/PortableFullTypeDescriptor.cs | 10 +-
.../Portable/PortableSurrogateTypeDescriptor.cs | 10 +-
.../Impl/Portable/PortableWriterImpl.cs | 70 ++--
.../Portable/Structure/PortableStructure.cs | 317 +++++++++++++++++++
.../Structure/PortableStructureEntry.cs | 128 ++++++++
.../Structure/PortableStructureJumpTable.cs | 115 +++++++
.../Structure/PortableStructureUpdate.cs | 84 +++++
13 files changed, 701 insertions(+), 690 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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 d412181..e8ec7ed 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -250,10 +250,6 @@
<Compile Include="Impl\Portable\IPortableTypeDescriptor.cs" />
<Compile Include="Impl\Portable\IPortableWriteAware.cs" />
<Compile Include="Impl\Portable\Metadata\IPortableMetadataHandler.cs" />
- <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructureEntry.cs" />
- <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructure.cs" />
- <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructureJumpTable.cs" />
- <Compile Include="Impl\Portable\Metadata\Opto\PortableTypeStructureUpdate.cs" />
<Compile Include="Impl\Portable\Metadata\PortableHashsetMetadataHandler.cs" />
<Compile Include="Impl\Portable\Metadata\PortableMetadataHolder.cs" />
<Compile Include="Impl\Portable\Metadata\PortableMetadataImpl.cs" />
@@ -279,6 +275,10 @@
<Compile Include="Impl\Portable\PortableUtils.cs" />
<Compile Include="Impl\Portable\PortableWriterImpl.cs" />
<Compile Include="Impl\Portable\SerializableObjectHolder.cs" />
+ <Compile Include="Impl\Portable\Structure\PortableStructure.cs" />
+ <Compile Include="Impl\Portable\Structure\PortableStructureEntry.cs" />
+ <Compile Include="Impl\Portable\Structure\PortableStructureJumpTable.cs" />
+ <Compile Include="Impl\Portable\Structure\PortableStructureUpdate.cs" />
<Compile Include="Impl\Portable\TypeResolver.cs" />
<Compile Include="Impl\Resource\IResourceInjector.cs" />
<Compile Include="Impl\Resource\ResourceFieldInjector.cs" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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 389238c..8a84daf 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
@@ -19,7 +19,7 @@ namespace Apache.Ignite.Core.Impl.Portable
{
using System;
using System.Collections.Generic;
- using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
+ using Apache.Ignite.Core.Impl.Portable.Structure;
using Apache.Ignite.Core.Portable;
/// <summary>
@@ -110,7 +110,7 @@ namespace Apache.Ignite.Core.Impl.Portable
/// <summary>
/// Type structure.
/// </summary>
- PortableTypeStructure TypeStructure { get; }
+ PortableStructure TypeStructure { get; }
/// <summary>
/// Update type structure.
@@ -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(PortableTypeStructure exp, int pathIdx, IList<PortableTypeStructureUpdate> updates);
+ void UpdateStrcuture(PortableStructure exp, int pathIdx, IList<PortableStructureUpdate> updates);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs
deleted file mode 100644
index cdc0859..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructure.cs
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
-
- using Apache.Ignite.Core.Portable;
-
- /// <summary>
- /// Portable type structure. Cache field IDs and metadata to improve marshalling performance.
- /// Every object write contains a set of field writes. Every unique ordered set of written fields
- /// produce write "path". We cache these paths allowing for very fast traverse over object structure
- /// without expensive map lookups and field ID calculations.
- /// </summary>
- internal class PortableTypeStructure
- {
- /// <summary>
- /// Create empty type structure.
- /// </summary>
- /// <returns>Empty type structure.</returns>
- public static PortableTypeStructure CreateEmpty()
- {
- return new PortableTypeStructure(new[] { new PortableTypeStructureEntry[0] },
- new PortableTypeStructureJumpTable[1], new Dictionary<string, byte>());
- }
-
- /** Entries. */
- private readonly PortableTypeStructureEntry[][] _paths;
-
- /** Jumps. */
- private readonly PortableTypeStructureJumpTable[] _jumps;
-
- /** Field types. */
- private readonly IDictionary<string, byte> _fieldTypes;
-
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="paths">Paths.</param>
- /// <param name="jumps">Jumps.</param>
- /// <param name="fieldTypes">Field types.</param>
- private PortableTypeStructure(PortableTypeStructureEntry[][] paths,
- PortableTypeStructureJumpTable[] jumps, IDictionary<string, byte> fieldTypes)
- {
- _paths = paths;
- _jumps = jumps;
- _fieldTypes = fieldTypes;
- }
-
- /// <summary>
- /// Gets field ID if possible.
- /// </summary>
- /// <param name="fieldName">Field name.</param>
- /// <param name="fieldType">Field type.</param>
- /// <param name="pathIdx">Path index, changes during jumps.</param>
- /// <param name="actionIdx">Action index.</param>
- /// <returns>Field ID or zero in case there are no matching path.</returns>
- public int GetFieldId(string fieldName, byte fieldType, ref int pathIdx, int actionIdx)
- {
- Debug.Assert(pathIdx <= _paths.Length);
-
- // Get path.
- PortableTypeStructureEntry[] path = _paths[pathIdx];
-
- if (actionIdx < path.Length)
- {
- // Get entry matching the action index.
- PortableTypeStructureEntry entry = path[actionIdx];
-
- if (entry.IsExpected(fieldName, fieldType))
- // Entry matches our expectations, return.
- return entry.Id;
- else if (entry.IsJumpTable)
- {
- // Entry is a pointer to a jump table.
- Debug.Assert(entry.Id < _jumps.Length);
-
- PortableTypeStructureJumpTable jmpTbl = _jumps[entry.Id];
-
- int pathIdx0 = jmpTbl.GetPathIndex(fieldName);
-
- if (pathIdx0 < 0)
- return 0;
-
- Debug.Assert(pathIdx < _paths.Length);
-
- entry = _paths[pathIdx][actionIdx];
-
- entry.ValidateType(fieldType);
-
- pathIdx = pathIdx0;
-
- return entry.Id;
- }
- }
-
- // Failed to find anything because this is a new field.
- return 0;
- }
-
- /// <summary>
- /// Merge updates into a new type structure.
- /// </summary>
- /// <param name="exp">Expected type structure to apply updates to </param>
- /// <param name="pathIdx">Path index.</param>
- /// <param name="updates">Updates.</param>
- /// <returns>New type structure with updates.</returns>
- public PortableTypeStructure Merge(PortableTypeStructure exp, int pathIdx,
- IList<PortableTypeStructureUpdate> updates)
- {
- if (updates.Count == 0)
- return this;
-
- // Algorithm ensures that updates are applied to the same type structure,
- // where they were initially observed. This allow us to keep structure
- // internals simpler and more efficient. On the other hand, this imposes
- // some performance hit because in case of concurrent update, recorded
- // changes will be discarded and recorded again during the next write
- // on the same path. This should occur only during application warmup.
-
- // Note that field types are merged anyway to avoid metadata clashes.
- PortableTypeStructure res = MergeFieldTypes(updates);
-
- if (ReferenceEquals(exp, this))
- {
- PortableTypeStructureUpdate firstUpdate = updates[0];
-
- if (firstUpdate.Index == 0)
- {
- // Special case: the very first structure update. Simply attach all updates.
- Debug.Assert(_paths.Length == 1);
- Debug.Assert(_paths[0].Length == 0);
- Debug.Assert(pathIdx == 0);
-
- PortableTypeStructureEntry[][] newPaths = CopyPaths(updates.Count, 0);
-
- ApplyUpdatesToPath(newPaths[0], updates);
-
- res = new PortableTypeStructure(newPaths, _jumps, res._fieldTypes);
- }
- else
- {
- // Get entry where updates should start.
- PortableTypeStructureEntry[] path = _paths[pathIdx];
-
- PortableTypeStructureEntry startEntry = default(PortableTypeStructureEntry);
-
- if (firstUpdate.Index < path.Length)
- startEntry = path[firstUpdate.Index];
-
- if (startEntry.IsEmpty)
- {
- // We are on the empty/non-existend entry. Continue the path without branching.
- var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 0);
-
- ApplyUpdatesToPath(newPaths[pathIdx], updates);
-
- res = new PortableTypeStructure(newPaths, _jumps, res._fieldTypes);
- }
- else if (startEntry.IsJumpTable)
- {
- // We are on the jump table. Add a new path and record it in the jump table.
-
- // 1. Preapare new structures.
- var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 1);
- var newJumps = CopyJumps(0);
-
- // New path will be the last one.
- int newPathIdx = newPaths.Length - 1;
-
- // Apply updats to the new path.
- ApplyUpdatesToPath(newPaths[newPathIdx], updates);
-
- // Add new jump to the table.
- newJumps[startEntry.Id] =
- newJumps[startEntry.Id].CopyAndAdd(firstUpdate.FieldName, newPathIdx);
-
- res = new PortableTypeStructure(newPaths, newJumps, res._fieldTypes);
- }
- else
- {
- // We are on existing entry. Need to create a new jump table here and two new paths.
-
- // 1. Preapare new structures.
- var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 2);
- var newJumps = CopyJumps(1);
-
- // Old path will be moved here.
- int oldPathIdx = newPaths.Length - 2;
-
- // New path will reside here.
- int newPathIdx = newPaths.Length - 1;
-
- // Create new jump table.
- int newJumpIdx = newJumps.Length - 1;
-
- newJumps[newJumpIdx] = new PortableTypeStructureJumpTable(startEntry.Name, oldPathIdx,
- firstUpdate.FieldName, newPathIdx);
-
- // Re-create old path in two steps: move old path to the new place, then clean the old path.
- for (int i = firstUpdate.Index; i < path.Length; i++)
- {
- newPaths[oldPathIdx][i] = newPaths[pathIdx][i];
-
- newPaths[pathIdx][i] = new PortableTypeStructureEntry();
- }
-
- // Apply updats to the new path.
- ApplyUpdatesToPath(newPaths[newPaths.Length - 1], updates);
-
- res = new PortableTypeStructure(newPaths, newJumps, res._fieldTypes);
- }
-
- }
- }
-
- return res;
- }
-
- /// <summary>
- /// Copy and possible expand paths.
- /// </summary>
- /// <param name="minLen">Minimum length.</param>
- /// <param name="additionalPaths">Amount of additional paths required.</param>
- /// <returns>Result.</returns>
- private PortableTypeStructureEntry[][] CopyPaths(int minLen, int additionalPaths)
- {
- var newPaths = new PortableTypeStructureEntry[_paths.Length + additionalPaths][];
-
- int newPathLen = Math.Max(_paths[0].Length, minLen);
-
- for (int i = 0; i < _paths.Length; i++)
- {
- newPaths[i] = new PortableTypeStructureEntry[newPathLen];
-
- Array.Copy(_paths[i], newPaths[i], _paths[i].Length);
- }
-
- return newPaths;
- }
-
- /// <summary>
- /// Copy and possible expand jump tables.
- /// </summary>
- /// <param name="additionalJumps">Additional jumps.</param>
- /// <returns>Result.</returns>
- private PortableTypeStructureJumpTable[] CopyJumps(int additionalJumps)
- {
- var newJumps = new PortableTypeStructureJumpTable[_jumps.Length + additionalJumps];
-
- for (int i = 0; i < _jumps.Length; i++)
- newJumps[i] = _jumps[i].Copy();
-
- return newJumps;
- }
-
- /// <summary>
- /// Apply updates to path.
- /// </summary>
- /// <param name="path">Path.</param>
- /// <param name="updates">Updates.</param>
- private static void ApplyUpdatesToPath(IList<PortableTypeStructureEntry> path,
- IEnumerable<PortableTypeStructureUpdate> updates)
- {
- foreach (var u in updates)
- path[u.Index] = new PortableTypeStructureEntry(u.FieldName, u.FieldId, u.FieldType);
- }
-
- /// <summary>
- /// Merge field types.
- /// </summary>
- /// <param name="updates">Updates.</param>
- /// <returns>Type structure with applied updates.</returns>
- private PortableTypeStructure MergeFieldTypes(IList<PortableTypeStructureUpdate> updates)
- {
- IDictionary<string, byte> newFieldTypes = new Dictionary<string, byte>(_fieldTypes);
-
- foreach (PortableTypeStructureUpdate update in updates)
- {
- byte expType;
-
- if (_fieldTypes.TryGetValue(update.FieldName, out expType))
- {
- // This is an old field.
- if (expType != update.FieldType)
- {
- throw new PortableException("Field type mismatch detected [fieldName=" + update.FieldName +
- ", expectedType=" + expType + ", actualType=" + update.FieldType + ']');
- }
- }
- else
- // This is a new field.
- newFieldTypes[update.FieldName] = update.FieldType;
- }
-
- return newFieldTypes.Count == _fieldTypes.Count ?
- this : new PortableTypeStructure(_paths, _jumps, newFieldTypes);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs
deleted file mode 100644
index e939d56..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureEntry.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
-{
- using System.Diagnostics;
- using Apache.Ignite.Core.Portable;
-
- /// <summary>
- /// Portable type structure entry. Might be either a normal field or a reference to jump table.
- /// </summary>
- internal struct PortableTypeStructureEntry
- {
- /** Field name. */
- private readonly string _name;
-
- /** Field ID. */
- private readonly int _id;
-
- /** Field type. */
- private readonly byte _type;
-
- /// <summary>
- /// Constructor for jump table entry.
- /// </summary>
- /// <param name="jumpTblIdx"></param>
- public PortableTypeStructureEntry(int jumpTblIdx)
- {
- Debug.Assert(jumpTblIdx > 0);
-
- _name = null;
- _id = jumpTblIdx;
- _type = 0;
- }
-
- /// <summary>
- /// Constructor for field entry.
- /// </summary>
- /// <param name="name">Field name.</param>
- /// <param name="id">Field ID.</param>
- /// <param name="type">Field type.</param>
- public PortableTypeStructureEntry(string name, int id, byte type)
- {
- Debug.Assert(name != null);
-
- _name = name;
- _id = id;
- _type = type;
- }
-
- /// <summary>
- /// Check whether current field entry matches passed arguments.
- /// </summary>
- /// <param name="name"></param>
- /// <param name="type"></param>
- /// <returns></returns>
- public bool IsExpected(string name, byte type)
- {
- if (!ReferenceEquals(_name, name) && !_name.Equals(name))
- return false;
-
- ValidateType(type);
-
- return true;
- }
-
- /// <summary>
- /// Valide field type.
- /// </summary>
- /// <param name="type">Expected type.</param>
- public void ValidateType(byte type)
- {
- if (_type != type)
- {
- throw new PortableException("Field type mismatch detected [fieldName=" + _name +
- ", expectedType=" + _type + ", actualType=" + type + ']');
- }
- }
-
- /// <summary>
- /// Whether this is an empty entry.
- /// </summary>
- /// <returns></returns>
- public bool IsEmpty
- {
- get { return _id == 0; }
- }
-
- /// <summary>
- /// Whether this is a jump table.
- /// </summary>
- public bool IsJumpTable
- {
- get { return _name == null && _id >= 0; }
- }
-
- /// <summary>
- /// Field name.
- /// </summary>
- public string Name
- {
- get { return _name; }
- }
-
- /// <summary>
- /// Field ID.
- /// </summary>
- public int Id
- {
- get { return _id; }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs
deleted file mode 100644
index b2409db..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureJumpTable.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
-{
- using System;
- using System.Diagnostics;
-
- /// <summary>
- /// Jump table.
- /// </summary>
- internal class PortableTypeStructureJumpTable
- {
- /** Names. */
- private readonly string[] _names;
-
- /** Path indexes. */
- private readonly int[] _pathIdxs;
-
- /// <summary>
- /// Create jump table with two entries.
- /// </summary>
- /// <param name="firstName">First name.</param>
- /// <param name="firstPathIdx">First path index.</param>
- /// <param name="secondName">Second name.</param>
- /// <param name="secondPathIdx">Second path index.</param>
- public PortableTypeStructureJumpTable(string firstName, int firstPathIdx,
- string secondName, int secondPathIdx)
- {
- _names = new[] { firstName, secondName };
- _pathIdxs = new[] { firstPathIdx, secondPathIdx };
- }
-
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="names">Field names.</param>
- /// <param name="pathIdxs">Path indexes.</param>
- private PortableTypeStructureJumpTable(string[] names, int[] pathIdxs)
- {
- Debug.Assert(_names.Length > 1);
- Debug.Assert(_names.Length == pathIdxs.Length);
-
- _names = names;
- _pathIdxs = pathIdxs;
- }
-
- /// <summary>
- /// Get path index for the given field.
- /// </summary>
- /// <param name="fieldName">Field name.</param>
- /// <returns>Path index.</returns>
- public int GetPathIndex(string fieldName)
- {
- Debug.Assert(fieldName != null);
-
- // Optimistically assume that field name is a literal.
- for (var i = 0; i < _names.Length; i++)
- {
- if (ReferenceEquals(fieldName, _names[i]))
- return _pathIdxs[i];
- }
-
- // Fallback to slow-path with normal string comparison.
- for (var i = 0; i < _names.Length; i++)
- {
- if (fieldName.Equals(_names[i]))
- return _pathIdxs[i];
- }
-
- // No path found for the field.
- return -1;
- }
-
- /// <summary>
- /// Copy jump table.
- /// </summary>
- /// <returns>New jump table.</returns>
- public PortableTypeStructureJumpTable Copy()
- {
- return new PortableTypeStructureJumpTable(_names, _pathIdxs);
- }
-
- /// <summary>
- /// Copy jump table with additional jump.
- /// </summary>
- /// <param name="name">Field name.</param>
- /// <param name="pathIdx">Path index.</param>
- /// <returns>New jump table.</returns>
- public PortableTypeStructureJumpTable CopyAndAdd(string name, int pathIdx)
- {
- var newNames = new string[_names.Length + 1];
- var pathIdxs = new int[_pathIdxs.Length + 1];
-
- Array.Copy(_names, newNames, _names.Length);
- Array.Copy(_pathIdxs, pathIdxs, _pathIdxs.Length);
-
- return new PortableTypeStructureJumpTable(newNames, pathIdxs);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs
deleted file mode 100644
index 56e0c12..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/Opto/PortableTypeStructureUpdate.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Apache.Ignite.Core.Impl.Portable.Metadata.Opto
-{
- /// <summary>
- /// Portable type structure update descriptor.
- /// </summary>
- class PortableTypeStructureUpdate
- {
- /** Field name. */
- private readonly string _fieldName;
-
- /** Field ID. */
- private readonly int _fieldId;
-
- /** Field type. */
- private readonly byte _fieldType;
-
- /** Field index. */
- private readonly int _idx;
-
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="fieldName">Field name.</param>
- /// <param name="fieldId">Field ID.</param>
- /// <param name="fieldType">Field type.</param>
- /// <param name="idx">Index.</param>
- public PortableTypeStructureUpdate(string fieldName, int fieldId, byte fieldType, int idx)
- {
- _fieldName = fieldName;
- _fieldId = fieldId;
- _fieldType = fieldType;
- _idx = idx;
- }
-
- /// <summary>
- /// Field name.
- /// </summary>
- public string FieldName
- {
- get { return _fieldName; }
- }
-
- /// <summary>
- /// Field ID.
- /// </summary>
- public int FieldId
- {
- get { return _fieldId; }
- }
-
- /// <summary>
- /// Field type.
- /// </summary>
- public byte FieldType
- {
- get { return _fieldType; }
- }
-
- /// <summary>
- /// Index.
- /// </summary>
- public int Index
- {
- get { return _idx; }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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 d1a714b..247a0b0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
@@ -19,7 +19,7 @@ namespace Apache.Ignite.Core.Impl.Portable
{
using System;
using System.Collections.Generic;
- using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
+ using Apache.Ignite.Core.Impl.Portable.Structure;
using Apache.Ignite.Core.Portable;
/// <summary>
@@ -58,7 +58,7 @@ namespace Apache.Ignite.Core.Impl.Portable
private readonly string _affKeyFieldName;
/** Type structure. */
- private volatile PortableTypeStructure _typeStruct = PortableTypeStructure.CreateEmpty();
+ private volatile PortableStructure _typeStruct = PortableStructure.CreateEmpty();
/// <summary>
/// Constructor.
@@ -178,14 +178,14 @@ namespace Apache.Ignite.Core.Impl.Portable
}
/** <inheritDoc /> */
- public PortableTypeStructure TypeStructure
+ public PortableStructure TypeStructure
{
get { return _typeStruct; }
}
/** <inheritDoc /> */
- public void UpdateStrcuture(PortableTypeStructure exp, int pathIdx,
- IList<PortableTypeStructureUpdate> updates)
+ public void UpdateStrcuture(PortableStructure exp, int pathIdx,
+ IList<PortableStructureUpdate> updates)
{
lock (this)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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 adbb6bb..103dd75 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
@@ -19,7 +19,7 @@ namespace Apache.Ignite.Core.Impl.Portable
{
using System;
using System.Collections.Generic;
- using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
+ using Apache.Ignite.Core.Impl.Portable.Structure;
using Apache.Ignite.Core.Portable;
/// <summary>
@@ -38,7 +38,7 @@ namespace Apache.Ignite.Core.Impl.Portable
private readonly string _name;
/** Type structure. */
- private volatile PortableTypeStructure _typeStruct = PortableTypeStructure.CreateEmpty();
+ private volatile PortableStructure _typeStruct = PortableStructure.CreateEmpty();
/// <summary>
/// Constructor.
@@ -125,14 +125,14 @@ namespace Apache.Ignite.Core.Impl.Portable
}
/** <inheritDoc /> */
- public PortableTypeStructure TypeStructure
+ public PortableStructure TypeStructure
{
get { return _typeStruct; }
}
/** <inheritDoc /> */
- public void UpdateStrcuture(PortableTypeStructure exp, int pathIdx,
- IList<PortableTypeStructureUpdate> updates)
+ public void UpdateStrcuture(PortableStructure exp, int pathIdx,
+ IList<PortableStructureUpdate> updates)
{
lock (this)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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 9727377..cafc69d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -24,7 +24,7 @@ namespace Apache.Ignite.Core.Impl.Portable
using Apache.Ignite.Core.Impl.Portable.IO;
using Apache.Ignite.Core.Impl.Portable.Metadata;
- using Apache.Ignite.Core.Impl.Portable.Metadata.Opto;
+ using Apache.Ignite.Core.Impl.Portable.Structure;
using Apache.Ignite.Core.Portable;
using PU = PortableUtils;
@@ -61,10 +61,17 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Current raw position. */
private long _curRawPos;
- private PortableTypeStructure _curTypeStruct;
- private int _curPathIdx;
- private int _curActionIdx;
- private List<PortableTypeStructureUpdate> _curUpdates;
+ /** Current type structure. */
+ private PortableStructure _curStruct;
+
+ /** Current type structure path index. */
+ private int _curStructPath;
+
+ /** Current type structure action index. */
+ private int _curStructAction;
+
+ /** Current type structure updates. */
+ private List<PortableStructureUpdate> _curStructUpdates;
/** Whether we are currently detaching an object. */
private bool _detaching;
@@ -1306,10 +1313,10 @@ namespace Apache.Ignite.Core.Impl.Portable
IPortableIdMapper oldMapper = _curMapper;
long oldRawPos = _curRawPos;
- PortableTypeStructure oldTypeStruct = _curTypeStruct;
- int oldPathIdx = _curPathIdx;
- int oldActionIdx = _curActionIdx;
- var oldUpdates = _curUpdates;
+ PortableStructure oldStruct = _curStruct;
+ int oldStructPath = _curStructPath;
+ int oldStructIdx = _curStructAction;
+ var oldStructUpdates = _curStructUpdates;
// Push new frame.
_curTypeId = desc.TypeId;
@@ -1317,10 +1324,10 @@ namespace Apache.Ignite.Core.Impl.Portable
_curMapper = desc.Mapper;
_curRawPos = 0;
- _curTypeStruct = desc.TypeStructure;
- _curPathIdx = 0;
- _curActionIdx = 0;
- _curUpdates = null;
+ _curStruct = desc.TypeStructure;
+ _curStructPath = 0;
+ _curStructAction = 0;
+ _curStructUpdates = null;
// Write object fields.
desc.Serializer.WritePortable(obj, this);
@@ -1335,16 +1342,16 @@ namespace Apache.Ignite.Core.Impl.Portable
else
_stream.WriteInt(pos + 14, len);
- // 13. Apply structure updates if any.
- if (_curUpdates != null)
+ // Apply structure updates if any.
+ if (_curStructUpdates != null)
{
- desc.UpdateStrcuture(_curTypeStruct, _curPathIdx, _curUpdates);
+ desc.UpdateStrcuture(_curStruct, _curStructPath, _curStructUpdates);
IPortableMetadataHandler metaHnd = _marsh.MetadataHandler(desc);
if (metaHnd != null)
{
- foreach (var u in _curUpdates)
+ foreach (var u in _curStructUpdates)
metaHnd.OnFieldWrite(u.FieldId, u.FieldName, u.FieldType);
IDictionary<string, int> meta = metaHnd.OnObjectWriteFinished();
@@ -1360,10 +1367,10 @@ namespace Apache.Ignite.Core.Impl.Portable
_curMapper = oldMapper;
_curRawPos = oldRawPos;
- _curTypeStruct = oldTypeStruct;
- _curPathIdx = oldPathIdx;
- _curActionIdx = oldActionIdx;
- _curUpdates = oldUpdates;
+ _curStruct = oldStruct;
+ _curStructPath = oldStructPath;
+ _curStructAction = oldStructIdx;
+ _curStructUpdates = oldStructUpdates;
}
else
{
@@ -1620,19 +1627,19 @@ namespace Apache.Ignite.Core.Impl.Portable
if (_curRawPos != 0)
throw new PortableException("Cannot write named fields after raw data is written.");
- int actionIdx = _curActionIdx++;
+ int action = _curStructAction++;
int fieldId;
- if (_curUpdates == null)
+ if (_curStructUpdates == null)
{
- fieldId = _curTypeStruct.GetFieldId(fieldName, fieldTypeId, ref _curPathIdx, actionIdx);
+ fieldId = _curStruct.GetFieldId(fieldName, fieldTypeId, ref _curStructPath, action);
if (fieldId == 0)
- fieldId = GetNewFieldId(fieldName, fieldTypeId, actionIdx);
+ fieldId = GetNewFieldId(fieldName, fieldTypeId, action);
}
else
- fieldId = GetNewFieldId(fieldName, fieldTypeId, actionIdx);
+ fieldId = GetNewFieldId(fieldName, fieldTypeId, action);
_stream.WriteInt(fieldId);
}
@@ -1640,15 +1647,18 @@ namespace Apache.Ignite.Core.Impl.Portable
/// <summary>
/// Get ID for the new field and save structure update.
/// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="fieldTypeId">Field type ID.</param>
+ /// <param name="action">Action index.</param>
/// <returns>Field ID.</returns>
- private int GetNewFieldId(string fieldName, byte fieldTypeId, int actionIdx)
+ private int GetNewFieldId(string fieldName, byte fieldTypeId, int action)
{
int fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
- if (_curUpdates == null)
- _curUpdates = new List<PortableTypeStructureUpdate>();
+ if (_curStructUpdates == null)
+ _curStructUpdates = new List<PortableStructureUpdate>();
- _curUpdates.Add(new PortableTypeStructureUpdate(fieldName, fieldId, fieldTypeId, actionIdx));
+ _curStructUpdates.Add(new PortableStructureUpdate(fieldName, fieldId, fieldTypeId, action));
return fieldId;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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
new file mode 100644
index 0000000..c434110
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructure.cs
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Structure
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Portable type structure. Cache field IDs and metadata to improve marshalling performance.
+ /// Every object write contains a set of field writes. Every unique ordered set of written fields
+ /// produce write "path". We cache these paths allowing for very fast traverse over object structure
+ /// without expensive map lookups and field ID calculations.
+ /// </summary>
+ internal class PortableStructure
+ {
+ /// <summary>
+ /// Create empty type structure.
+ /// </summary>
+ /// <returns>Empty type structure.</returns>
+ public static PortableStructure CreateEmpty()
+ {
+ return new PortableStructure(new[] { new PortableStructureEntry[0] },
+ new PortableStructureJumpTable[1], new Dictionary<string, byte>());
+ }
+
+ /** Entries. */
+ private readonly PortableStructureEntry[][] _paths;
+
+ /** Jumps. */
+ private readonly PortableStructureJumpTable[] _jumps;
+
+ /** Field types. */
+ private readonly IDictionary<string, byte> _fieldTypes;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="paths">Paths.</param>
+ /// <param name="jumps">Jumps.</param>
+ /// <param name="fieldTypes">Field types.</param>
+ private PortableStructure(PortableStructureEntry[][] paths,
+ PortableStructureJumpTable[] jumps, IDictionary<string, byte> fieldTypes)
+ {
+ _paths = paths;
+ _jumps = jumps;
+ _fieldTypes = fieldTypes;
+ }
+
+ /// <summary>
+ /// Gets field ID if possible.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="fieldType">Field type.</param>
+ /// <param name="pathIdx">Path index, changes during jumps.</param>
+ /// <param name="actionIdx">Action index.</param>
+ /// <returns>Field ID or zero in case there are no matching path.</returns>
+ public int GetFieldId(string fieldName, byte fieldType, ref int pathIdx, int actionIdx)
+ {
+ Debug.Assert(pathIdx <= _paths.Length);
+
+ // Get path.
+ PortableStructureEntry[] path = _paths[pathIdx];
+
+ if (actionIdx < path.Length)
+ {
+ // Get entry matching the action index.
+ PortableStructureEntry entry = path[actionIdx];
+
+ if (entry.IsExpected(fieldName, fieldType))
+ // Entry matches our expectations, return.
+ return entry.Id;
+ else if (entry.IsJumpTable)
+ {
+ // Entry is a pointer to a jump table.
+ Debug.Assert(entry.Id < _jumps.Length);
+
+ PortableStructureJumpTable jmpTbl = _jumps[entry.Id];
+
+ int pathIdx0 = jmpTbl.GetPathIndex(fieldName);
+
+ if (pathIdx0 < 0)
+ return 0;
+
+ Debug.Assert(pathIdx < _paths.Length);
+
+ entry = _paths[pathIdx][actionIdx];
+
+ entry.ValidateType(fieldType);
+
+ pathIdx = pathIdx0;
+
+ return entry.Id;
+ }
+ }
+
+ // Failed to find anything because this is a new field.
+ return 0;
+ }
+
+ /// <summary>
+ /// Merge updates into a new type structure.
+ /// </summary>
+ /// <param name="exp">Expected type structure to apply updates to </param>
+ /// <param name="pathIdx">Path index.</param>
+ /// <param name="updates">Updates.</param>
+ /// <returns>New type structure with updates.</returns>
+ public PortableStructure Merge(PortableStructure exp, int pathIdx,
+ IList<PortableStructureUpdate> updates)
+ {
+ if (updates.Count == 0)
+ return this;
+
+ // Algorithm ensures that updates are applied to the same type structure,
+ // where they were initially observed. This allow us to keep structure
+ // internals simpler and more efficient. On the other hand, this imposes
+ // some performance hit because in case of concurrent update, recorded
+ // changes will be discarded and recorded again during the next write
+ // on the same path. This should occur only during application warmup.
+
+ // Note that field types are merged anyway to avoid metadata clashes.
+ PortableStructure res = MergeFieldTypes(updates);
+
+ if (ReferenceEquals(exp, this))
+ {
+ PortableStructureUpdate firstUpdate = updates[0];
+
+ if (firstUpdate.Index == 0)
+ {
+ // Special case: the very first structure update. Simply attach all updates.
+ Debug.Assert(_paths.Length == 1);
+ Debug.Assert(_paths[0].Length == 0);
+ Debug.Assert(pathIdx == 0);
+
+ PortableStructureEntry[][] newPaths = CopyPaths(updates.Count, 0);
+
+ ApplyUpdatesToPath(newPaths[0], updates);
+
+ res = new PortableStructure(newPaths, _jumps, res._fieldTypes);
+ }
+ else
+ {
+ // Get entry where updates should start.
+ PortableStructureEntry[] path = _paths[pathIdx];
+
+ PortableStructureEntry startEntry = default(PortableStructureEntry);
+
+ if (firstUpdate.Index < path.Length)
+ startEntry = path[firstUpdate.Index];
+
+ if (startEntry.IsEmpty)
+ {
+ // We are on the empty/non-existend entry. Continue the path without branching.
+ var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 0);
+
+ ApplyUpdatesToPath(newPaths[pathIdx], updates);
+
+ res = new PortableStructure(newPaths, _jumps, res._fieldTypes);
+ }
+ else if (startEntry.IsJumpTable)
+ {
+ // We are on the jump table. Add a new path and record it in the jump table.
+
+ // 1. Preapare new structures.
+ var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 1);
+ var newJumps = CopyJumps(0);
+
+ // New path will be the last one.
+ int newPathIdx = newPaths.Length - 1;
+
+ // Apply updats to the new path.
+ ApplyUpdatesToPath(newPaths[newPathIdx], updates);
+
+ // Add new jump to the table.
+ newJumps[startEntry.Id] =
+ newJumps[startEntry.Id].CopyAndAdd(firstUpdate.FieldName, newPathIdx);
+
+ res = new PortableStructure(newPaths, newJumps, res._fieldTypes);
+ }
+ else
+ {
+ // We are on existing entry. Need to create a new jump table here and two new paths.
+
+ // 1. Preapare new structures.
+ var newPaths = CopyPaths(firstUpdate.Index + updates.Count, 2);
+ var newJumps = CopyJumps(1);
+
+ // Old path will be moved here.
+ int oldPathIdx = newPaths.Length - 2;
+
+ // New path will reside here.
+ int newPathIdx = newPaths.Length - 1;
+
+ // Create new jump table.
+ int newJumpIdx = newJumps.Length - 1;
+
+ newJumps[newJumpIdx] = new PortableStructureJumpTable(startEntry.Name, oldPathIdx,
+ firstUpdate.FieldName, newPathIdx);
+
+ // Re-create old path in two steps: move old path to the new place, then clean the old path.
+ for (int i = firstUpdate.Index; i < path.Length; i++)
+ {
+ newPaths[oldPathIdx][i] = newPaths[pathIdx][i];
+
+ newPaths[pathIdx][i] = new PortableStructureEntry();
+ }
+
+ // Apply updats to the new path.
+ ApplyUpdatesToPath(newPaths[newPaths.Length - 1], updates);
+
+ res = new PortableStructure(newPaths, newJumps, res._fieldTypes);
+ }
+
+ }
+ }
+
+ return res;
+ }
+
+ /// <summary>
+ /// Copy and possible expand paths.
+ /// </summary>
+ /// <param name="minLen">Minimum length.</param>
+ /// <param name="additionalPaths">Amount of additional paths required.</param>
+ /// <returns>Result.</returns>
+ private PortableStructureEntry[][] CopyPaths(int minLen, int additionalPaths)
+ {
+ var newPaths = new PortableStructureEntry[_paths.Length + additionalPaths][];
+
+ int newPathLen = Math.Max(_paths[0].Length, minLen);
+
+ for (int i = 0; i < _paths.Length; i++)
+ {
+ newPaths[i] = new PortableStructureEntry[newPathLen];
+
+ Array.Copy(_paths[i], newPaths[i], _paths[i].Length);
+ }
+
+ return newPaths;
+ }
+
+ /// <summary>
+ /// Copy and possible expand jump tables.
+ /// </summary>
+ /// <param name="additionalJumps">Additional jumps.</param>
+ /// <returns>Result.</returns>
+ private PortableStructureJumpTable[] CopyJumps(int additionalJumps)
+ {
+ var newJumps = new PortableStructureJumpTable[_jumps.Length + additionalJumps];
+
+ for (int i = 0; i < _jumps.Length; i++)
+ newJumps[i] = _jumps[i].Copy();
+
+ return newJumps;
+ }
+
+ /// <summary>
+ /// Apply updates to path.
+ /// </summary>
+ /// <param name="path">Path.</param>
+ /// <param name="updates">Updates.</param>
+ private static void ApplyUpdatesToPath(IList<PortableStructureEntry> path,
+ IEnumerable<PortableStructureUpdate> updates)
+ {
+ foreach (var u in updates)
+ path[u.Index] = new PortableStructureEntry(u.FieldName, u.FieldId, u.FieldType);
+ }
+
+ /// <summary>
+ /// Merge field types.
+ /// </summary>
+ /// <param name="updates">Updates.</param>
+ /// <returns>Type structure with applied updates.</returns>
+ private PortableStructure MergeFieldTypes(IList<PortableStructureUpdate> updates)
+ {
+ IDictionary<string, byte> newFieldTypes = new Dictionary<string, byte>(_fieldTypes);
+
+ foreach (PortableStructureUpdate update in updates)
+ {
+ byte expType;
+
+ if (_fieldTypes.TryGetValue(update.FieldName, out expType))
+ {
+ // This is an old field.
+ if (expType != update.FieldType)
+ {
+ throw new PortableException("Field type mismatch detected [fieldName=" + update.FieldName +
+ ", expectedType=" + expType + ", actualType=" + update.FieldType + ']');
+ }
+ }
+ else
+ // This is a new field.
+ newFieldTypes[update.FieldName] = update.FieldType;
+ }
+
+ return newFieldTypes.Count == _fieldTypes.Count ?
+ this : new PortableStructure(_paths, _jumps, newFieldTypes);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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
new file mode 100644
index 0000000..5229a95
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureEntry.cs
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Structure
+{
+ using System.Diagnostics;
+
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Portable type structure entry. Might be either a normal field or a reference to jump table.
+ /// </summary>
+ internal struct PortableStructureEntry
+ {
+ /** Field name. */
+ private readonly string _name;
+
+ /** Field ID. */
+ private readonly int _id;
+
+ /** Field type. */
+ private readonly byte _type;
+
+ /// <summary>
+ /// Constructor for jump table entry.
+ /// </summary>
+ /// <param name="jumpTblIdx">Jump table index.</param>
+ public PortableStructureEntry(int jumpTblIdx)
+ {
+ Debug.Assert(jumpTblIdx > 0);
+
+ _name = null;
+ _id = jumpTblIdx;
+ _type = 0;
+ }
+
+ /// <summary>
+ /// Constructor for field entry.
+ /// </summary>
+ /// <param name="name">Field name.</param>
+ /// <param name="id">Field ID.</param>
+ /// <param name="type">Field type.</param>
+ public PortableStructureEntry(string name, int id, byte type)
+ {
+ Debug.Assert(name != null);
+
+ _name = name;
+ _id = id;
+ _type = type;
+ }
+
+ /// <summary>
+ /// Check whether current field entry matches passed arguments.
+ /// </summary>
+ /// <param name="name"></param>
+ /// <param name="type"></param>
+ /// <returns></returns>
+ public bool IsExpected(string name, byte type)
+ {
+ if (!ReferenceEquals(_name, name) && !_name.Equals(name))
+ return false;
+
+ ValidateType(type);
+
+ return true;
+ }
+
+ /// <summary>
+ /// Valide field type.
+ /// </summary>
+ /// <param name="type">Expected type.</param>
+ public void ValidateType(byte type)
+ {
+ if (_type != type)
+ {
+ throw new PortableException("Field type mismatch detected [fieldName=" + _name +
+ ", expectedType=" + _type + ", actualType=" + type + ']');
+ }
+ }
+
+ /// <summary>
+ /// Whether this is an empty entry.
+ /// </summary>
+ /// <returns></returns>
+ public bool IsEmpty
+ {
+ get { return _id == 0; }
+ }
+
+ /// <summary>
+ /// Whether this is a jump table.
+ /// </summary>
+ public bool IsJumpTable
+ {
+ get { return _name == null && _id >= 0; }
+ }
+
+ /// <summary>
+ /// Field name.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+
+ /// <summary>
+ /// Field ID.
+ /// </summary>
+ public int Id
+ {
+ get { return _id; }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/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
new file mode 100644
index 0000000..85e71c4
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureJumpTable.cs
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Structure
+{
+ using System;
+ using System.Diagnostics;
+
+ /// <summary>
+ /// Jump table.
+ /// </summary>
+ internal class PortableStructureJumpTable
+ {
+ /** Names. */
+ private readonly string[] _names;
+
+ /** Path indexes. */
+ private readonly int[] _pathIdxs;
+
+ /// <summary>
+ /// Create jump table with two entries.
+ /// </summary>
+ /// <param name="firstName">First name.</param>
+ /// <param name="firstPathIdx">First path index.</param>
+ /// <param name="secondName">Second name.</param>
+ /// <param name="secondPathIdx">Second path index.</param>
+ public PortableStructureJumpTable(string firstName, int firstPathIdx,
+ string secondName, int secondPathIdx)
+ {
+ _names = new[] { firstName, secondName };
+ _pathIdxs = new[] { firstPathIdx, secondPathIdx };
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="names">Field names.</param>
+ /// <param name="pathIdxs">Path indexes.</param>
+ private PortableStructureJumpTable(string[] names, int[] pathIdxs)
+ {
+ Debug.Assert(_names.Length > 1);
+ Debug.Assert(_names.Length == pathIdxs.Length);
+
+ _names = names;
+ _pathIdxs = pathIdxs;
+ }
+
+ /// <summary>
+ /// Get path index for the given field.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <returns>Path index.</returns>
+ public int GetPathIndex(string fieldName)
+ {
+ Debug.Assert(fieldName != null);
+
+ // Optimistically assume that field name is a literal.
+ for (var i = 0; i < _names.Length; i++)
+ {
+ if (ReferenceEquals(fieldName, _names[i]))
+ return _pathIdxs[i];
+ }
+
+ // Fallback to slow-path with normal string comparison.
+ for (var i = 0; i < _names.Length; i++)
+ {
+ if (fieldName.Equals(_names[i]))
+ return _pathIdxs[i];
+ }
+
+ // No path found for the field.
+ return -1;
+ }
+
+ /// <summary>
+ /// Copy jump table.
+ /// </summary>
+ /// <returns>New jump table.</returns>
+ public PortableStructureJumpTable Copy()
+ {
+ return new PortableStructureJumpTable(_names, _pathIdxs);
+ }
+
+ /// <summary>
+ /// Copy jump table with additional jump.
+ /// </summary>
+ /// <param name="name">Field name.</param>
+ /// <param name="pathIdx">Path index.</param>
+ /// <returns>New jump table.</returns>
+ public PortableStructureJumpTable CopyAndAdd(string name, int pathIdx)
+ {
+ var newNames = new string[_names.Length + 1];
+ var pathIdxs = new int[_pathIdxs.Length + 1];
+
+ Array.Copy(_names, newNames, _names.Length);
+ Array.Copy(_pathIdxs, pathIdxs, _pathIdxs.Length);
+
+ return new PortableStructureJumpTable(newNames, pathIdxs);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b34084eb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs
new file mode 100644
index 0000000..fa239db
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Structure/PortableStructureUpdate.cs
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable.Structure
+{
+ /// <summary>
+ /// Portable type structure update descriptor.
+ /// </summary>
+ internal class PortableStructureUpdate
+ {
+ /** Field name. */
+ private readonly string _fieldName;
+
+ /** Field ID. */
+ private readonly int _fieldId;
+
+ /** Field type. */
+ private readonly byte _fieldType;
+
+ /** Field index. */
+ private readonly int _idx;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="fieldId">Field ID.</param>
+ /// <param name="fieldType">Field type.</param>
+ /// <param name="idx">Index.</param>
+ public PortableStructureUpdate(string fieldName, int fieldId, byte fieldType, int idx)
+ {
+ _fieldName = fieldName;
+ _fieldId = fieldId;
+ _fieldType = fieldType;
+ _idx = idx;
+ }
+
+ /// <summary>
+ /// Field name.
+ /// </summary>
+ public string FieldName
+ {
+ get { return _fieldName; }
+ }
+
+ /// <summary>
+ /// Field ID.
+ /// </summary>
+ public int FieldId
+ {
+ get { return _fieldId; }
+ }
+
+ /// <summary>
+ /// Field type.
+ /// </summary>
+ public byte FieldType
+ {
+ get { return _fieldType; }
+ }
+
+ /// <summary>
+ /// Index.
+ /// </summary>
+ public int Index
+ {
+ get { return _idx; }
+ }
+ }
+}
[2/4] ignite git commit: IGNITE-1282: WIP on optos.
Posted by vo...@apache.org.
IGNITE-1282: WIP on optos.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/11f7d097
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/11f7d097
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/11f7d097
Branch: refs/heads/ignite-1282-opto
Commit: 11f7d097da6c83b1dac8427e8294b098d98db898
Parents: 9da45ed
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Wed Oct 7 11:31:38 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Wed Oct 7 11:31:38 2015 +0300
----------------------------------------------------------------------
.../Portable/PortableWriteBenchmark.cs | 2 +-
.../Impl/Portable/PortableMarshaller.cs | 1 +
.../Impl/Portable/PortableWriterImpl.cs | 73 +++++++++-----------
3 files changed, 35 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/11f7d097/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
index 9fcfa46..5638195 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
@@ -46,7 +46,7 @@ namespace Apache.Ignite.Benchmarks.Portable
{
TypeConfigurations = new List<PortableTypeConfiguration>
{
- new PortableTypeConfiguration(typeof (Address)) {MetadataEnabled = false}
+ new PortableTypeConfiguration(typeof (Address)) {MetadataEnabled = true}
}
});
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/11f7d097/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
index c7a0b7b..c7262e1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
@@ -309,6 +309,7 @@ namespace Apache.Ignite.Core.Impl.Portable
return new PortableHashsetMetadataHandler(ids, newType);
}
+
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/11f7d097/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 6a0917a..9727377 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -57,9 +57,6 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Current mapper. */
private IPortableIdMapper _curMapper;
-
- /** Current metadata handler. */
- private IPortableMetadataHandler _curMetaHnd;
/** Current raw position. */
private long _curRawPos;
@@ -67,7 +64,6 @@ namespace Apache.Ignite.Core.Impl.Portable
private PortableTypeStructure _curTypeStruct;
private int _curPathIdx;
private int _curActionIdx;
- private bool _curNewStruct;
private List<PortableTypeStructureUpdate> _curUpdates;
/** Whether we are currently detaching an object. */
@@ -1308,26 +1304,22 @@ namespace Apache.Ignite.Core.Impl.Portable
int oldTypeId = _curTypeId;
IPortableNameMapper oldConverter = _curConverter;
IPortableIdMapper oldMapper = _curMapper;
- IPortableMetadataHandler oldMetaHnd = _curMetaHnd;
long oldRawPos = _curRawPos;
PortableTypeStructure oldTypeStruct = _curTypeStruct;
int oldPathIdx = _curPathIdx;
int oldActionIdx = _curActionIdx;
- bool oldNewStruct = _curNewStruct;
var oldUpdates = _curUpdates;
// Push new frame.
_curTypeId = desc.TypeId;
_curConverter = desc.NameConverter;
_curMapper = desc.Mapper;
- _curMetaHnd = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
_curRawPos = 0;
_curTypeStruct = desc.TypeStructure;
_curPathIdx = 0;
_curActionIdx = 0;
- _curNewStruct = false;
_curUpdates = null;
// Write object fields.
@@ -1343,30 +1335,34 @@ namespace Apache.Ignite.Core.Impl.Portable
else
_stream.WriteInt(pos + 14, len);
- // 13. Collect metadata.
- if (_curMetaHnd != null)
+ // 13. Apply structure updates if any.
+ if (_curUpdates != null)
{
- IDictionary<string, int> meta = _curMetaHnd.OnObjectWriteFinished();
+ desc.UpdateStrcuture(_curTypeStruct, _curPathIdx, _curUpdates);
+
+ IPortableMetadataHandler metaHnd = _marsh.MetadataHandler(desc);
+
+ if (metaHnd != null)
+ {
+ foreach (var u in _curUpdates)
+ metaHnd.OnFieldWrite(u.FieldId, u.FieldName, u.FieldType);
+
+ IDictionary<string, int> meta = metaHnd.OnObjectWriteFinished();
- if (meta != null)
- SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
+ if (meta != null)
+ SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
+ }
}
- // 14. Apply structure updates
- if (_curUpdates != null)
- desc.UpdateStrcuture(_curTypeStruct, _curPathIdx, _curUpdates);
-
// Restore old frame.
_curTypeId = oldTypeId;
_curConverter = oldConverter;
_curMapper = oldMapper;
- _curMetaHnd = oldMetaHnd;
_curRawPos = oldRawPos;
_curTypeStruct = oldTypeStruct;
_curPathIdx = oldPathIdx;
_curActionIdx = oldActionIdx;
- _curNewStruct = oldNewStruct;
_curUpdates = oldUpdates;
}
else
@@ -1628,36 +1624,33 @@ namespace Apache.Ignite.Core.Impl.Portable
int fieldId;
- if (!_curNewStruct)
+ if (_curUpdates == null)
{
fieldId = _curTypeStruct.GetFieldId(fieldName, fieldTypeId, ref _curPathIdx, actionIdx);
if (fieldId == 0)
- {
- _curNewStruct = true;
-
- fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
-
- if (_curUpdates == null)
- _curUpdates = new List<PortableTypeStructureUpdate>();
-
- _curUpdates.Add(new PortableTypeStructureUpdate(fieldName, fieldId, fieldTypeId, actionIdx));
- }
+ fieldId = GetNewFieldId(fieldName, fieldTypeId, actionIdx);
}
else
- {
- fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+ fieldId = GetNewFieldId(fieldName, fieldTypeId, actionIdx);
- if (_curUpdates == null)
- _curUpdates = new List<PortableTypeStructureUpdate>();
+ _stream.WriteInt(fieldId);
+ }
- _curUpdates.Add(new PortableTypeStructureUpdate(fieldName, fieldId, fieldTypeId, actionIdx));
- }
+ /// <summary>
+ /// Get ID for the new field and save structure update.
+ /// </summary>
+ /// <returns>Field ID.</returns>
+ private int GetNewFieldId(string fieldName, byte fieldTypeId, int actionIdx)
+ {
+ int fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
- _stream.WriteInt(fieldId);
-
- if (_curMetaHnd != null)
- _curMetaHnd.OnFieldWrite(fieldId, fieldName, fieldTypeId);
+ if (_curUpdates == null)
+ _curUpdates = new List<PortableTypeStructureUpdate>();
+
+ _curUpdates.Add(new PortableTypeStructureUpdate(fieldName, fieldId, fieldTypeId, actionIdx));
+
+ return fieldId;
}
/// <summary>