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/11/03 11:15:29 UTC
[1/2] ignite git commit: IGNITE-1418: Implemented compact field
offsets.
Repository: ignite
Updated Branches:
refs/heads/ignite-1282 fd640d7a8 -> 845c4f272
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/src/impl/portable/portable_schema.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/portable/portable_schema.cpp b/modules/platforms/cpp/core/src/impl/portable/portable_schema.cpp
index 57c23a7..448cf02 100644
--- a/modules/platforms/cpp/core/src/impl/portable/portable_schema.cpp
+++ b/modules/platforms/cpp/core/src/impl/portable/portable_schema.cpp
@@ -15,6 +15,8 @@
* limitations under the License.
*/
+#include <cassert>
+
#include "ignite/impl/portable/portable_schema.h"
#include "ignite/impl/portable/portable_writer_impl.h"
@@ -66,10 +68,43 @@ namespace ignite
void PortableSchema::Write(interop::InteropOutputStream& out) const
{
- for (FieldContainer::const_iterator i = fieldsInfo->begin(); i != fieldsInfo->end(); ++i)
+ switch (GetType())
{
- out.WriteInt32(i->id);
- out.WriteInt32(i->offset);
+ case OFFSET_TYPE_1_BYTE:
+ {
+ for (FieldContainer::const_iterator i = fieldsInfo->begin(); i != fieldsInfo->end(); ++i)
+ {
+ out.WriteInt32(i->id);
+ out.WriteInt8(static_cast<int8_t>(i->offset));
+ }
+ break;
+ }
+
+ case OFFSET_TYPE_2_BYTE:
+ {
+ for (FieldContainer::const_iterator i = fieldsInfo->begin(); i != fieldsInfo->end(); ++i)
+ {
+ out.WriteInt32(i->id);
+ out.WriteInt16(static_cast<int16_t>(i->offset));
+ }
+ break;
+ }
+
+ case OFFSET_TYPE_4_BYTE:
+ {
+ for (FieldContainer::const_iterator i = fieldsInfo->begin(); i != fieldsInfo->end(); ++i)
+ {
+ out.WriteInt32(i->id);
+ out.WriteInt32(i->offset);
+ }
+ break;
+ }
+
+ default:
+ {
+ assert(false);
+ break;
+ }
}
}
@@ -83,6 +118,18 @@ namespace ignite
id = 0;
fieldsInfo->clear();
}
+
+ PortableOffsetType PortableSchema::GetType() const
+ {
+ int32_t maxOffset = fieldsInfo->back().offset;
+
+ if (maxOffset < 0x100)
+ return OFFSET_TYPE_1_BYTE;
+ else if (maxOffset < 0x10000)
+ return OFFSET_TYPE_2_BYTE;
+
+ return OFFSET_TYPE_4_BYTE;
+ }
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/src/impl/portable/portable_writer_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/portable/portable_writer_impl.cpp b/modules/platforms/cpp/core/src/impl/portable/portable_writer_impl.cpp
index 4b65b4b..2dac125 100644
--- a/modules/platforms/cpp/core/src/impl/portable/portable_writer_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/portable/portable_writer_impl.cpp
@@ -567,13 +567,12 @@ namespace ignite
{
int32_t lenWithoutSchema = stream->Position() - start;
+ int32_t nonRawLen = rawPos == -1 ? lenWithoutSchema : rawPos - start;
+
if (schema.Empty())
{
- InteropStreamPositionGuard<InteropOutputStream> guard(*stream);
-
- stream->Position(start + IGNITE_OFFSET_FLAGS);
- stream->WriteInt16(IGNITE_PORTABLE_FLAG_USER_OBJECT | IGNITE_PORTABLE_FLAG_RAW_ONLY);
-
+ stream->WriteInt16(start + IGNITE_OFFSET_FLAGS, IGNITE_PORTABLE_FLAG_USER_OBJECT |
+ IGNITE_PORTABLE_FLAG_RAW_ONLY);
stream->WriteInt32(start + IGNITE_OFFSET_LEN, lenWithoutSchema);
stream->WriteInt32(start + IGNITE_OFFSET_SCHEMA_ID, 0);
stream->WriteInt32(start + IGNITE_OFFSET_SCHEMA_OR_RAW_OFF, GetRawPosition() - start);
@@ -581,6 +580,7 @@ namespace ignite
else
{
int32_t schemaId = schema.GetId();
+ PortableOffsetType schemaType = schema.GetType();
WriteAndClearSchema();
@@ -589,6 +589,17 @@ namespace ignite
int32_t length = stream->Position() - start;
+ if (schemaType == OFFSET_TYPE_1_BYTE)
+ {
+ stream->WriteInt16(start + IGNITE_OFFSET_FLAGS,
+ IGNITE_PORTABLE_FLAG_USER_OBJECT | IGNITE_PORTABLE_FLAG_OFFSET_1_BYTE);
+ }
+ else if (schemaType == OFFSET_TYPE_2_BYTE)
+ {
+ stream->WriteInt16(start + IGNITE_OFFSET_FLAGS,
+ IGNITE_PORTABLE_FLAG_USER_OBJECT | IGNITE_PORTABLE_FLAG_OFFSET_2_BYTE);
+ }
+
stream->WriteInt32(start + IGNITE_OFFSET_LEN, length);
stream->WriteInt32(start + IGNITE_OFFSET_SCHEMA_ID, schemaId);
stream->WriteInt32(start + IGNITE_OFFSET_SCHEMA_OR_RAW_OFF, lenWithoutSchema);
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
index 08e0b31..2313f92 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
@@ -1225,6 +1225,38 @@ namespace Apache.Ignite.Core.Tests.Portable
Assert.AreEqual(nDateArr, obj2.NDateArr);
}
+ /// <summary>
+ /// Writes objects of various sizes to test schema compaction
+ /// (where field offsets can be stored as 1, 2 or 4 bytes).
+ /// </summary>
+ [Test]
+ public void TestCompactSchema()
+ {
+ var marsh = new PortableMarshaller(new PortableConfiguration
+ {
+ TypeConfigurations = new List<PortableTypeConfiguration>
+ {
+ new PortableTypeConfiguration(typeof (SpecialArray)),
+ new PortableTypeConfiguration(typeof (SpecialArrayMarshalAware))
+ }
+ });
+
+ var dt = new SpecialArrayMarshalAware();
+
+ foreach (var i in new[] {1, 5, 10, 13, 14, 15, 100, 200, 1000, 5000, 15000, 30000})
+ {
+ dt.NGuidArr = Enumerable.Range(1, i).Select(x => (Guid?) Guid.NewGuid()).ToArray();
+ dt.NDateArr = Enumerable.Range(1, i).Select(x => (DateTime?) DateTime.Now.AddDays(x)).ToArray();
+
+ var bytes = marsh.Marshal(dt);
+
+ var res = marsh.Unmarshal<SpecialArrayMarshalAware>(bytes);
+
+ CollectionAssert.AreEquivalent(dt.NGuidArr, res.NGuidArr);
+ CollectionAssert.AreEquivalent(dt.NDateArr, res.NDateArr);
+ }
+ }
+
private static void CheckKeepSerialized(PortableConfiguration cfg, bool expKeep)
{
if (cfg.TypeConfigurations == null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/ResizeableArray.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/ResizeableArray.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/ResizeableArray.cs
index cb432e5..82a8eee 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/ResizeableArray.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/ResizeableArray.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -27,9 +27,6 @@ namespace Apache.Ignite.Core.Impl.Common
/** Array. */
private T[] _arr;
- /** Items count. */
- private int _count;
-
/// <summary>
/// Constructor.
/// </summary>
@@ -50,10 +47,7 @@ namespace Apache.Ignite.Core.Impl.Common
/// <summary>
/// Count.
/// </summary>
- public int Count
- {
- get { return _count; }
- }
+ public int Count { get; private set; }
/// <summary>
/// Add element.
@@ -61,10 +55,10 @@ namespace Apache.Ignite.Core.Impl.Common
/// <param name="element">Element.</param>
public void Add(T element)
{
- if (_count == _arr.Length)
+ if (Count == _arr.Length)
System.Array.Resize(ref _arr, _arr.Length*2);
- _arr[_count++] = element;
+ _arr[Count++] = element;
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
index ea109ba..c12a651 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
@@ -21,7 +21,6 @@ namespace Apache.Ignite.Core.Impl
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
- using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using Apache.Ignite.Core.Cache;
@@ -35,7 +34,6 @@ namespace Apache.Ignite.Core.Impl
/// <summary>
/// Managed environment. Acts as a gateway for native code.
/// </summary>
- [StructLayout(LayoutKind.Sequential)]
internal static class ExceptionUtils
{
/** NoClassDefFoundError fully-qualified class name which is important during startup phase. */
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
index 08a1d00..c299039 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
@@ -569,7 +569,7 @@ namespace Apache.Ignite.Core.Impl.Portable
/// <param name="hash">New hash.</param>
/// <param name="vals">Values to be replaced.</param>
/// <returns>Mutated object.</returns>
- private unsafe void Mutate0(Context ctx, PortableHeapStream inStream, IPortableStream outStream,
+ private void Mutate0(Context ctx, PortableHeapStream inStream, IPortableStream outStream,
bool changeHash, int hash, IDictionary<int, PortableBuilderField> vals)
{
int inStartPos = inStream.Position;
@@ -694,12 +694,14 @@ namespace Apache.Ignite.Core.Impl.Portable
// Write schema
int outSchemaOff = outRawOff;
+ short flags = 0;
if (outSchema != null)
{
outSchemaOff = outStream.Position - outStartPos;
- PortableObjectSchemaField.WriteArray(outSchema.Array, outStream, outSchema.Count);
+ flags = PortableObjectHeader.WriteSchema(outSchema.Array, outStream, outSchema.Count,
+ outStream.Position - outStartPos);
if (inRawLen > 0)
outStream.WriteInt(outRawOff);
@@ -712,7 +714,7 @@ namespace Apache.Ignite.Core.Impl.Portable
var outHash = changeHash ? hash : inHeader.HashCode;
var outHeader = new PortableObjectHeader(inHeader.IsUserType, inHeader.TypeId, outHash,
- outLen, outSchemaId, outSchemaOff, outSchema == null);
+ outLen, outSchemaId, outSchemaOff, outSchema == null, flags);
PortableObjectHeader.Write(outHeader, outStream, outStartPos);
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs
index b3768a0..50adc02 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs
@@ -27,17 +27,23 @@ namespace Apache.Ignite.Core.Impl.Portable
/// <summary>
/// Portable object header structure.
/// </summary>
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Sequential, Pack = 0)]
internal struct PortableObjectHeader : IEquatable<PortableObjectHeader>
{
- /** Size, equals to sizeof(PortableObjectHeader) */
+ /** Size, equals to sizeof(PortableObjectHeader). */
public const int Size = 24;
- /** User type flag */
- private const int FlagUserType = 0x1;
+ /** User type flag. */
+ public const short FlagUserType = 0x1;
- /** Raw only flag */
- private const int FlagRawOnly = 0x2;
+ /** Raw only flag. */
+ public const short FlagRawOnly = 0x2;
+
+ /** Byte-sized field offsets flag. */
+ public const short FlagByteOffsets = 0x4;
+
+ /** Short-sized field offsets flag. */
+ public const short FlagShortOffsets = 0x8;
/** Actual header layout */
public readonly byte Header; // Header code, always 103 (HdrFull)
@@ -50,7 +56,7 @@ namespace Apache.Ignite.Core.Impl.Portable
public readonly int SchemaOffset; // Schema offset, or raw offset when RawOnly flag is set.
/// <summary>
- /// Initializes a new instance of the <see cref="PortableObjectHeader"/> struct.
+ /// Initializes a new instance of the <see cref="PortableObjectHeader" /> struct.
/// </summary>
/// <param name="userType">User type flag.</param>
/// <param name="typeId">Type ID.</param>
@@ -59,18 +65,23 @@ namespace Apache.Ignite.Core.Impl.Portable
/// <param name="schemaId">Schema ID.</param>
/// <param name="schemaOffset">Schema offset.</param>
/// <param name="rawOnly">Raw flag.</param>
- public PortableObjectHeader(bool userType, int typeId, int hashCode, int length, int schemaId, int schemaOffset, bool rawOnly)
+ /// <param name="flags">The flags.</param>
+ public PortableObjectHeader(bool userType, int typeId, int hashCode, int length, int schemaId, int schemaOffset,
+ bool rawOnly, short flags)
{
Header = PortableUtils.HdrFull;
Version = PortableUtils.ProtoVer;
Debug.Assert(schemaOffset <= length);
Debug.Assert(schemaOffset >= Size);
-
- Flags = (short) (userType ? FlagUserType : 0);
+
+ if (userType)
+ flags |= FlagUserType;
if (rawOnly)
- Flags = (short) (Flags | FlagRawOnly);
+ flags |= FlagRawOnly;
+
+ Flags = flags;
TypeId = typeId;
HashCode = hashCode;
@@ -134,49 +145,50 @@ namespace Apache.Ignite.Core.Impl.Portable
{
get
{
- // Odd amount of records in schema => raw offset is the very last 4 bytes in object.
- return !IsRawOnly && (((Length - SchemaOffset) >> 2) & 0x1) != 0x0;
+ // Remainder => raw offset is the very last 4 bytes in object.
+ return !IsRawOnly && ((Length - SchemaOffset) % SchemaFieldSize) == 4;
}
}
/// <summary>
- /// Gets the schema field count.
+ /// Gets the size of the schema field offset (1, 2 or 4 bytes).
/// </summary>
- public int SchemaFieldCount
+ public int SchemaFieldOffsetSize
{
get
{
- if (IsRawOnly)
- return 0;
-
- var schemaSize = Length - SchemaOffset;
+ if ((Flags & FlagByteOffsets) == FlagByteOffsets)
+ return 1;
- if (HasRawOffset)
- schemaSize -= 4;
+ if ((Flags & FlagShortOffsets) == FlagShortOffsets)
+ return 2;
- return schemaSize >> 3; // 8 == PortableObjectSchemaField.Size
+ return 4;
}
}
/// <summary>
- /// Gets the schema end.
+ /// Gets the size of the schema field.
/// </summary>
- public int GetSchemaEnd(int position)
+ public int SchemaFieldSize
{
- var res = position + Length;
-
- if (HasRawOffset)
- res -= 4;
-
- return res;
+ get { return SchemaFieldOffsetSize + 4; }
}
/// <summary>
- /// Gets the schema start.
+ /// Gets the schema field count.
/// </summary>
- public int GetSchemaStart(int position)
+ public int SchemaFieldCount
{
- return IsRawOnly ? GetSchemaEnd(position) : position + SchemaOffset;
+ get
+ {
+ if (IsRawOnly)
+ return 0;
+
+ var schemaSize = Length - SchemaOffset;
+
+ return schemaSize / SchemaFieldSize;
+ }
}
/// <summary>
@@ -214,10 +226,25 @@ namespace Apache.Ignite.Core.Impl.Portable
stream.Seek(position + SchemaOffset, SeekOrigin.Begin);
- var schema = new Dictionary<int, int>(schemaSize >> 3);
+ var schema = new Dictionary<int, int>(schemaSize);
+
+ var offsetSize = SchemaFieldOffsetSize;
- for (var i = 0; i < schemaSize; i++)
- schema.Add(stream.ReadInt(), stream.ReadInt());
+ if (offsetSize == 1)
+ {
+ for (var i = 0; i < schemaSize; i++)
+ schema.Add(stream.ReadInt(), stream.ReadByte());
+ }
+ else if (offsetSize == 2)
+ {
+ for (var i = 0; i < schemaSize; i++)
+ schema.Add(stream.ReadInt(), stream.ReadShort());
+ }
+ else
+ {
+ for (var i = 0; i < schemaSize; i++)
+ schema.Add(stream.ReadInt(), stream.ReadInt());
+ }
return schema;
}
@@ -239,7 +266,98 @@ namespace Apache.Ignite.Core.Impl.Portable
stream.Seek(position + SchemaOffset, SeekOrigin.Begin);
- return PortableObjectSchemaField.ReadArray(stream, schemaSize);
+ var schema = new PortableObjectSchemaField[schemaSize];
+
+ var offsetSize = SchemaFieldOffsetSize;
+
+ if (offsetSize == 1)
+ {
+ for (var i = 0; i < schemaSize; i++)
+ schema[i] = new PortableObjectSchemaField(stream.ReadInt(), stream.ReadByte());
+ }
+ else if (offsetSize == 2)
+ {
+ for (var i = 0; i < schemaSize; i++)
+ schema[i] = new PortableObjectSchemaField(stream.ReadInt(), stream.ReadShort());
+ }
+ else
+ {
+ for (var i = 0; i < schemaSize; i++)
+ schema[i] = new PortableObjectSchemaField(stream.ReadInt(), stream.ReadInt());
+ }
+
+ return schema;
+ }
+
+ /// <summary>
+ /// Writes an array of fields to a stream.
+ /// </summary>
+ /// <param name="fields">Fields.</param>
+ /// <param name="stream">Stream.</param>
+ /// <param name="count">Field count to write.</param>
+ /// <param name="maxOffset">The maximum field offset to determine
+ /// whether 1, 2 or 4 bytes are needed for offsets.</param>
+ /// <returns>
+ /// Flags according to offset sizes: <see cref="PortableObjectHeader.FlagByteOffsets"/>,
+ /// <see cref="PortableObjectHeader.FlagShortOffsets"/>, or 0.
+ /// </returns>
+ public static unsafe short WriteSchema(PortableObjectSchemaField[] fields, IPortableStream stream, int count,
+ int maxOffset)
+ {
+ Debug.Assert(fields != null);
+ Debug.Assert(stream != null);
+ Debug.Assert(count > 0);
+
+ unchecked
+ {
+ if (maxOffset <= byte.MaxValue)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ var field = fields[i];
+
+ stream.WriteInt(field.Id);
+ stream.WriteByte((byte)field.Offset);
+ }
+
+ return FlagByteOffsets;
+ }
+
+ if (maxOffset <= ushort.MaxValue)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ var field = fields[i];
+
+ stream.WriteInt(field.Id);
+
+ stream.WriteShort((short)field.Offset);
+ }
+
+ return FlagShortOffsets;
+ }
+
+ if (BitConverter.IsLittleEndian)
+ {
+ fixed (PortableObjectSchemaField* ptr = &fields[0])
+ {
+ stream.Write((byte*)ptr, count / PortableObjectSchemaField.Size);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < count; i++)
+ {
+ var field = fields[i];
+
+ stream.WriteInt(field.Id);
+ stream.WriteInt(field.Offset);
+ }
+ }
+
+ return 0;
+ }
+
}
/// <summary>
@@ -284,6 +402,10 @@ namespace Apache.Ignite.Core.Impl.Portable
Debug.Assert(hdr.SchemaOffset <= hdr.Length);
Debug.Assert(hdr.SchemaOffset >= Size);
+ // Only one of the flags can be set
+ var f = hdr.Flags;
+ Debug.Assert((f & (FlagShortOffsets | FlagByteOffsets)) != (FlagShortOffsets | FlagByteOffsets));
+
return hdr;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs
index 7d3663c..51ae34e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs
@@ -20,7 +20,7 @@ namespace Apache.Ignite.Core.Impl.Portable
using System.Collections.Generic;
/// <summary>
- /// Holds and manages portable object schema for a specific type.
+ /// Holds and manages portable object schemas for a specific type.
/// </summary>
internal class PortableObjectSchema
{
@@ -44,7 +44,7 @@ namespace Apache.Ignite.Core.Impl.Portable
/// </summary>
/// <param name="id">Schema id.</param>
/// <returns>Schema or null.</returns>
- public int[] GetSchema(int id)
+ public int[] Get(int id)
{
if (_schemaId1 == id)
return _schema1;
@@ -65,7 +65,7 @@ namespace Apache.Ignite.Core.Impl.Portable
/// </summary>
/// <param name="id">Schema id.</param>
/// <param name="schema">Schema.</param>
- public void AddSchema(int id, int[] schema)
+ public void Add(int id, int[] schema)
{
lock (this)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs
index 48fd9c1..bc18191 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs
@@ -17,15 +17,12 @@
namespace Apache.Ignite.Core.Impl.Portable
{
- using System;
- using System.Diagnostics;
using System.Runtime.InteropServices;
- using Apache.Ignite.Core.Impl.Portable.IO;
/// <summary>
/// Portable schema field DTO (as it is stored in a stream).
/// </summary>
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Sequential, Pack = 0)]
internal struct PortableObjectSchemaField
{
/* Field ID */
@@ -35,7 +32,7 @@ namespace Apache.Ignite.Core.Impl.Portable
public readonly int Offset;
/** Size, equals to sizeof(PortableObjectSchemaField) */
- private const int Size = 8;
+ public const int Size = 8;
/// <summary>
/// Initializes a new instance of the <see cref="PortableObjectSchemaField"/> struct.
@@ -47,67 +44,5 @@ namespace Apache.Ignite.Core.Impl.Portable
Id = id;
Offset = offset;
}
-
- /// <summary>
- /// Writes an array of fields to a stream.
- /// </summary>
- /// <param name="fields">Fields.</param>
- /// <param name="stream">Stream.</param>
- /// <param name="count">Field count to write.</param>
- public static unsafe void WriteArray(PortableObjectSchemaField[] fields, IPortableStream stream, int count)
- {
- Debug.Assert(fields != null);
- Debug.Assert(stream != null);
- Debug.Assert(count > 0);
-
- if (BitConverter.IsLittleEndian)
- {
- fixed (PortableObjectSchemaField* ptr = &fields[0])
- {
- stream.Write((byte*) ptr, count * Size);
- }
- }
- else
- {
- for (int i = 0; i < count; i++)
- {
- var field = fields[i];
-
- stream.WriteInt(field.Id);
- stream.WriteInt(field.Offset);
- }
- }
- }
-
- /// <summary>
- /// Reads an array of fields from a stream.
- /// </summary>
- /// <param name="stream">Stream.</param>
- /// <param name="count">Count.</param>
- /// <returns></returns>
- public static unsafe PortableObjectSchemaField[] ReadArray(IPortableStream stream, int count)
- {
- Debug.Assert(stream != null);
- Debug.Assert(count > 0);
-
- var res = new PortableObjectSchemaField[count];
-
- if (BitConverter.IsLittleEndian)
- {
- fixed (PortableObjectSchemaField* ptr = &res[0])
- {
- stream.Read((byte*) ptr, count * Size);
- }
- }
- else
- {
- for (int i = 0; i < count; i++)
- {
- res[i] = new PortableObjectSchemaField(stream.ReadInt(), stream.ReadInt());
- }
- }
-
- return res;
- }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
index 48ea799..2b7ddb8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
@@ -45,15 +45,9 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Handles. */
private PortableReaderHandleDictionary _hnds;
- /** Current type ID. */
- private int _curTypeId;
-
/** Current position. */
private int _curPos;
- /** Current raw data offset. */
- private int _curRawOffset;
-
/** Current raw flag. */
private bool _curRaw;
@@ -66,14 +60,14 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Current type structure tracker. */
private PortableStructureTracker _curStruct;
- /** */
- private int _curFooterStart;
+ /** Current schema. */
+ private int[] _curSchema;
- /** */
- private int _curFooterEnd;
+ /** Current schema with positions. */
+ private Dictionary<int, int> _curSchemaMap;
- /** */
- private int[] _curSchema;
+ /** Current header. */
+ private PortableObjectHeader _curHdr;
/// <summary>
/// Constructor.
@@ -432,9 +426,7 @@ namespace Apache.Ignite.Core.Impl.Portable
if (_curRaw)
throw new PortableException("Cannot read named fields after raw data is read.");
- int fieldId = _curStruct.GetFieldId(fieldName);
-
- if (SeekField(fieldId))
+ if (SeekField(fieldName))
return Deserialize<T>();
return default(T);
@@ -669,31 +661,26 @@ namespace Apache.Ignite.Core.Impl.Portable
desc.TypeId + ", typeName=" + desc.TypeName + ']');
// Preserve old frame.
- int oldTypeId = _curTypeId;
+ var oldHdr = _curHdr;
int oldPos = _curPos;
- int oldRawOffset = _curRawOffset;
var oldStruct = _curStruct;
bool oldRaw = _curRaw;
- var oldFooterStart = _curFooterStart;
- var oldFooterEnd = _curFooterEnd;
var oldSchema = _curSchema;
+ var oldSchemaMap = _curSchemaMap;
// Set new frame.
- _curTypeId = hdr.TypeId;
+ _curHdr = hdr;
_curPos = pos;
- _curFooterEnd = hdr.GetSchemaEnd(pos);
- _curFooterStart = hdr.GetSchemaStart(pos);
- _curSchema = desc.Schema.GetSchema(hdr.SchemaId);
+ _curSchema = desc.Schema.Get(hdr.SchemaId);
if (_curSchema == null)
{
_curSchema = ReadSchema();
- desc.Schema.AddSchema(hdr.SchemaId, _curSchema);
+ desc.Schema.Add(hdr.SchemaId, _curSchema);
}
- _curRawOffset = hdr.GetRawOffset(Stream, pos);
_curStruct = new PortableStructureTracker(desc, desc.ReaderTypeStructure);
_curRaw = false;
@@ -727,14 +714,12 @@ namespace Apache.Ignite.Core.Impl.Portable
_curStruct.UpdateReaderStructure();
// Restore old frame.
- _curTypeId = oldTypeId;
+ _curHdr = oldHdr;
_curPos = oldPos;
- _curRawOffset = oldRawOffset;
_curStruct = oldStruct;
_curRaw = oldRaw;
- _curFooterStart = oldFooterStart;
- _curFooterEnd = oldFooterEnd;
_curSchema = oldSchema;
+ _curSchemaMap = oldSchemaMap;
// Process wrappers. We could introduce a common interface, but for only 2 if-else is faster.
var wrappedSerializable = obj as SerializableObjectHolder;
@@ -762,21 +747,22 @@ namespace Apache.Ignite.Core.Impl.Portable
/// </summary>
private int[] ReadSchema()
{
- Stream.Seek(_curFooterStart, SeekOrigin.Begin);
-
- var count = (_curFooterEnd - _curFooterStart) >> 3;
-
+ Stream.Seek(_curPos + _curHdr.SchemaOffset, SeekOrigin.Begin);
+
+ var count = _curHdr.SchemaFieldCount;
+
+ var offsetSize = _curHdr.SchemaFieldOffsetSize;
+
var res = new int[count];
for (int i = 0; i < count; i++)
{
res[i] = Stream.ReadInt();
- Stream.Seek(4, SeekOrigin.Current);
+ Stream.Seek(offsetSize, SeekOrigin.Current);
}
return res;
}
-
/// <summary>
/// Reads the handle object.
/// </summary>
@@ -846,38 +832,11 @@ namespace Apache.Ignite.Core.Impl.Portable
{
_curRaw = true;
- Stream.Seek(_curPos + _curRawOffset, SeekOrigin.Begin);
+ Stream.Seek(_curPos + _curHdr.GetRawOffset(Stream, _curPos), SeekOrigin.Begin);
}
}
/// <summary>
- /// Seek field with the given ID in the current object.
- /// </summary>
- /// <param name="fieldId">Field ID.</param>
- /// <returns>True in case the field was found and position adjusted, false otherwise.</returns>
- private bool SeekField(int fieldId)
- {
- Stream.Seek(_curFooterStart, SeekOrigin.Begin);
-
- while (Stream.Position < _curFooterEnd)
- {
- var id = Stream.ReadInt();
-
- if (id == fieldId)
- {
- var fieldOffset = Stream.ReadInt();
-
- Stream.Seek(_curPos + fieldOffset, SeekOrigin.Begin);
- return true;
- }
-
- Stream.Seek(4, SeekOrigin.Current);
- }
-
- return false;
- }
-
- /// <summary>
/// Determines whether header at current position is HDR_NULL.
/// </summary>
private bool IsNotNullHeader(byte expHdr)
@@ -899,23 +858,43 @@ namespace Apache.Ignite.Core.Impl.Portable
/// </summary>
private bool SeekField(string fieldName, byte expHdr)
{
+ if (!SeekField(fieldName))
+ return false;
+
+ // Expected read order, no need to seek.
+ return IsNotNullHeader(expHdr);
+ }
+
+ /// <summary>
+ /// Seeks the field by name.
+ /// </summary>
+ private bool SeekField(string fieldName)
+ {
if (_curRaw)
throw new PortableException("Cannot read named fields after raw data is read.");
+ if (_curHdr.IsRawOnly)
+ return false;
+
var actionId = _curStruct.CurStructAction;
var fieldId = _curStruct.GetFieldId(fieldName);
if (_curSchema == null || actionId >= _curSchema.Length || fieldId != _curSchema[actionId])
{
- _curSchema = null; // read order is different, ignore schema for future reads
+ _curSchema = null; // read order is different, ignore schema for future reads
+
+ _curSchemaMap = _curSchemaMap ?? _curHdr.ReadSchemaAsDictionary(Stream, _curPos);
+
+ int pos;
- if (!SeekField(fieldId))
+ if (!_curSchemaMap.TryGetValue(fieldId, out pos))
return false;
+
+ Stream.Seek(pos, SeekOrigin.Begin);
}
- // Expected read order, no need to seek.
- return IsNotNullHeader(expHdr);
+ return true;
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/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 a0657b2..79c4858 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
@@ -1804,7 +1804,7 @@ namespace Apache.Ignite.Core.Impl.Portable
/// <summary>
/// Struct with .Net-style Guid memory layout.
/// </summary>
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Sequential, Pack = 0)]
private struct GuidAccessor
{
public readonly ulong ABC;
@@ -1828,7 +1828,7 @@ namespace Apache.Ignite.Core.Impl.Portable
/// <summary>
/// Struct with Java-style Guid memory layout.
/// </summary>
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Sequential, Pack = 0)]
private struct JavaGuid
{
public readonly ulong CBA;
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/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 e17449d..66caca3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -73,7 +73,6 @@ namespace Apache.Ignite.Core.Impl.Portable
/** Current schema. */
private ResizeableArray<PortableObjectSchemaField> _curSchema;
-
/// <summary>
/// Gets the marshaller.
/// </summary>
@@ -1092,9 +1091,11 @@ namespace Apache.Ignite.Core.Impl.Portable
// Write schema
var hasSchema = _curSchema != null;
var schemaOffset = hasSchema ? _stream.Position - pos : PortableObjectHeader.Size;
+ short flags = 0;
if (hasSchema)
- PortableObjectSchemaField.WriteArray(_curSchema.Array, _stream, _curSchema.Count);
+ flags = PortableObjectHeader.WriteSchema(_curSchema.Array, _stream, _curSchema.Count,
+ _curSchema.Array[_curSchema.Count - 1].Offset);
// Calculate and write header.
if (hasSchema && _curRawPos > 0)
@@ -1103,7 +1104,7 @@ namespace Apache.Ignite.Core.Impl.Portable
var len = _stream.Position - pos;
var header = new PortableObjectHeader(desc.UserType, desc.TypeId, obj.GetHashCode(), len,
- PU.GetSchemaId(_curSchema), schemaOffset, !hasSchema);
+ PU.GetSchemaId(_curSchema), schemaOffset, !hasSchema, flags);
PortableObjectHeader.Write(header, _stream, pos);
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
index f48f120..e72ffac 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
@@ -166,7 +166,7 @@ namespace Apache.Ignite.Core.Impl.Portable
{
var len = PortableObjectHeader.Size;
- var hdr = new PortableObjectHeader(desc.UserType, desc.TypeId, 0, len, 0, len, true);
+ var hdr = new PortableObjectHeader(desc.UserType, desc.TypeId, 0, len, 0, len, true, 0);
var stream = new PortableHeapStream(len);
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
index 07cf309..8147e9d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
@@ -22,7 +22,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
/// <summary>
/// Unmanaged callback handler function pointers.
/// </summary>
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Sequential, Pack = 0)]
internal unsafe struct UnmanagedCallbackHandlers
{
internal void* target;
[2/2] ignite git commit: IGNITE-1418: Implemented compact field
offsets.
Posted by vo...@apache.org.
IGNITE-1418: Implemented compact field offsets.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/845c4f27
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/845c4f27
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/845c4f27
Branch: refs/heads/ignite-1282
Commit: 845c4f2722e69aa1f7ccd8ff619c52a013eb775a
Parents: fd640d7
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Nov 3 13:16:10 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Nov 3 13:16:10 2015 +0300
----------------------------------------------------------------------
.gitignore | 7 +
.../portable/PortableClassDescriptor.java | 33 ++-
.../internal/portable/PortableFieldImpl.java | 10 +-
.../internal/portable/PortableObjectEx.java | 2 +-
.../internal/portable/PortableObjectImpl.java | 46 ++-
.../portable/PortableObjectOffheapImpl.java | 89 +++++-
.../internal/portable/PortableReaderExImpl.java | 41 +--
.../internal/portable/PortableSchema.java | 133 ++++-----
.../ignite/internal/portable/PortableUtils.java | 46 ++-
.../internal/portable/PortableWriterExImpl.java | 76 ++++-
.../portable/builder/PortableBuilderImpl.java | 283 ++++++++++---------
.../src/portable_reader_writer_test.cpp | 251 +++++++++++++---
.../ignite/impl/interop/interop_input_stream.h | 16 ++
.../ignite/impl/interop/interop_output_stream.h | 8 +
.../ignite/impl/portable/portable_common.h | 6 +
.../ignite/impl/portable/portable_reader_impl.h | 29 +-
.../ignite/impl/portable/portable_schema.h | 26 +-
.../src/impl/interop/interop_input_stream.cpp | 20 ++
.../src/impl/interop/interop_output_stream.cpp | 7 +
.../src/impl/portable/portable_reader_impl.cpp | 45 ++-
.../core/src/impl/portable/portable_schema.cpp | 53 +++-
.../src/impl/portable/portable_writer_impl.cpp | 21 +-
.../Portable/PortableSelfTest.cs | 32 +++
.../Impl/Common/ResizeableArray.cs | 14 +-
.../Apache.Ignite.Core/Impl/ExceptionUtils.cs | 2 -
.../Impl/Portable/PortableBuilderImpl.cs | 8 +-
.../Impl/Portable/PortableObjectHeader.cs | 196 ++++++++++---
.../Impl/Portable/PortableObjectSchema.cs | 6 +-
.../Impl/Portable/PortableObjectSchemaField.cs | 69 +----
.../Impl/Portable/PortableReaderImpl.cs | 113 +++-----
.../Impl/Portable/PortableUtils.cs | 4 +-
.../Impl/Portable/PortableWriterImpl.cs | 7 +-
.../Impl/Portable/PortablesImpl.cs | 2 +-
.../Impl/Unmanaged/UnmanagedCallbackHandlers.cs | 2 +-
34 files changed, 1145 insertions(+), 558 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 3da8e4d..22e3cc6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,10 @@ target
pom-installed.xml
git-patch-prop-local.sh
/slurp.sh
+*.vcxproj.user
+Apache.Ignite.sdf
+ignite.sdf
+ignite.opensdf
+**/cpp/**/vs/x64/
+**/cpp/**/vs/Win32/
+**/dotnet/**/obj/
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
index 9f7f0c6..aa72017 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
@@ -524,12 +524,17 @@ public class PortableClassDescriptor {
case PORTABLE:
if (writeHeader(obj, writer)) {
- if (serializer != null)
- serializer.writePortable(obj, writer);
- else
- ((PortableMarshalAware)obj).writePortable(writer);
+ try {
+ if (serializer != null)
+ serializer.writePortable(obj, writer);
+ else
+ ((PortableMarshalAware) obj).writePortable(writer);
- writer.postWrite(userType);
+ writer.postWrite(userType);
+ }
+ finally {
+ writer.popSchema();
+ }
if (obj.getClass() != PortableMetaDataImpl.class
&& ctx.isMetaDataChanged(typeId, writer.metaDataHashSum())) {
@@ -552,22 +557,30 @@ public class PortableClassDescriptor {
try {
((Externalizable)obj).writeExternal(writer);
+
+ writer.postWrite(userType);
}
catch (IOException e) {
throw new PortableException("Failed to write Externalizable object: " + obj, e);
}
-
- writer.postWrite(userType);
+ finally {
+ writer.popSchema();
+ }
}
break;
case OBJECT:
if (writeHeader(obj, writer)) {
- for (FieldInfo info : fields)
- info.write(obj, writer);
+ try {
+ for (FieldInfo info : fields)
+ info.write(obj, writer);
- writer.postWrite(userType);
+ writer.postWrite(userType);
+ }
+ finally {
+ writer.popSchema();
+ }
}
break;
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
index 5780b76..12be55c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
@@ -45,7 +45,7 @@ public class PortableFieldImpl implements PortableField {
@Override public boolean exists(PortableObject obj) {
PortableObjectEx obj0 = (PortableObjectEx)obj;
- return fieldOffset(obj0) != 0;
+ return fieldOrder(obj0) != 0;
}
/** {@inheritDoc} */
@@ -53,9 +53,9 @@ public class PortableFieldImpl implements PortableField {
@Override public <T> T value(PortableObject obj) {
PortableObjectEx obj0 = (PortableObjectEx)obj;
- int offset = fieldOffset(obj0);
+ int order = fieldOrder(obj0);
- return offset != 0 ? (T)obj0.fieldByOffset(offset) : null;
+ return order != 0 ? (T)obj0.fieldByOrder(order) : null;
}
/**
@@ -64,7 +64,7 @@ public class PortableFieldImpl implements PortableField {
* @param obj Object.
* @return Field offset.
*/
- private int fieldOffset(PortableObjectEx obj) {
+ private int fieldOrder(PortableObjectEx obj) {
int schemaId = obj.schemaId();
PortableSchema schema = schemas.schema(schemaId);
@@ -77,6 +77,6 @@ public class PortableFieldImpl implements PortableField {
assert schema != null;
- return schema.offset(fieldId);
+ return schema.order(fieldId);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
index 42c973b..d6d7f50 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
@@ -72,7 +72,7 @@ public abstract class PortableObjectEx implements PortableObject {
* @param fieldOffset Field offset.
* @return Field value.
*/
- @Nullable protected abstract <F> F fieldByOffset(int fieldOffset);
+ @Nullable protected abstract <F> F fieldByOrder(int fieldOffset);
/**
* @param ctx Reader context.
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
index a1272d0..c7e01d7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
@@ -256,11 +256,25 @@ public final class PortableObjectImpl extends PortableObjectEx implements Extern
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
- @Nullable @Override protected <F> F fieldByOffset(int fieldOffset) {
+ @Nullable @Override protected <F> F fieldByOrder(int order) {
Object val;
+ // Calculate field position.
int schemaOffset = PortablePrimitives.readInt(arr, start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
- int fieldPos = PortablePrimitives.readInt(arr, start + schemaOffset + fieldOffset);
+
+ short flags = PortablePrimitives.readShort(arr, start + GridPortableMarshaller.FLAGS_POS);
+ int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
+
+ int fieldOffsetPos = start + schemaOffset + order * (4 + fieldOffsetSize) + 4;
+
+ int fieldPos;
+
+ if (fieldOffsetSize == PortableUtils.OFFSET_1)
+ fieldPos = start + (int)PortablePrimitives.readByte(arr, fieldOffsetPos) & 0xFF;
+ else if (fieldOffsetSize == PortableUtils.OFFSET_2)
+ fieldPos = start + (int)PortablePrimitives.readShort(arr, fieldOffsetPos) & 0xFFFF;
+ else
+ fieldPos = start + PortablePrimitives.readInt(arr, fieldOffsetPos);
// Read header and try performing fast lookup for well-known types (the most common types go first).
byte hdr = PortablePrimitives.readByte(arr, fieldPos);
@@ -306,36 +320,10 @@ public final class PortableObjectImpl extends PortableObjectEx implements Extern
break;
-// case DECIMAL:
-// val = doReadDecimal();
-//
-// break;
-//
-// case STRING:
-// val = doReadString();
-//
-// break;
-//
-// case UUID:
-// val = doReadUuid();
-//
-// break;
-//
-// case DATE:
-// val = doReadDate();
-//
-// break;
-//
-// case TIMESTAMP:
-// val = doReadTimestamp();
-//
-// break;
-
default: {
- // TODO: Pass absolute offset, not relative.
PortableReaderExImpl reader = new PortableReaderExImpl(ctx, arr, start, null);
- val = reader.unmarshalFieldByOffset(fieldOffset);
+ val = reader.unmarshalFieldByAbsolutePosition(fieldPos);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
index f023f2e..7ba5553 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
@@ -37,6 +37,15 @@ import org.apache.ignite.portable.PortableObject;
import org.jetbrains.annotations.Nullable;
import sun.misc.Unsafe;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.BYTE;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.INT;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT;
+
/**
* Portable object implementation over offheap memory
*/
@@ -179,13 +188,81 @@ public class PortableObjectOffheapImpl extends PortableObjectEx implements Exter
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
- @Nullable @Override protected <F> F fieldByOffset(int fieldOffset) {
- PortableReaderExImpl reader = new PortableReaderExImpl(ctx,
- new PortableOffheapInputStream(ptr, size, false),
- start,
- null);
+ @Nullable @Override protected <F> F fieldByOrder(int order) {
+ Object val;
+
+ // Calculate field position.
+ int schemaOffset = PortablePrimitives.readInt(ptr, start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
+
+ short flags = PortablePrimitives.readShort(ptr, start + GridPortableMarshaller.FLAGS_POS);
+ int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
+
+ int fieldOffsetPos = start + schemaOffset + order * (4 + fieldOffsetSize) + 4;
+
+ int fieldPos;
+
+ if (fieldOffsetSize == PortableUtils.OFFSET_1)
+ fieldPos = start + (int)PortablePrimitives.readByte(ptr, fieldOffsetPos) & 0xFF;
+ else if (fieldOffsetSize == PortableUtils.OFFSET_2)
+ fieldPos = start + (int)PortablePrimitives.readShort(ptr, fieldOffsetPos) & 0xFFFF;
+ else
+ fieldPos = start + PortablePrimitives.readInt(ptr, fieldOffsetPos);
+
+ // Read header and try performing fast lookup for well-known types (the most common types go first).
+ byte hdr = PortablePrimitives.readByte(ptr, fieldPos);
+
+ switch (hdr) {
+ case INT:
+ val = PortablePrimitives.readInt(ptr, fieldPos + 1);
+
+ break;
+
+ case LONG:
+ val = PortablePrimitives.readLong(ptr, fieldPos + 1);
+
+ break;
+
+ case BOOLEAN:
+ val = PortablePrimitives.readBoolean(ptr, fieldPos + 1);
+
+ break;
+
+ case SHORT:
+ val = PortablePrimitives.readShort(ptr, fieldPos + 1);
+
+ break;
+
+ case BYTE:
+ val = PortablePrimitives.readByte(ptr, fieldPos + 1);
+
+ break;
+
+ case CHAR:
+ val = PortablePrimitives.readChar(ptr, fieldPos + 1);
+
+ break;
+
+ case FLOAT:
+ val = PortablePrimitives.readFloat(ptr, fieldPos + 1);
+
+ break;
+
+ case DOUBLE:
+ val = PortablePrimitives.readDouble(ptr, fieldPos + 1);
+
+ break;
+
+ default: {
+ PortableReaderExImpl reader = new PortableReaderExImpl(ctx,
+ new PortableOffheapInputStream(ptr, size, false),
+ start,
+ null);
+
+ val = reader.unmarshalFieldByAbsolutePosition(fieldPos);
+ }
+ }
- return (F)reader.unmarshalFieldByOffset(fieldOffset);
+ return (F)val;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
index aa1519d..061a9fd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
@@ -163,6 +163,9 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
/** Schema Id. */
private int schemaId;
+ /** Offset size in bytes. */
+ private int offsetSize;
+
/** Object schema. */
private PortableSchema schema;
@@ -221,18 +224,20 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
PortableUtils.checkProtocolVersion(in.readByte());
- in.position(in.position() + 2); // Skip flags.
+ short flags = in.readShort();
+
+ offsetSize = PortableUtils.fieldOffsetSize(flags);
typeId = in.readIntPositioned(start + GridPortableMarshaller.TYPE_ID_POS);
- IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(in, start);
+ IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(in, start, offsetSize);
footerStart = footer.get1();
footerLen = footer.get2() - footerStart;
schemaId = in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_ID_POS);
- rawOff = PortableUtils.rawOffsetAbsolute(in, start);
+ rawOff = PortableUtils.rawOffsetAbsolute(in, start, offsetSize);
if (typeId == UNREGISTERED_TYPE_ID) {
// Skip to the class name position.
@@ -307,16 +312,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
}
/**
- * @param fieldOffset Field offset.
- * @return Unmarshalled value.
+ * Unmarshal field by absolute position.
+ *
+ * @param pos Absolute position.
+ * @return Field value.
* @throws PortableException In case of error.
*/
- @Nullable Object unmarshalFieldByOffset(int fieldOffset) throws PortableException {
- assert fieldOffset != 0;
-
+ @Nullable Object unmarshalFieldByAbsolutePosition(int pos) throws PortableException {
parseHeaderIfNeeded();
- in.position(start + in.readIntPositioned(footerStart + fieldOffset));
+ in.position(pos);
return unmarshal();
}
@@ -2567,12 +2572,14 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
int searchPos = footerStart;
int searchEnd = searchPos + footerLen;
+ int idx = 0;
+
while (searchPos < searchEnd) {
int fieldId = in.readIntPositioned(searchPos);
- fields.put(fieldId, searchPos + 4 - footerStart);
+ fields.put(fieldId, idx++);
- searchPos += 8;
+ searchPos += 4 + offsetSize;
}
return new PortableSchema(fields);
@@ -2599,14 +2606,14 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
int id0 = in.readIntPositioned(searchPos);
if (id0 == id) {
- int pos = start + in.readIntPositioned(searchPos + 4);
+ int pos = start + PortableUtils.fieldOffsetRelative(in, searchPos + 4, offsetSize);
in.position(pos);
return pos;
}
- searchPos += 8;
+ searchPos += 4 + offsetSize;
}
}
else {
@@ -2624,10 +2631,12 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
schema = schema0;
}
- int fieldOffsetPos = schema.offset(id);
+ int order = schema.order(id);
+
+ if (order != 0) {
+ int offsetPos = footerStart + order * (4 + offsetSize) + 4;
- if (fieldOffsetPos != 0) {
- int pos = start + in.readIntPositioned(footerStart + fieldOffsetPos);
+ int pos = start + PortableUtils.fieldOffsetRelative(in, offsetPos, offsetSize);
in.position(pos);
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
index 09bfe35..03be319 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
@@ -36,52 +36,28 @@ public class PortableSchema {
private final HashMap<Integer, Integer> map;
/** ID 1. */
- private final int id1;
-
- /** Offset 1. */
- private final int offset1;
+ private final int id0;
/** ID 2. */
- private final int id2;
-
- /** Offset 2. */
- private final int offset2;
+ private final int id1;
/** ID 3. */
- private final int id3;
-
- /** Offset 3. */
- private final int offset3;
+ private final int id2;
/** ID 4. */
- private final int id4;
-
- /** Offset 4. */
- private final int offset4;
+ private final int id3;
/** ID 1. */
- private final int id5;
-
- /** Offset 1. */
- private final int offset5;
+ private final int id4;
/** ID 2. */
- private final int id6;
-
- /** Offset 2. */
- private final int offset6;
+ private final int id5;
/** ID 3. */
- private final int id7;
-
- /** Offset 3. */
- private final int offset7;
+ private final int id6;
/** ID 4. */
- private final int id8;
-
- /** Offset 4. */
- private final int offset8;
+ private final int id7;
/**
* Constructor.
@@ -97,120 +73,111 @@ public class PortableSchema {
Map.Entry<Integer, Integer> entry = iter.hasNext() ? iter.next() : null;
if (entry != null) {
+ id0 = entry.getKey();
+
+ assert entry.getValue() == 0;
+ }
+ else
+ id0 = 0;
+
+ if ((entry = iter.hasNext() ? iter.next() : null) != null) {
id1 = entry.getKey();
- offset1 = entry.getValue();
+
+ assert entry.getValue() == 1;
}
- else{
+ else
id1 = 0;
- offset1 = 0;
- }
if ((entry = iter.hasNext() ? iter.next() : null) != null) {
id2 = entry.getKey();
- offset2 = entry.getValue();
+
+ assert entry.getValue() == 2;
}
- else{
+ else
id2 = 0;
- offset2 = 0;
- }
if ((entry = iter.hasNext() ? iter.next() : null) != null) {
id3 = entry.getKey();
- offset3 = entry.getValue();
+
+ assert entry.getValue() == 3;
}
- else{
+ else
id3 = 0;
- offset3 = 0;
- }
if ((entry = iter.hasNext() ? iter.next() : null) != null) {
id4 = entry.getKey();
- offset4 = entry.getValue();
+
+ assert entry.getValue() == 4;
}
- else{
+ else
id4 = 0;
- offset4 = 0;
- }
if ((entry = iter.hasNext() ? iter.next() : null) != null) {
id5 = entry.getKey();
- offset5 = entry.getValue();
+
+ assert entry.getValue() == 5;
}
- else{
+ else
id5 = 0;
- offset5 = 0;
- }
if ((entry = iter.hasNext() ? iter.next() : null) != null) {
id6 = entry.getKey();
- offset6 = entry.getValue();
+
+ assert entry.getValue() == 6;
}
- else{
+ else
id6 = 0;
- offset6 = 0;
- }
if ((entry = iter.hasNext() ? iter.next() : null) != null) {
id7 = entry.getKey();
- offset7 = entry.getValue();
- }
- else{
- id7 = 0;
- offset7 = 0;
- }
- if ((entry = iter.hasNext() ? iter.next() : null) != null) {
- id8 = entry.getKey();
- offset8 = entry.getValue();
- }
- else{
- id8 = 0;
- offset8 = 0;
+ assert entry.getValue() == 7;
}
+ else
+ id7 = 0;
map = null;
}
else {
inline = false;
- id1 = id2 = id3 = id4 = id5 = id6 = id7 = id8 = 0;
- offset1 = offset2 = offset3 = offset4 = offset5 = offset6 = offset7 = offset8 = 0;
+ id0 = id1 = id2 = id3 = id4 = id5 = id6 = id7 = 0;
map = new HashMap<>(vals);
}
}
/**
- * Get offset for the given field ID.
+ * Get field position in footer by schema ID.
*
* @param id Field ID.
* @return Offset or {@code 0} if there is no such field.
*/
- public int offset(int id) {
+ public int order(int id) {
if (inline) {
+ if (id == id0)
+ return 0;
+
if (id == id1)
- return offset1;
+ return 1;
if (id == id2)
- return offset2;
+ return 2;
if (id == id3)
- return offset3;
+ return 3;
if (id == id4)
- return offset4;
+ return 4;
if (id == id5)
- return offset5;
+ return 5;
if (id == id6)
- return offset6;
+ return 6;
if (id == id7)
- return offset7;
-
- if (id == id8)
- return offset8;
+ return 7;
return 0;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
index f57a29b..4e3538c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
@@ -619,14 +619,16 @@ public class PortableUtils {
*
* @param in Input stream.
* @param start Start position.
+ * @param fieldOffsetSize Field offset size.
* @return Footer.
*/
- public static IgniteBiTuple<Integer, Integer> footerAbsolute(PortablePositionReadable in, int start) {
+ public static IgniteBiTuple<Integer, Integer> footerAbsolute(PortablePositionReadable in, int start,
+ int fieldOffsetSize) {
int footerStart = footerStartRelative(in, start);
int footerEnd = length(in, start);
// Take in count possible raw offset.
- if ((((footerEnd - footerStart) >> 2) & 0x1) == 0x1)
+ if ((footerEnd - footerStart) % (4 + fieldOffsetSize) != 0)
footerEnd -= 4;
return F.t(start + footerStart, start + footerEnd);
@@ -637,9 +639,10 @@ public class PortableUtils {
*
* @param in Input stream.
* @param start Object start position inside the stream.
+ * @param fieldOffsetSize Field offset size.
* @return Raw offset.
*/
- public static int rawOffsetAbsolute(PortablePositionReadable in, int start) {
+ public static int rawOffsetAbsolute(PortablePositionReadable in, int start, int fieldOffsetSize) {
int len = length(in, start);
short flags = in.readShortPositioned(start + GridPortableMarshaller.FLAGS_POS);
@@ -651,7 +654,7 @@ public class PortableUtils {
// Schema exists.
int schemaOff = in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
- if ((((len - schemaOff) >> 2) & 0x1) == 0x0)
+ if (((len - schemaOff) % (4 + fieldOffsetSize)) == 0x0)
// Even amount of records in schema => no raw offset.
return start + schemaOff;
else
@@ -659,4 +662,39 @@ public class PortableUtils {
return start + in.readIntPositioned(start + len - 4);
}
}
+
+ /**
+ * Get offset size for the given flags.
+ * @param flags Flags.
+ * @return Offset size.
+ */
+ public static int fieldOffsetSize(short flags) {
+ if ((flags & FLAG_OFFSET_ONE_BYTE) == FLAG_OFFSET_ONE_BYTE)
+ return OFFSET_1;
+ else if ((flags & FLAG_OFFSET_TWO_BYTES) == FLAG_OFFSET_TWO_BYTES)
+ return OFFSET_2;
+ else
+ return OFFSET_4;
+ }
+
+ /**
+ * Get relative field offset.
+ *
+ * @param stream Stream.
+ * @param pos Position.
+ * @param fieldOffsetSize Field offset size.
+ * @return Relative field offset.
+ */
+ public static int fieldOffsetRelative(PortablePositionReadable stream, int pos, int fieldOffsetSize) {
+ int res;
+
+ if (fieldOffsetSize == PortableUtils.OFFSET_1)
+ res = (int)stream.readBytePositioned(pos) & 0xFF;
+ else if (fieldOffsetSize == PortableUtils.OFFSET_2)
+ res = (int)stream.readShortPositioned(pos) & 0xFFFF;
+ else
+ res = stream.readIntPositioned(pos);
+
+ return res;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
index 227087b..ff85ecd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
@@ -99,6 +99,12 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
/** FNV1 hash prime. */
private static final int FNV1_PRIME = 0x01000193;
+ /** Maximum offset which fits in 1 byte. */
+ private static final int MAX_OFFSET_1 = 1 << 8;
+
+ /** Maximum offset which fits in 2 bytes. */
+ private static final int MAX_OFFSET_2 = 1 << 16;
+
/** Thread-local schema. */
private static final ThreadLocal<SchemaHolder> SCHEMA = new ThreadLocal<>();
@@ -342,11 +348,22 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
out.writeInt(start + SCHEMA_OR_RAW_OFF_POS, out.position() - start);
// Write the schema.
- schema.writeAndPop(this, fieldCnt);
+ int offsetByteCnt = schema.write(this, fieldCnt);
// Write raw offset if needed.
if (rawOffPos != 0)
out.writeInt(rawOffPos - start);
+
+ if (offsetByteCnt == PortableUtils.OFFSET_1) {
+ int flags = (userType ? PortableUtils.FLAG_USR_TYP : 0) | PortableUtils.FLAG_OFFSET_ONE_BYTE;
+
+ out.writeShort(start + FLAGS_POS, (short)flags);
+ }
+ else if (offsetByteCnt == PortableUtils.OFFSET_2) {
+ int flags = (userType ? PortableUtils.FLAG_USR_TYP : 0) | PortableUtils.FLAG_OFFSET_TWO_BYTES;
+
+ out.writeShort(start + FLAGS_POS, (short)flags);
+ }
}
else {
// Write raw-only flag is needed.
@@ -363,6 +380,17 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
}
/**
+ * Pop schema.
+ */
+ public void popSchema() {
+ if (schema != null) {
+ assert fieldCnt > 0;
+
+ schema.pop(fieldCnt);
+ }
+ }
+
+ /**
* @param val Byte array.
*/
public void write(byte[] val) {
@@ -1833,19 +1861,51 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
* Write collected frames and pop them.
*
* @param writer Writer.
- * @param cnt Count.
+ * @param fieldCnt Count.
+ * @return Amount of bytes dedicated to
*/
- public void writeAndPop(PortableWriterExImpl writer, int cnt) {
- int startIdx = idx - cnt * 2;
+ public int write(PortableWriterExImpl writer, int fieldCnt) {
+ int startIdx = idx - fieldCnt * 2;
assert startIdx >= 0;
- for (int idx0 = startIdx; idx0 < idx;) {
- writer.writeInt(data[idx0++]);
- writer.writeInt(data[idx0++]);
+ int lastOffset = data[idx - 1];
+
+ int res;
+
+ if (lastOffset < MAX_OFFSET_1) {
+ for (int idx0 = startIdx; idx0 < idx; ) {
+ writer.writeInt(data[idx0++]);
+ writer.writeByte((byte) data[idx0++]);
+ }
+
+ res = PortableUtils.OFFSET_1;
}
+ else if (lastOffset < MAX_OFFSET_2) {
+ for (int idx0 = startIdx; idx0 < idx; ) {
+ writer.writeInt(data[idx0++]);
+ writer.writeShort((short)data[idx0++]);
+ }
+
+ res = PortableUtils.OFFSET_2;
+ }
+ else {
+ for (int idx0 = startIdx; idx0 < idx; ) {
+ writer.writeInt(data[idx0++]);
+ writer.writeInt(data[idx0++]);
+ }
- idx = startIdx;
+ res = PortableUtils.OFFSET_4;
+ }
+
+ return res;
+ }
+
+ /**
+ * Pop current object's frame.
+ */
+ public void pop(int fieldCnt) {
+ idx = idx - fieldCnt * 2;
// Shrink data array if needed.
if (idx == 0 && data.length > MAX_SIZE)
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
index 34e1d6d..608425d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
@@ -41,6 +41,7 @@ import java.util.Map;
import java.util.Set;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.DFLT_HDR_LEN;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLAGS_POS;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.HASH_CODE_POS;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROTO_VER_POS;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.TYPE_ID_POS;
@@ -77,12 +78,13 @@ public class PortableBuilderImpl implements PortableBuilder {
/** Position of object in source array, or -1 if object is not created from PortableObject. */
private final int start;
+ /** Flags. */
+ private final short flags;
+
/** Total header length */
private final int hdrLen;
- /**
- * Context of PortableObject reading process. Or {@code null} if object is not created from PortableObject.
- */
+ /** Context of PortableObject reading process. Or {@code null} if object is not created from PortableObject. */
private final PortableBuilderReader reader;
/** */
@@ -115,6 +117,7 @@ public class PortableBuilderImpl implements PortableBuilder {
this.ctx = ctx;
start = -1;
+ flags = -1;
reader = null;
hdrLen = DFLT_HDR_LEN;
@@ -137,6 +140,7 @@ public class PortableBuilderImpl implements PortableBuilder {
PortableBuilderImpl(PortableBuilderReader reader, int start) {
this.reader = reader;
this.start = start;
+ this.flags = reader.readShortPositioned(start + FLAGS_POS);
byte ver = reader.readBytePositioned(start + PROTO_VER_POS);
@@ -198,184 +202,188 @@ public class PortableBuilderImpl implements PortableBuilder {
* @param serializer Serializer.
*/
void serializeTo(PortableWriterExImpl writer, PortableBuilderSerializer serializer) {
- PortableUtils.writeHeader(writer,
- true,
- registeredType ? typeId : UNREGISTERED_TYPE_ID,
- hashCode,
- registeredType ? null : clsNameToWrite);
+ try {
+ PortableUtils.writeHeader(writer,
+ true,
+ registeredType ? typeId : UNREGISTERED_TYPE_ID,
+ hashCode,
+ registeredType ? null : clsNameToWrite);
- Set<Integer> remainsFlds = null;
+ Set<Integer> remainsFlds = null;
- if (reader != null) {
- Map<Integer, Object> assignedFldsById;
+ if (reader != null) {
+ Map<Integer, Object> assignedFldsById;
- if (assignedVals != null) {
- assignedFldsById = U.newHashMap(assignedVals.size());
+ if (assignedVals != null) {
+ assignedFldsById = U.newHashMap(assignedVals.size());
- for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
- int fldId = ctx.fieldId(typeId, entry.getKey());
+ for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
+ int fldId = ctx.fieldId(typeId, entry.getKey());
- assignedFldsById.put(fldId, entry.getValue());
- }
+ assignedFldsById.put(fldId, entry.getValue());
+ }
- remainsFlds = assignedFldsById.keySet();
- }
- else
- assignedFldsById = Collections.emptyMap();
+ remainsFlds = assignedFldsById.keySet();
+ } else
+ assignedFldsById = Collections.emptyMap();
- // Get footer details.
- IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start);
+ // Get footer details.
+ int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
- int footerPos = footer.get1();
- int footerEnd = footer.get2();
+ IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start, fieldOffsetSize);
- // Get raw position.
- int rawPos = PortableUtils.rawOffsetAbsolute(reader, start);
+ int footerPos = footer.get1();
+ int footerEnd = footer.get2();
- // Position reader on data.
- reader.position(start + hdrLen);
+ // Get raw position.
+ int rawPos = PortableUtils.rawOffsetAbsolute(reader, start, fieldOffsetSize);
- while (reader.position() < rawPos) {
- int fieldId = reader.readIntPositioned(footerPos);
- int fieldLen = fieldPositionAndLength(footerPos, footerEnd, rawPos).get2();
+ // Position reader on data.
+ reader.position(start + hdrLen);
- footerPos += 8;
+ while (reader.position() + 4 < rawPos) {
+ int fieldId = reader.readIntPositioned(footerPos);
+ int fieldLen = fieldPositionAndLength(footerPos, footerEnd, rawPos, fieldOffsetSize).get2();
- if (assignedFldsById.containsKey(fieldId)) {
- Object assignedVal = assignedFldsById.remove(fieldId);
+ footerPos += 4 + fieldOffsetSize;
- reader.skip(fieldLen);
+ if (assignedFldsById.containsKey(fieldId)) {
+ Object assignedVal = assignedFldsById.remove(fieldId);
- if (assignedVal != REMOVED_FIELD_MARKER) {
- writer.writeFieldId(fieldId);
+ reader.skip(fieldLen);
- serializer.writeValue(writer, assignedVal);
- }
- }
- else {
- int type = fieldLen != 0 ? reader.readByte(0) : 0;
+ if (assignedVal != REMOVED_FIELD_MARKER) {
+ writer.writeFieldId(fieldId);
- if (fieldLen != 0 && !PortableUtils.isPlainArrayType(type) && PortableUtils.isPlainType(type)) {
- writer.writeFieldId(fieldId);
- writer.write(reader.array(), reader.position(), fieldLen);
+ serializer.writeValue(writer, assignedVal);
+ }
+ } else {
+ int type = fieldLen != 0 ? reader.readByte(0) : 0;
- reader.skip(fieldLen);
- }
- else {
- writer.writeFieldId(fieldId);
+ if (fieldLen != 0 && !PortableUtils.isPlainArrayType(type) && PortableUtils.isPlainType(type)) {
+ writer.writeFieldId(fieldId);
+ writer.write(reader.array(), reader.position(), fieldLen);
- Object val;
+ reader.skip(fieldLen);
+ } else {
+ writer.writeFieldId(fieldId);
- if (fieldLen == 0)
- val = null;
- else if (readCache == null) {
- int savedPos = reader.position();
+ Object val;
- val = reader.parseValue();
+ if (fieldLen == 0)
+ val = null;
+ else if (readCache == null) {
+ int savedPos = reader.position();
- assert reader.position() == savedPos + fieldLen;
- }
- else {
- val = readCache.get(fieldId);
+ val = reader.parseValue();
- reader.skip(fieldLen);
- }
+ assert reader.position() == savedPos + fieldLen;
+ } else {
+ val = readCache.get(fieldId);
+
+ reader.skip(fieldLen);
+ }
- serializer.writeValue(writer, val);
+ serializer.writeValue(writer, val);
+ }
}
}
}
- }
-
- if (assignedVals != null && (remainsFlds == null || !remainsFlds.isEmpty())) {
- boolean metadataEnabled = ctx.isMetaDataEnabled(typeId);
- PortableMetadata metadata = null;
+ if (assignedVals != null && (remainsFlds == null || !remainsFlds.isEmpty())) {
+ boolean metadataEnabled = ctx.isMetaDataEnabled(typeId);
- if (metadataEnabled)
- metadata = ctx.metaData(typeId);
+ PortableMetadata metadata = null;
- Map<String, String> newFldsMetadata = null;
+ if (metadataEnabled)
+ metadata = ctx.metaData(typeId);
- for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
- Object val = entry.getValue();
+ Map<String, String> newFldsMetadata = null;
- if (val == REMOVED_FIELD_MARKER)
- continue;
-
- String name = entry.getKey();
+ for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
+ Object val = entry.getValue();
- int fldId = ctx.fieldId(typeId, name);
+ if (val == REMOVED_FIELD_MARKER)
+ continue;
- if (remainsFlds != null && !remainsFlds.contains(fldId))
- continue;
+ String name = entry.getKey();
- writer.writeFieldId(fldId);
+ int fldId = ctx.fieldId(typeId, name);
- serializer.writeValue(writer, val);
+ if (remainsFlds != null && !remainsFlds.contains(fldId))
+ continue;
- if (metadataEnabled) {
- String oldFldTypeName = metadata == null ? null : metadata.fieldTypeName(name);
+ writer.writeFieldId(fldId);
- String newFldTypeName;
+ serializer.writeValue(writer, val);
- if (val instanceof PortableValueWithType)
- newFldTypeName = ((PortableValueWithType)val).typeName();
- else {
- byte type = PortableUtils.typeByClass(val.getClass());
+ if (metadataEnabled) {
+ String oldFldTypeName = metadata == null ? null : metadata.fieldTypeName(name);
- newFldTypeName = CacheObjectPortableProcessorImpl.fieldTypeName(type);
- }
+ String newFldTypeName;
- if (oldFldTypeName == null) {
- // It's a new field, we have to add it to metadata.
+ if (val instanceof PortableValueWithType)
+ newFldTypeName = ((PortableValueWithType) val).typeName();
+ else {
+ byte type = PortableUtils.typeByClass(val.getClass());
- if (newFldsMetadata == null)
- newFldsMetadata = new HashMap<>();
+ newFldTypeName = CacheObjectPortableProcessorImpl.fieldTypeName(type);
+ }
- newFldsMetadata.put(name, newFldTypeName);
- }
- else {
- if (!"Object".equals(oldFldTypeName) && !oldFldTypeName.equals(newFldTypeName)) {
- throw new PortableException(
- "Wrong value has been set [" +
- "typeName=" + (typeName == null ? metadata.typeName() : typeName) +
- ", fieldName=" + name +
- ", fieldType=" + oldFldTypeName +
- ", assignedValueType=" + newFldTypeName +
- ", assignedValue=" + (((PortableValueWithType)val).value()) + ']'
- );
+ if (oldFldTypeName == null) {
+ // It's a new field, we have to add it to metadata.
+
+ if (newFldsMetadata == null)
+ newFldsMetadata = new HashMap<>();
+
+ newFldsMetadata.put(name, newFldTypeName);
+ } else {
+ if (!"Object".equals(oldFldTypeName) && !oldFldTypeName.equals(newFldTypeName)) {
+ throw new PortableException(
+ "Wrong value has been set [" +
+ "typeName=" + (typeName == null ? metadata.typeName() : typeName) +
+ ", fieldName=" + name +
+ ", fieldType=" + oldFldTypeName +
+ ", assignedValueType=" + newFldTypeName +
+ ", assignedValue=" + (((PortableValueWithType) val).value()) + ']'
+ );
+ }
}
}
}
- }
- if (newFldsMetadata != null) {
- String typeName = this.typeName;
+ if (newFldsMetadata != null) {
+ String typeName = this.typeName;
- if (typeName == null)
- typeName = metadata.typeName();
+ if (typeName == null)
+ typeName = metadata.typeName();
- ctx.updateMetaData(typeId, typeName, newFldsMetadata);
+ ctx.updateMetaData(typeId, typeName, newFldsMetadata);
+ }
}
- }
- if (reader != null) {
- // Write raw data if any.
- int rawOff = PortableUtils.rawOffsetAbsolute(reader, start);
- int footerStart = PortableUtils.footerStartAbsolute(reader, start);
+ if (reader != null) {
+ // Write raw data if any.
+ int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
+
+ int rawOff = PortableUtils.rawOffsetAbsolute(reader, start, fieldOffsetSize);
+ int footerStart = PortableUtils.footerStartAbsolute(reader, start);
- if (rawOff < footerStart) {
- writer.rawWriter();
+ if (rawOff < footerStart) {
+ writer.rawWriter();
- writer.write(reader.array(), rawOff, footerStart - rawOff);
+ writer.write(reader.array(), rawOff, footerStart - rawOff);
+ }
+
+ // Shift reader to the end of the object.
+ reader.position(start + PortableUtils.length(reader, start));
}
- // Shift reader to the end of the object.
- reader.position(start + PortableUtils.length(reader, start));
+ writer.postWrite(true);
+ }
+ finally {
+ writer.popSchema();
}
-
- writer.postWrite(true);
}
/** {@inheritDoc} */
@@ -391,21 +399,25 @@ public class PortableBuilderImpl implements PortableBuilder {
* @param footerPos Field position inside the footer (absolute).
* @param footerEnd Footer end (absolute).
* @param rawPos Raw data position (absolute).
+ * @param fieldOffsetSize Size of field's offset.
* @return Tuple with field position and length.
*/
- private IgniteBiTuple<Integer, Integer> fieldPositionAndLength(int footerPos, int footerEnd, int rawPos) {
- int fieldOffset = reader.readIntPositioned(footerPos + 4);
+ private IgniteBiTuple<Integer, Integer> fieldPositionAndLength(int footerPos, int footerEnd, int rawPos,
+ int fieldOffsetSize) {
+ // Get field offset first.
+ int fieldOffset = PortableUtils.fieldOffsetRelative(reader, footerPos + 4, fieldOffsetSize);
int fieldPos = start + fieldOffset;
// Get field length.
int fieldLen;
- if (footerPos + 8 == footerEnd)
+ if (footerPos + 4 + fieldOffsetSize == footerEnd)
// This is the last field, compare to raw offset.
fieldLen = rawPos - fieldPos;
else {
// Field is somewhere in the middle, get difference with the next offset.
- int nextFieldOffset = reader.readIntPositioned(footerPos + 8 + 4);
+ int nextFieldOffset = PortableUtils.fieldOffsetRelative(reader, footerPos + 4 + fieldOffsetSize + 4,
+ fieldOffsetSize);
fieldLen = nextFieldOffset - fieldOffset;
}
@@ -418,26 +430,29 @@ public class PortableBuilderImpl implements PortableBuilder {
*/
private void ensureReadCacheInit() {
if (readCache == null) {
+ int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
+
Map<Integer, Object> readCache = new HashMap<>();
- IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start);
+ IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start, fieldOffsetSize);
int footerPos = footer.get1();
int footerEnd = footer.get2();
- int rawPos = PortableUtils.rawOffsetAbsolute(reader, start);
+ int rawPos = PortableUtils.rawOffsetAbsolute(reader, start, fieldOffsetSize);
- while (footerPos < footerEnd) {
+ while (footerPos + 4 < footerEnd) {
int fieldId = reader.readIntPositioned(footerPos);
- IgniteBiTuple<Integer, Integer> posAndLen = fieldPositionAndLength(footerPos, footerEnd, rawPos);
+ IgniteBiTuple<Integer, Integer> posAndLen =
+ fieldPositionAndLength(footerPos, footerEnd, rawPos, fieldOffsetSize);
Object val = reader.getValueQuickly(posAndLen.get1(), posAndLen.get2());
readCache.put(fieldId, val);
// Shift current footer position.
- footerPos += 8;
+ footerPos += 4 + fieldOffsetSize;
}
this.readCache = readCache;
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp b/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
index baeb9e7..3ec5a15 100644
--- a/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
+++ b/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
@@ -68,9 +68,9 @@ void CheckPrimitive(T val)
in.Synchronize();
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8;
+ int32_t footerEnd = footerBegin + 5;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
try
@@ -148,9 +148,9 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
in.Synchronize();
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8;
+ int32_t footerEnd = footerBegin + 5;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -181,9 +181,9 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
in.Synchronize();
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8;
+ int32_t footerEnd = footerBegin + 5;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -218,9 +218,9 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
in.Synchronize();
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8;
+ int32_t footerEnd = footerBegin + 5;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -258,9 +258,9 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
in.Synchronize();
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8;
+ int32_t footerEnd = footerBegin + 5;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -510,9 +510,9 @@ void CheckCollectionEmpty(CollectionType* colType)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -600,9 +600,9 @@ void CheckCollection(CollectionType* colType)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -677,9 +677,9 @@ void CheckCollectionIterators(CollectionType* colType)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -753,9 +753,9 @@ void CheckMapEmpty(MapType* mapType)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -846,9 +846,9 @@ void CheckMap(MapType* mapType)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1028,9 +1028,9 @@ BOOST_AUTO_TEST_CASE(TestGuidNull)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8;
+ int32_t footerEnd = footerBegin + 5;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1113,9 +1113,9 @@ BOOST_AUTO_TEST_CASE(TestString) {
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 5;
+ int32_t footerEnd = footerBegin + 5 * 5;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1191,9 +1191,9 @@ BOOST_AUTO_TEST_CASE(TestStringArrayNull)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1308,9 +1308,9 @@ BOOST_AUTO_TEST_CASE(TestStringArrayEmpty)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1435,9 +1435,9 @@ BOOST_AUTO_TEST_CASE(TestStringArray)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1549,14 +1549,15 @@ BOOST_AUTO_TEST_CASE(TestObject)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 3;
+ int32_t footerEnd = footerBegin + 5 * 3;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
PortableInner readVal1 = reader.ReadObject<PortableInner>("field1");
+
BOOST_REQUIRE(writeVal1.GetValue() == readVal1.GetValue());
PortableInner readVal2 = reader.ReadObject<PortableInner>("field2");
@@ -1592,9 +1593,9 @@ BOOST_AUTO_TEST_CASE(TestNestedObject)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 3;
+ int32_t footerEnd = footerBegin + 5 * 3;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1634,9 +1635,9 @@ BOOST_AUTO_TEST_CASE(TestArrayNull)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1710,9 +1711,9 @@ BOOST_AUTO_TEST_CASE(TestArrayEmpty)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1794,9 +1795,9 @@ BOOST_AUTO_TEST_CASE(TestArray)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1855,9 +1856,9 @@ BOOST_AUTO_TEST_CASE(TestCollectionNull)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -1941,9 +1942,9 @@ BOOST_AUTO_TEST_CASE(TestMapNull)
InteropInputStream in(&mem);
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
- int32_t footerEnd = footerBegin + 8 * 2;
+ int32_t footerEnd = footerBegin + 5 * 2;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -2034,7 +2035,7 @@ BOOST_AUTO_TEST_CASE(TestRawMode)
int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
int32_t footerEnd = footerBegin;
- PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, footerBegin, footerBegin, footerEnd);
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, footerBegin, footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
in.Position(IGNITE_DFLT_HDR_LEN);
@@ -2111,7 +2112,7 @@ BOOST_AUTO_TEST_CASE(TestFieldSeek)
PortableReaderImpl readerImpl(&in, &idRslvr, pos, usrType,
typeId, hashCode, len, rawOff,
- footerBegin, footerEnd);
+ footerBegin, footerEnd, OFFSET_TYPE_1_BYTE);
PortableReader reader(&readerImpl);
@@ -2211,4 +2212,162 @@ BOOST_AUTO_TEST_CASE(TestFieldSeek)
BOOST_REQUIRE(mapReader.IsNull());
}
+BOOST_AUTO_TEST_CASE(TestSchemaOffset2ByteFields)
+{
+ const int fieldsNum = 64;
+
+ TemplatedPortableIdResolver<PortableDummy> idRslvr;
+
+ InteropUnpooledMemory mem(4096);
+
+ InteropOutputStream out(&mem);
+ PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
+ PortableWriter writer(&writerImpl);
+
+ out.Position(IGNITE_DFLT_HDR_LEN);
+
+ for (int i = 0; i < fieldsNum; ++i)
+ {
+ std::stringstream tmp;
+ tmp << "field" << i;
+
+ writer.WriteInt32(tmp.str().c_str(), i * 10);
+ }
+
+ writerImpl.PostWrite();
+
+ out.Synchronize();
+
+ InteropInputStream in(&mem);
+
+ int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+ int32_t footerEnd = footerBegin + 6 * fieldsNum;
+
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_2_BYTE);
+ PortableReader reader(&readerImpl);
+
+ in.Position(IGNITE_DFLT_HDR_LEN);
+
+ for (int i = 0; i < fieldsNum; ++i)
+ {
+ std::stringstream tmp;
+ tmp << "field" << i;
+
+ BOOST_REQUIRE(reader.ReadInt32(tmp.str().c_str()) == i * 10);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TestSchemaOffset4ByteFields)
+{
+ const int fieldsNum = 0x10000 / 4;
+
+ TemplatedPortableIdResolver<PortableDummy> idRslvr;
+
+ InteropUnpooledMemory mem(1024 * 1024);
+
+ InteropOutputStream out(&mem);
+ PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
+ PortableWriter writer(&writerImpl);
+
+ out.Position(IGNITE_DFLT_HDR_LEN);
+
+ for (int i = 0; i < fieldsNum; ++i)
+ {
+ std::stringstream tmp;
+ tmp << "field" << i;
+
+ writer.WriteInt32(tmp.str().c_str(), i * 10);
+ }
+
+ writerImpl.PostWrite();
+
+ out.Synchronize();
+
+ InteropInputStream in(&mem);
+
+ int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+ int32_t footerEnd = footerBegin + 8 * fieldsNum;
+
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_4_BYTE);
+ PortableReader reader(&readerImpl);
+
+ in.Position(IGNITE_DFLT_HDR_LEN);
+
+ for (int i = 0; i < fieldsNum; ++i)
+ {
+ std::stringstream tmp;
+ tmp << "field" << i;
+
+ BOOST_REQUIRE(reader.ReadInt32(tmp.str().c_str()) == i * 10);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TestSchemaOffset2ByteArray)
+{
+ TemplatedPortableIdResolver<PortableDummy> idRslvr;
+
+ InteropUnpooledMemory mem(4096);
+
+ InteropOutputStream out(&mem);
+ PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
+ PortableWriter writer(&writerImpl);
+
+ out.Position(IGNITE_DFLT_HDR_LEN);
+
+ int8_t dummyArray[256] = {};
+
+ writer.WriteInt8Array("field1", dummyArray, sizeof(dummyArray));
+ writer.WriteInt32("field2", 42);
+
+ writerImpl.PostWrite();
+
+ out.Synchronize();
+
+ InteropInputStream in(&mem);
+
+ int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+ int32_t footerEnd = footerBegin + 6 * 2;
+
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_2_BYTE);
+ PortableReader reader(&readerImpl);
+
+ in.Position(IGNITE_DFLT_HDR_LEN);
+
+ BOOST_REQUIRE(reader.ReadInt32("field2") == 42);
+}
+
+BOOST_AUTO_TEST_CASE(TestSchemaOffset4ByteArray)
+{
+ TemplatedPortableIdResolver<PortableDummy> idRslvr;
+
+ InteropUnpooledMemory mem(1024 * 1024);
+
+ InteropOutputStream out(&mem);
+ PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
+ PortableWriter writer(&writerImpl);
+
+ out.Position(IGNITE_DFLT_HDR_LEN);
+
+ int8_t dummyArray[0x10000] = {};
+
+ writer.WriteInt8Array("field1", dummyArray, sizeof(dummyArray));
+ writer.WriteInt32("field2", 42);
+
+ writerImpl.PostWrite();
+
+ out.Synchronize();
+
+ InteropInputStream in(&mem);
+
+ int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+ int32_t footerEnd = footerBegin + 8 * 2;
+
+ PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd, OFFSET_TYPE_4_BYTE);
+ PortableReader reader(&readerImpl);
+
+ in.Position(IGNITE_DFLT_HDR_LEN);
+
+ BOOST_REQUIRE(reader.ReadInt32("field2") == 42);
+}
+
BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/include/ignite/impl/interop/interop_input_stream.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_input_stream.h b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_input_stream.h
index f23cec6..6842990 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_input_stream.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_input_stream.h
@@ -44,6 +44,14 @@ namespace ignite
* @return Value.
*/
int8_t ReadInt8();
+
+ /**
+ * Read signed 8-byte int at the given position.
+ *
+ * @param pos Position.
+ * @return Value.
+ */
+ int32_t ReadInt8(int32_t pos);
/**
* Read signed 8-byte int array.
@@ -76,6 +84,14 @@ namespace ignite
int16_t ReadInt16();
/**
+ * Read signed 16-byte int at the given position.
+ *
+ * @param pos Position.
+ * @return Value.
+ */
+ int32_t ReadInt16(int32_t pos);
+
+ /**
* Read signed 16-byte int array.
*
* @param res Allocated array.
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
index 211ac6d..0814c01 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
@@ -83,6 +83,14 @@ namespace ignite
void WriteInt16(const int16_t val);
/**
+ * Write signed 16-byte integer at the given position.
+ *
+ * @param pos Position.
+ * @param val Value.
+ */
+ void WriteInt16(const int32_t pos, const int16_t val);
+
+ /**
* Write signed 16-byte integer array.
*
* @param val Value.
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
index c6dad50..f08c49b 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
@@ -169,6 +169,12 @@ namespace ignite
/** Raw only flag. */
const int16_t IGNITE_PORTABLE_FLAG_RAW_ONLY = 0x0002;
+
+ /** Flag indicating that schema field offset is one byte long. */
+ const int16_t IGNITE_PORTABLE_FLAG_OFFSET_1_BYTE = 0x0004;
+
+ /** Flag indicating that schema field offset is two byte long. */
+ const int16_t IGNITE_PORTABLE_FLAG_OFFSET_2_BYTE = 0x0008;
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
index fe25c87..4762fff 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
@@ -59,7 +59,7 @@ namespace ignite
*/
PortableReaderImpl(interop::InteropInputStream* stream, PortableIdResolver* idRslvr,
int32_t pos, bool usrType, int32_t typeId, int32_t hashCode, int32_t len, int32_t rawOff,
- int32_t footerBegin, int32_t footerEnd);
+ int32_t footerBegin, int32_t footerEnd, PortableOffsetType schemaType);
/**
* Constructor used to construct light-weight reader allowing only raw operations
@@ -788,7 +788,27 @@ namespace ignite
else
footerBegin = schemaOrRawOff;
- int32_t trailingBytes = (len - footerBegin) % 8;
+ PortableOffsetType schemaType;
+ int32_t trailingBytes;
+
+ if (flags & IGNITE_PORTABLE_FLAG_OFFSET_1_BYTE)
+ {
+ schemaType = OFFSET_TYPE_1_BYTE;
+
+ trailingBytes = (len - footerBegin) % 5;
+ }
+ else if (flags & IGNITE_PORTABLE_FLAG_OFFSET_2_BYTE)
+ {
+ schemaType = OFFSET_TYPE_2_BYTE;
+
+ trailingBytes = (len - footerBegin) % 6;
+ }
+ else
+ {
+ schemaType = OFFSET_TYPE_4_BYTE;
+
+ trailingBytes = (len - footerBegin) % 8;
+ }
int32_t footerEnd = len - trailingBytes;
@@ -806,7 +826,7 @@ namespace ignite
TemplatedPortableIdResolver<T> idRslvr(type);
PortableReaderImpl readerImpl(stream, &idRslvr, pos, usrType,
typeId, hashCode, len, rawOff,
- footerBegin, footerEnd);
+ footerBegin, footerEnd, schemaType);
ignite::portable::PortableReader reader(&readerImpl);
T val = type.Read(reader);
@@ -887,6 +907,9 @@ namespace ignite
/** Footer ending position. */
int32_t footerEnd;
+ /** Object schema type. */
+ PortableOffsetType schemaType;
+
IGNITE_NO_COPY_ASSIGNMENT(PortableReaderImpl)
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h
index 1795fd1..4919e2a 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h
@@ -34,6 +34,21 @@ namespace ignite
class PortableWriterImpl;
/**
+ * Schema size variants.
+ */
+ enum PortableOffsetType
+ {
+ /** Means all field offsets can be fit in one byte. */
+ OFFSET_TYPE_1_BYTE,
+
+ /** Means all field offsets can be fit in two bytes. */
+ OFFSET_TYPE_2_BYTE,
+
+ /** Means field offsets should be stored in four bytes. */
+ OFFSET_TYPE_4_BYTE
+ };
+
+ /**
* Portable schema.
*/
class IGNITE_IMPORT_EXPORT PortableSchema
@@ -86,10 +101,17 @@ namespace ignite
*/
void Clear();
+ /**
+ * Get type of schema.
+ *
+ * @return Type of schema.
+ */
+ PortableOffsetType GetType() const;
+
private:
/**
- * Single schema field info.
- */
+ * Single schema field info.
+ */
struct PortableSchemaFieldInfo
{
int32_t id;
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp b/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
index 02e894c..fed7871 100644
--- a/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
+++ b/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
@@ -69,6 +69,16 @@ namespace ignite
IGNITE_INTEROP_IN_READ(int8_t, 1);
}
+ int32_t InteropInputStream::ReadInt8(int32_t pos)
+ {
+ int delta = pos + 1 - this->pos;
+
+ if (delta > 0)
+ EnsureEnoughData(delta);
+
+ return *reinterpret_cast<int8_t*>(data + pos);
+ }
+
void InteropInputStream::ReadInt8Array(int8_t* const res, const int32_t len)
{
IGNITE_INTEROP_IN_READ_ARRAY(len, 0);
@@ -90,6 +100,16 @@ namespace ignite
IGNITE_INTEROP_IN_READ(int16_t, 2);
}
+ int32_t InteropInputStream::ReadInt16(int32_t pos)
+ {
+ int delta = pos + 2 - this->pos;
+
+ if (delta > 0)
+ EnsureEnoughData(delta);
+
+ return *reinterpret_cast<int16_t*>(data + pos);
+ }
+
void InteropInputStream::ReadInt16Array(int16_t* const res, const int32_t len)
{
IGNITE_INTEROP_IN_READ_ARRAY(len, 1);
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp b/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
index 1fd400b..acfd3ec 100644
--- a/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
+++ b/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
@@ -96,6 +96,13 @@ namespace ignite
IGNITE_INTEROP_OUT_WRITE(val, int16_t, 2);
}
+ void InteropOutputStream::WriteInt16(const int32_t pos, const int16_t val)
+ {
+ EnsureCapacity(pos + 2);
+
+ *reinterpret_cast<int16_t*>(data + pos) = val;
+ }
+
void InteropOutputStream::WriteInt16Array(const int16_t* val, const int32_t len)
{
IGNITE_INTEROP_OUT_WRITE_ARRAY(val, len << 1);
http://git-wip-us.apache.org/repos/asf/ignite/blob/845c4f27/modules/platforms/cpp/core/src/impl/portable/portable_reader_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/portable/portable_reader_impl.cpp b/modules/platforms/cpp/core/src/impl/portable/portable_reader_impl.cpp
index 96378e0..fd2cc18 100644
--- a/modules/platforms/cpp/core/src/impl/portable/portable_reader_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/portable/portable_reader_impl.cpp
@@ -36,10 +36,10 @@ namespace ignite
{
PortableReaderImpl::PortableReaderImpl(InteropInputStream* stream, PortableIdResolver* idRslvr,
int32_t pos, bool usrType, int32_t typeId, int32_t hashCode, int32_t len, int32_t rawOff,
- int32_t footerBegin, int32_t footerEnd) :
+ int32_t footerBegin, int32_t footerEnd, PortableOffsetType schemaType) :
stream(stream), idRslvr(idRslvr), pos(pos), usrType(usrType), typeId(typeId),
hashCode(hashCode), len(len), rawOff(rawOff), rawMode(false), elemIdGen(0), elemId(0),
- elemCnt(-1), elemRead(0), footerBegin(footerBegin), footerEnd(footerEnd)
+ elemCnt(-1), elemRead(0), footerBegin(footerBegin), footerEnd(footerEnd), schemaType(schemaType)
{
// No-op.
}
@@ -47,7 +47,7 @@ namespace ignite
PortableReaderImpl::PortableReaderImpl(InteropInputStream* stream) :
stream(stream), idRslvr(NULL), pos(0), usrType(false), typeId(0), hashCode(0), len(0),
rawOff(0), rawMode(true), elemIdGen(0), elemId(0), elemCnt(-1), elemRead(0), footerBegin(-1),
- footerEnd(-1)
+ footerEnd(-1), schemaType(OFFSET_TYPE_4_BYTE)
{
// No-op.
}
@@ -648,12 +648,43 @@ namespace ignite
stream->Position(footerBegin);
- for (int32_t schemaPos = footerBegin; schemaPos < footerEnd; schemaPos += 8)
+ switch (schemaType)
{
- int32_t currentFieldId = stream->ReadInt32(schemaPos);
+ case OFFSET_TYPE_1_BYTE:
+ {
+ for (int32_t schemaPos = footerBegin; schemaPos < footerEnd; schemaPos += 5)
+ {
+ int32_t currentFieldId = stream->ReadInt32(schemaPos);
+
+ if (fieldId == currentFieldId)
+ return static_cast<uint8_t>(stream->ReadInt8(schemaPos + 4)) + pos;
+ }
+ break;
+ }
+
+ case OFFSET_TYPE_2_BYTE:
+ {
+ for (int32_t schemaPos = footerBegin; schemaPos < footerEnd; schemaPos += 6)
+ {
+ int32_t currentFieldId = stream->ReadInt32(schemaPos);
- if (fieldId == currentFieldId)
- return stream->ReadInt32(schemaPos + 4) + pos;
+ if (fieldId == currentFieldId)
+ return static_cast<uint16_t>(stream->ReadInt16(schemaPos + 4)) + pos;
+ }
+ break;
+ }
+
+ case OFFSET_TYPE_4_BYTE:
+ {
+ for (int32_t schemaPos = footerBegin; schemaPos < footerEnd; schemaPos += 8)
+ {
+ int32_t currentFieldId = stream->ReadInt32(schemaPos);
+
+ if (fieldId == currentFieldId)
+ return stream->ReadInt32(schemaPos + 4) + pos;
+ }
+ break;
+ }
}
return -1;