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 2016/02/08 08:31:16 UTC
[1/2] ignite git commit: IGNITE-1759: .NET: Improved GUID handling
for different platforms and endians. This closes #437.
Repository: ignite
Updated Branches:
refs/heads/master bad042097 -> d844e9599
IGNITE-1759: .NET: Improved GUID handling for different platforms and endians. This closes #437.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f07adff7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f07adff7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f07adff7
Branch: refs/heads/master
Commit: f07adff7bb601971bb6c83b0459113678f387592
Parents: e88cc67
Author: Pavel Tupitsyn <pt...@gridgain.com>
Authored: Mon Feb 8 10:30:57 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Feb 8 10:30:57 2016 +0300
----------------------------------------------------------------------
.../Binary/BinarySelfTest.cs | 32 ++++
.../Impl/Binary/BinaryUtils.cs | 166 ++++++++++++++++---
2 files changed, 172 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/f07adff7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
index 44db6f7..f49a28a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
@@ -26,12 +26,15 @@ namespace Apache.Ignite.Core.Tests.Binary
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+ using System.IO;
using System.Linq;
using Apache.Ignite.Core.Binary;
using Apache.Ignite.Core.Common;
using Apache.Ignite.Core.Impl.Binary;
using Apache.Ignite.Core.Impl.Binary.IO;
using NUnit.Framework;
+ using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader;
+ using BinaryWriter = Apache.Ignite.Core.Impl.Binary.BinaryWriter;
/// <summary>
///
@@ -476,6 +479,35 @@ namespace Apache.Ignite.Core.Tests.Binary
Assert.AreEqual(vals, newVals);
}
+ /// <summary>
+ /// Checks that both methods produce identical results.
+ /// </summary>
+ [Test]
+ public void TestGuidSlowFast()
+ {
+ var stream = new BinaryHeapStream(128);
+
+ var guid = Guid.NewGuid();
+
+ BinaryUtils.WriteGuidFast(guid, stream);
+
+ stream.Seek(0, SeekOrigin.Begin);
+ Assert.AreEqual(guid, BinaryUtils.ReadGuidFast(stream));
+
+ stream.Seek(0, SeekOrigin.Begin);
+ Assert.AreEqual(guid, BinaryUtils.ReadGuidSlow(stream));
+
+
+ stream.Seek(0, SeekOrigin.Begin);
+ BinaryUtils.WriteGuidFast(guid, stream);
+
+ stream.Seek(0, SeekOrigin.Begin);
+ Assert.AreEqual(guid, BinaryUtils.ReadGuidFast(stream));
+
+ stream.Seek(0, SeekOrigin.Begin);
+ Assert.AreEqual(guid, BinaryUtils.ReadGuidSlow(stream));
+ }
+
/**
* <summary>Check write of enum.</summary>
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/f07adff7/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
index 06dec2c..9066bd1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -243,6 +243,17 @@ namespace Apache.Ignite.Core.Impl.Binary
private static readonly CopyOnWriteConcurrentDictionary<Type, Func<BinaryReader, bool, object>>
ArrayReaders = new CopyOnWriteConcurrentDictionary<Type, Func<BinaryReader, bool, object>>();
+ /** Flag indicating whether Guid struct is sequential in current runtime. */
+ private static readonly bool IsGuidSequential = GetIsGuidSequential();
+
+ /** Guid writer. */
+ public static readonly Action<Guid, IBinaryStream> WriteGuid = IsGuidSequential
+ ? (Action<Guid, IBinaryStream>)WriteGuidFast : WriteGuidSlow;
+
+ /** Guid reader. */
+ public static readonly Func<IBinaryStream, Guid?> ReadGuid = IsGuidSequential
+ ? (Func<IBinaryStream, Guid?>)ReadGuidFast : ReadGuidSlow;
+
/// <summary>
/// Default marshaller.
/// </summary>
@@ -900,12 +911,33 @@ namespace Apache.Ignite.Core.Impl.Binary
return vals;
}
- /**
- * <summary>Write GUID.</summary>
- * <param name="val">GUID.</param>
- * <param name="stream">Stream.</param>
- */
- public static unsafe void WriteGuid(Guid val, IBinaryStream stream)
+ /// <summary>
+ /// Gets a value indicating whether <see cref="Guid"/> fields are stored sequentially in memory.
+ /// </summary>
+ /// <returns></returns>
+ private static unsafe bool GetIsGuidSequential()
+ {
+ // Check that bitwise conversion returns correct result
+ var guid = Guid.NewGuid();
+
+ var bytes = guid.ToByteArray();
+
+ var bytes0 = (byte*) &guid;
+
+ for (var i = 0; i < bytes.Length; i++)
+ if (bytes[i] != bytes0[i])
+ return false;
+
+ return true;
+ }
+
+ /// <summary>
+ /// Writes a guid with bitwise conversion, assuming that <see cref="Guid"/>
+ /// is laid out in memory sequentially and without gaps between fields.
+ /// </summary>
+ /// <param name="val">The value.</param>
+ /// <param name="stream">The stream.</param>
+ public static unsafe void WriteGuidFast(Guid val, IBinaryStream stream)
{
var jguid = new JavaGuid(val);
@@ -913,13 +945,47 @@ namespace Apache.Ignite.Core.Impl.Binary
stream.Write((byte*) ptr, 16);
}
-
- /**
- * <summary>Read GUID.</summary>
- * <param name="stream">Stream.</param>
- * <returns>GUID</returns>
- */
- public static unsafe Guid? ReadGuid(IBinaryStream stream)
+
+ /// <summary>
+ /// Writes a guid byte by byte.
+ /// </summary>
+ /// <param name="val">The value.</param>
+ /// <param name="stream">The stream.</param>
+ public static unsafe void WriteGuidSlow(Guid val, IBinaryStream stream)
+ {
+ var bytes = val.ToByteArray();
+ byte* jBytes = stackalloc byte[16];
+
+ jBytes[0] = bytes[6]; // c1
+ jBytes[1] = bytes[7]; // c2
+
+ jBytes[2] = bytes[4]; // b1
+ jBytes[3] = bytes[5]; // b2
+
+ jBytes[4] = bytes[0]; // a1
+ jBytes[5] = bytes[1]; // a2
+ jBytes[6] = bytes[2]; // a3
+ jBytes[7] = bytes[3]; // a4
+
+ jBytes[8] = bytes[15]; // k
+ jBytes[9] = bytes[14]; // j
+ jBytes[10] = bytes[13]; // i
+ jBytes[11] = bytes[12]; // h
+ jBytes[12] = bytes[11]; // g
+ jBytes[13] = bytes[10]; // f
+ jBytes[14] = bytes[9]; // e
+ jBytes[15] = bytes[8]; // d
+
+ stream.Write(jBytes, 16);
+ }
+
+ /// <summary>
+ /// Reads a guid with bitwise conversion, assuming that <see cref="Guid"/>
+ /// is laid out in memory sequentially and without gaps between fields.
+ /// </summary>
+ /// <param name="stream">The stream.</param>
+ /// <returns>Guid.</returns>
+ public static unsafe Guid? ReadGuidFast(IBinaryStream stream)
{
JavaGuid jguid;
@@ -931,7 +997,43 @@ namespace Apache.Ignite.Core.Impl.Binary
return *(Guid*) (&dotnetGuid);
}
-
+
+ /// <summary>
+ /// Reads a guid byte by byte.
+ /// </summary>
+ /// <param name="stream">The stream.</param>
+ /// <returns>Guid.</returns>
+ public static unsafe Guid? ReadGuidSlow(IBinaryStream stream)
+ {
+ byte* jBytes = stackalloc byte[16];
+
+ stream.Read(jBytes, 16);
+
+ var bytes = new byte[16];
+
+ bytes[0] = jBytes[4]; // a1
+ bytes[1] = jBytes[5]; // a2
+ bytes[2] = jBytes[6]; // a3
+ bytes[3] = jBytes[7]; // a4
+
+ bytes[4] = jBytes[2]; // b1
+ bytes[5] = jBytes[3]; // b2
+
+ bytes[6] = jBytes[0]; // c1
+ bytes[7] = jBytes[1]; // c2
+
+ bytes[8] = jBytes[15]; // d
+ bytes[9] = jBytes[14]; // e
+ bytes[10] = jBytes[13]; // f
+ bytes[11] = jBytes[12]; // g
+ bytes[12] = jBytes[11]; // h
+ bytes[13] = jBytes[10]; // i
+ bytes[14] = jBytes[9]; // j
+ bytes[15] = jBytes[8]; // k
+
+ return new Guid(bytes);
+ }
+
/// <summary>
/// Write GUID array.
/// </summary>
@@ -1689,7 +1791,7 @@ namespace Apache.Ignite.Core.Impl.Binary
private struct GuidAccessor
{
public readonly ulong ABC;
- public readonly ulong DEGHIJK;
+ public readonly ulong DEFGHIJK;
/// <summary>
/// Initializes a new instance of the <see cref="GuidAccessor"/> struct.
@@ -1699,21 +1801,28 @@ namespace Apache.Ignite.Core.Impl.Binary
{
var l = val.CBA;
- ABC = ((l >> 32) & 0x00000000FFFFFFFF) | ((l << 48) & 0xFFFF000000000000) |
- ((l << 16) & 0x0000FFFF00000000);
+ if (BitConverter.IsLittleEndian)
+ ABC = ((l >> 32) & 0x00000000FFFFFFFF) | ((l << 48) & 0xFFFF000000000000) |
+ ((l << 16) & 0x0000FFFF00000000);
+ else
+ ABC = ((l << 32) & 0xFFFFFFFF00000000) | ((l >> 48) & 0x000000000000FFFF) |
+ ((l >> 16) & 0x00000000FFFF0000);
- DEGHIJK = ReverseByteOrder(val.KJIHGED);
+ // This is valid in any endianness (symmetrical)
+ DEFGHIJK = ReverseByteOrder(val.KJIHGFED);
}
}
/// <summary>
/// Struct with Java-style Guid memory layout.
/// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 0)]
+ [StructLayout(LayoutKind.Explicit)]
private struct JavaGuid
{
- public readonly ulong CBA;
- public readonly ulong KJIHGED;
+ [FieldOffset(0)] public readonly ulong CBA;
+ [FieldOffset(8)] public readonly ulong KJIHGFED;
+ [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ [FieldOffset(0)] public unsafe fixed byte Bytes [16];
/// <summary>
/// Initializes a new instance of the <see cref="JavaGuid"/> struct.
@@ -1721,17 +1830,22 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <param name="val">The value.</param>
public unsafe JavaGuid(Guid val)
{
- // .Net returns bytes in the following order: _a(4), _b(2), _c(2), _d, _e, _g, _h, _i, _j, _k.
+ // .Net returns bytes in the following order: _a(4), _b(2), _c(2), _d, _e, _f, _g, _h, _i, _j, _k.
// And _a, _b and _c are always in little endian format irrespective of system configuration.
- // To be compliant with Java we rearrange them as follows: _c, _b_, a_, _k, _j, _i, _h, _g, _e, _d.
+ // To be compliant with Java we rearrange them as follows: _c, _b_, a_, _k, _j, _i, _h, _g, _f, _e, _d.
var accessor = *((GuidAccessor*)&val);
var l = accessor.ABC;
- CBA = ((l << 32) & 0xFFFFFFFF00000000) | ((l >> 48) & 0x000000000000FFFF) |
- ((l >> 16) & 0x00000000FFFF0000);
+ if (BitConverter.IsLittleEndian)
+ CBA = ((l << 32) & 0xFFFFFFFF00000000) | ((l >> 48) & 0x000000000000FFFF) |
+ ((l >> 16) & 0x00000000FFFF0000);
+ else
+ CBA = ((l >> 32) & 0x00000000FFFFFFFF) | ((l << 48) & 0xFFFF000000000000) |
+ ((l << 16) & 0x0000FFFF00000000);
- KJIHGED = ReverseByteOrder(accessor.DEGHIJK);
+ // This is valid in any endianness (symmetrical)
+ KJIHGFED = ReverseByteOrder(accessor.DEFGHIJK);
}
}
}
[2/2] ignite git commit: Merge remote-tracking branch 'origin/master'
Posted by vo...@apache.org.
Merge remote-tracking branch 'origin/master'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d844e959
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d844e959
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d844e959
Branch: refs/heads/master
Commit: d844e95991408970598b324b204c4b6942e67e13
Parents: f07adff bad0420
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Mon Feb 8 10:31:14 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Feb 8 10:31:14 2016 +0300
----------------------------------------------------------------------
.../util/nio/SelectedSelectionKeySet.java | 65 +++++++++++++-------
1 file changed, 43 insertions(+), 22 deletions(-)
----------------------------------------------------------------------