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/08/25 12:04:39 UTC
[1/2] ignite git commit: IGNITE-1287: Moved memory management code to
Ignite.
Repository: ignite
Updated Branches:
refs/heads/master 14718f964 -> 7b61a0973
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Memory/InteropMemoryTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Memory/InteropMemoryTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Memory/InteropMemoryTest.cs
new file mode 100644
index 0000000..e32e622
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Memory/InteropMemoryTest.cs
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Memory
+{
+ using System;
+ using Apache.Ignite.Core.Impl.Memory;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests for interop memory.
+ /// </summary>
+ public class InteropMemoryTest
+ {
+ /// <summary>
+ /// Test pooled memory.
+ /// </summary>
+ [Test]
+ public void TestPooled()
+ {
+ PlatformMemoryManager mgr = new PlatformMemoryManager(256);
+
+ var mem1 = mgr.Allocate();
+ Assert.IsTrue(mem1 is PlatformPooledMemory);
+ Assert.IsTrue(mem1.Capacity >= 256);
+ Assert.IsTrue(mem1.Pointer > 0);
+ Assert.IsTrue(mem1.Data > 0);
+ Assert.AreEqual(0, mem1.Length);
+
+ mem1.Reallocate(512);
+
+ Assert.IsTrue(mem1.Capacity >= 512);
+ Assert.IsTrue(mem1.Pointer > 0);
+ Assert.IsTrue(mem1.Data > 0);
+ Assert.AreEqual(0, mem1.Length);
+
+ mem1.Length = 128;
+ Assert.AreEqual(128, mem1.Length);
+
+ mem1.Release();
+
+ Assert.AreSame(mem1, mgr.Allocate());
+ Assert.IsTrue(mem1.Capacity >= 512);
+ Assert.IsTrue(mem1.Pointer > 0);
+ Assert.IsTrue(mem1.Data > 0);
+ Assert.AreEqual(128, mem1.Length);
+
+ IPlatformMemory mem2 = mgr.Allocate();
+ Assert.IsTrue(mem2 is PlatformPooledMemory);
+
+ IPlatformMemory mem3 = mgr.Allocate();
+ Assert.IsTrue(mem3 is PlatformPooledMemory);
+
+ mem1.Release();
+ Assert.AreSame(mem1, mgr.Allocate());
+
+ mem2.Release();
+ Assert.AreSame(mem2, mgr.Allocate());
+
+ mem3.Release();
+ Assert.AreSame(mem3, mgr.Allocate());
+
+ mem1.Release();
+ mem2.Release();
+
+ Assert.AreSame(mem1, mgr.Allocate());
+ Assert.AreSame(mem2, mgr.Allocate());
+
+ IPlatformMemory unpooled = mgr.Allocate();
+
+ try
+ {
+ Assert.IsTrue(unpooled is PlatformUnpooledMemory);
+ }
+ finally
+ {
+ unpooled.Release();
+ }
+ }
+
+ /// <summary>
+ /// Test unpooled memory.
+ /// </summary>
+ [Test]
+ public void TestUnpooled()
+ {
+ PlatformMemoryManager mgr = new PlatformMemoryManager(256);
+
+ for (int i = 0; i < 3; i++)
+ mgr.Allocate();
+
+ IPlatformMemory mem1 = mgr.Allocate();
+ Assert.IsTrue(mem1 is PlatformUnpooledMemory);
+ Assert.IsTrue(mem1.Capacity >= 256);
+ Assert.IsTrue(mem1.Pointer > 0);
+ Assert.IsTrue(mem1.Data > 0);
+ Assert.AreEqual(0, mem1.Length);
+
+ mem1.Reallocate(512);
+ Assert.IsTrue(mem1.Capacity >= 512);
+ Assert.IsTrue(mem1.Pointer > 0);
+ Assert.IsTrue(mem1.Data > 0);
+ Assert.AreEqual(0, mem1.Length);
+
+ mem1.Length = 128;
+ Assert.AreEqual(128, mem1.Length);
+
+ mem1.Release();
+
+ IPlatformMemory mem2 = mgr.Allocate();
+ Assert.AreNotSame(mem1, mem2);
+ Assert.IsTrue(mem2.Capacity >= 256);
+ Assert.IsTrue(mem2.Pointer > 0);
+ Assert.IsTrue(mem2.Data > 0);
+ Assert.AreEqual(0, mem2.Length);
+
+ mem2.Release();
+ }
+
+ /// <summary>
+ /// Test pooled memory stream reallocation initiated from stream.
+ /// </summary>
+ [Test]
+ public void TestPooledStreamReallocate()
+ {
+ IPlatformMemory mem = new PlatformMemoryManager(256).Allocate();
+
+ try
+ {
+ Assert.IsTrue(mem is PlatformPooledMemory);
+
+ CheckStreamReallocate(mem);
+ }
+ finally
+ {
+ mem.Release();
+ }
+ }
+
+ /// <summary>
+ /// Test unpooled memory stream reallocation initiated from stream.
+ /// </summary>
+ [Test]
+ public void TestUnpooledStreamReallocate()
+ {
+ PlatformMemoryManager mgr = new PlatformMemoryManager(256);
+
+ for (int i = 0; i < 3; i++)
+ mgr.Allocate();
+
+ IPlatformMemory mem = mgr.Allocate();
+
+ try
+ {
+ Assert.IsTrue(mem is PlatformUnpooledMemory);
+
+ CheckStreamReallocate(mem);
+ }
+ finally
+ {
+ mem.Release();
+ }
+ }
+
+ /// <summary>
+ /// Check stream reallocation.
+ /// </summary>
+ /// <param name="mem">Memory.</param>
+ private void CheckStreamReallocate(IPlatformMemory mem)
+ {
+ Assert.IsTrue(mem.Capacity >= 256);
+
+ int dataLen = 2048 + 13;
+
+ Random rand = new Random();
+
+ byte[] data = new byte[dataLen];
+
+ for (int i = 0; i < data.Length; i++)
+ data[i] = (byte)rand.Next(0, 255);
+
+ PlatformMemoryStream stream = mem.Stream();
+
+ stream.WriteByteArray(data);
+
+ stream.SynchronizeOutput();
+
+ Assert.IsTrue(mem.Capacity >= dataLen);
+
+ stream.Reset();
+
+ stream.SynchronizeInput();
+
+ byte[] data0 = stream.ReadByteArray(dataLen);
+
+ Assert.AreEqual(data, data0);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
index feb91bc..73c9bcb 100644
--- a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
@@ -31,9 +31,9 @@ namespace Apache.Ignite.Core.Tests
//TestOne(typeof(ContinuousQueryAtomiclBackupTest), "TestInitialQuery");
- TestAll(typeof(IgnitionTest));
+ //TestAll(typeof(IgnitionTest));
- //TestAllInAssembly();
+ TestAllInAssembly();
}
private static void TestOne(Type testClass, string method)
[2/2] ignite git commit: IGNITE-1287: Moved memory management code to
Ignite.
Posted by vo...@apache.org.
IGNITE-1287: Moved memory management code to Ignite.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/7b61a097
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/7b61a097
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/7b61a097
Branch: refs/heads/master
Commit: 7b61a0973027ac5a7c3d508018503ca2621a1092
Parents: 14718f9
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Aug 25 13:05:16 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Aug 25 13:05:16 2015 +0300
----------------------------------------------------------------------
.../Apache.Ignite.Core.csproj | 25 +
.../Impl/Memory/IPlatformMemory.cs | 62 ++
.../Memory/PlatformBigEndianMemoryStream.cs | 483 +++++++++++++
.../Impl/Memory/PlatformMemory.cs | 77 +++
.../Impl/Memory/PlatformMemoryManager.cs | 106 +++
.../Impl/Memory/PlatformMemoryPool.cs | 105 +++
.../Impl/Memory/PlatformMemoryStream.cs | 676 +++++++++++++++++++
.../Impl/Memory/PlatformMemoryUtils.cs | 462 +++++++++++++
.../Impl/Memory/PlatformPooledMemory.cs | 70 ++
.../Impl/Memory/PlatformRawMemory.cs | 88 +++
.../Impl/Memory/PlatformUnpooledMemory.cs | 52 ++
.../Impl/Portable/Io/IPortableStream.cs | 320 +++++++++
.../Properties/AssemblyInfo.cs | 6 +
.../main/dotnet/Apache.Ignite.sln.DotSettings | 4 +
.../Apache.Ignite.Core.Tests.csproj | 8 +
.../Memory/InteropMemoryTest.cs | 213 ++++++
.../Apache.Ignite.Core.Tests/TestRunner.cs | 4 +-
17 files changed, 2759 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 0980c8f..c6c8324 100644
--- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -15,18 +15,32 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\x64\Debug\</OutputPath>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\x64\Release\</OutputPath>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Debug\</OutputPath>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Release\</OutputPath>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>false</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DelaySign>false</DelaySign>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -34,6 +48,17 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Ignition.cs" />
+ <Compile Include="Impl\Memory\IPlatformMemory.cs" />
+ <Compile Include="Impl\Memory\PlatformBigEndianMemoryStream.cs" />
+ <Compile Include="Impl\Memory\PlatformMemory.cs" />
+ <Compile Include="Impl\Memory\PlatformMemoryManager.cs" />
+ <Compile Include="Impl\Memory\PlatformMemoryPool.cs" />
+ <Compile Include="Impl\Memory\PlatformMemoryStream.cs" />
+ <Compile Include="Impl\Memory\PlatformMemoryUtils.cs" />
+ <Compile Include="Impl\Memory\PlatformPooledMemory.cs" />
+ <Compile Include="Impl\Memory\PlatformRawMemory.cs" />
+ <Compile Include="Impl\Memory\PlatformUnpooledMemory.cs" />
+ <Compile Include="Impl\Portable\IO\IPortableStream.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/IPlatformMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/IPlatformMemory.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/IPlatformMemory.cs
new file mode 100644
index 0000000..ff91f48
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/IPlatformMemory.cs
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ /// <summary>
+ /// Platform memory chunk.
+ /// </summary>
+ public interface IPlatformMemory
+ {
+ /// <summary>
+ /// Gets stream for read/write operations on the given memory chunk.
+ /// </summary>
+ /// <returns></returns>
+ PlatformMemoryStream Stream();
+
+ /// <summary>
+ /// Cross-platform pointer.
+ /// </summary>
+ long Pointer { get; }
+
+ /// <summary>
+ /// Data pointer.
+ /// </summary>
+ long Data { get; }
+
+ /// <summary>
+ /// CalculateCapacity.
+ /// </summary>
+ int Capacity { get; }
+
+ /// <summary>
+ /// Length.
+ /// </summary>
+ int Length { get; set; }
+
+ /// <summary>
+ /// Reallocates memory chunk.
+ /// </summary>
+ /// <param name="cap">Minimum capacity.</param>
+ void Reallocate(int cap);
+
+ /// <summary>
+ /// Release memory.
+ /// </summary>
+ void Release();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformBigEndianMemoryStream.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformBigEndianMemoryStream.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformBigEndianMemoryStream.cs
new file mode 100644
index 0000000..33a0487
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformBigEndianMemoryStream.cs
@@ -0,0 +1,483 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ /// <summary>
+ /// Platform memory stream for big endian platforms.
+ /// </summary>
+ internal class PlatformBigEndianMemoryStream : PlatformMemoryStream
+ {
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="mem"></param>
+ public PlatformBigEndianMemoryStream(IPlatformMemory mem) : base(mem)
+ {
+ // No-op.
+ }
+
+ #region WRITE
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteShort(short val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(Len2);
+
+ byte* valPtr = (byte*)&val;
+
+ curPos[0] = valPtr[1];
+ curPos[1] = valPtr[0];
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteShortArray(short[] val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(val.Length << Shift2);
+
+ for (int i = 0; i < val.Length; i++)
+ {
+ short val0 = val[i];
+
+ byte* valPtr = (byte*)&(val0);
+
+ *curPos++ = valPtr[1];
+ *curPos++ = valPtr[0];
+ }
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteChar(char val)
+ {
+ WriteShort(*(short*)(&val));
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteCharArray(char[] val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(val.Length << Shift2);
+
+ for (int i = 0; i < val.Length; i++)
+ {
+ char val0 = val[i];
+
+ byte* valPtr = (byte*)&(val0);
+
+ *curPos++ = valPtr[1];
+ *curPos++ = valPtr[0];
+ }
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteInt(int val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(Len4);
+
+ byte* valPtr = (byte*)&val;
+
+ curPos[0] = valPtr[3];
+ curPos[1] = valPtr[2];
+ curPos[2] = valPtr[1];
+ curPos[3] = valPtr[0];
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteInt(int writePos, int val)
+ {
+ EnsureWriteCapacity(writePos + 4);
+
+ byte* curPos = Data + writePos;
+
+ byte* valPtr = (byte*)&val;
+
+ curPos[0] = valPtr[3];
+ curPos[1] = valPtr[2];
+ curPos[2] = valPtr[1];
+ curPos[3] = valPtr[0];
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteIntArray(int[] val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(val.Length << Shift4);
+
+ for (int i = 0; i < val.Length; i++)
+ {
+ int val0 = val[i];
+
+ byte* valPtr = (byte*)&(val0);
+
+ *curPos++ = valPtr[3];
+ *curPos++ = valPtr[2];
+ *curPos++ = valPtr[1];
+ *curPos++ = valPtr[0];
+ }
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteLong(long val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(Len8);
+
+ byte* valPtr = (byte*)&val;
+
+ curPos[0] = valPtr[7];
+ curPos[1] = valPtr[6];
+ curPos[2] = valPtr[5];
+ curPos[3] = valPtr[4];
+ curPos[4] = valPtr[3];
+ curPos[5] = valPtr[2];
+ curPos[6] = valPtr[1];
+ curPos[7] = valPtr[0];
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteLongArray(long[] val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(val.Length << Shift8);
+
+ for (int i = 0; i < val.Length; i++)
+ {
+ long val0 = val[i];
+
+ byte* valPtr = (byte*)&(val0);
+
+ *curPos++ = valPtr[7];
+ *curPos++ = valPtr[6];
+ *curPos++ = valPtr[5];
+ *curPos++ = valPtr[4];
+ *curPos++ = valPtr[3];
+ *curPos++ = valPtr[2];
+ *curPos++ = valPtr[1];
+ *curPos++ = valPtr[0];
+ }
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteFloat(float val)
+ {
+ WriteInt(*(int*)(&val));
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteFloatArray(float[] val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(val.Length << Shift4);
+
+ for (int i = 0; i < val.Length; i++)
+ {
+ float val0 = val[i];
+
+ byte* valPtr = (byte*)&(val0);
+
+ *curPos++ = valPtr[3];
+ *curPos++ = valPtr[2];
+ *curPos++ = valPtr[1];
+ *curPos++ = valPtr[0];
+ }
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteDouble(double val)
+ {
+ WriteLong(*(long*)(&val));
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe void WriteDoubleArray(double[] val)
+ {
+ byte* curPos = Data + EnsureWriteCapacityAndShift(val.Length << Shift8);
+
+ for (int i = 0; i < val.Length; i++)
+ {
+ double val0 = val[i];
+
+ byte* valPtr = (byte*)&(val0);
+
+ *curPos++ = valPtr[7];
+ *curPos++ = valPtr[6];
+ *curPos++ = valPtr[5];
+ *curPos++ = valPtr[4];
+ *curPos++ = valPtr[3];
+ *curPos++ = valPtr[2];
+ *curPos++ = valPtr[1];
+ *curPos++ = valPtr[0];
+ }
+ }
+
+ #endregion
+
+ #region READ
+
+ /** <inheritDoc /> */
+ public override unsafe short ReadShort()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len2);
+
+ short val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos);
+
+ return val;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe short[] ReadShortArray(int len)
+ {
+ int curPos = EnsureReadCapacityAndShift(len << Shift2);
+
+ short[] res = new short[len];
+
+ for (int i = 0; i < len; i++)
+ {
+ short val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos++);
+
+ res[i] = val;
+ }
+
+ return res;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe char ReadChar()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len2);
+
+ char val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos);
+
+ return val;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe char[] ReadCharArray(int len)
+ {
+ int curPos = EnsureReadCapacityAndShift(len << Shift2);
+
+ char[] res = new char[len];
+
+ for (int i = 0; i < len; i++)
+ {
+ char val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos++);
+
+ res[i] = val;
+ }
+
+ return res;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe int ReadInt()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len4);
+
+ int val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos);
+
+ return val;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe int[] ReadIntArray(int len)
+ {
+ int curPos = EnsureReadCapacityAndShift(len << Shift4);
+
+ int[] res = new int[len];
+
+ for (int i = 0; i < len; i++)
+ {
+ int val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos++);
+
+ res[i] = val;
+ }
+
+ return res;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe long ReadLong()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len8);
+
+ long val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[7] = *(Data + curPos++);
+ valPtr[6] = *(Data + curPos++);
+ valPtr[5] = *(Data + curPos++);
+ valPtr[4] = *(Data + curPos++);
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos);
+
+ return val;
+ }
+
+ /** <inheritDoc /> */
+
+ public override unsafe long[] ReadLongArray(int len)
+ {
+ int curPos = EnsureReadCapacityAndShift(len << Shift8);
+
+ long[] res = new long[len];
+
+ for (int i = 0; i < len; i++)
+ {
+ long val;
+
+ byte* valPtr = (byte*) &val;
+
+ valPtr[7] = *(Data + curPos++);
+ valPtr[6] = *(Data + curPos++);
+ valPtr[5] = *(Data + curPos++);
+ valPtr[4] = *(Data + curPos++);
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos++);
+
+ res[i] = val;
+ }
+
+ return res;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe float ReadFloat()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len4);
+
+ float val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos);
+
+ return val;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe float[] ReadFloatArray(int len)
+ {
+ int curPos = EnsureReadCapacityAndShift(len << Shift4);
+
+ float[] res = new float[len];
+
+ for (int i = 0; i < len; i++)
+ {
+ float val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos++);
+
+ res[i] = val;
+ }
+
+ return res;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe double ReadDouble()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len8);
+
+ double val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[7] = *(Data + curPos++);
+ valPtr[6] = *(Data + curPos++);
+ valPtr[5] = *(Data + curPos++);
+ valPtr[4] = *(Data + curPos++);
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos);
+
+ return val;
+ }
+
+ /** <inheritDoc /> */
+ public override unsafe double[] ReadDoubleArray(int len)
+ {
+ int curPos = EnsureReadCapacityAndShift(len << Shift8);
+
+ double[] res = new double[len];
+
+ for (int i = 0; i < len; i++)
+ {
+ double val;
+
+ byte* valPtr = (byte*)&val;
+
+ valPtr[7] = *(Data + curPos++);
+ valPtr[6] = *(Data + curPos++);
+ valPtr[5] = *(Data + curPos++);
+ valPtr[4] = *(Data + curPos++);
+ valPtr[3] = *(Data + curPos++);
+ valPtr[2] = *(Data + curPos++);
+ valPtr[1] = *(Data + curPos++);
+ valPtr[0] = *(Data + curPos++);
+
+ res[i] = val;
+ }
+
+ return res;
+ }
+
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs
new file mode 100644
index 0000000..e19505c
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ using System;
+
+ /// <summary>
+ /// Abstract memory chunk.
+ /// </summary>
+ public abstract class PlatformMemory : IPlatformMemory
+ {
+ /** Memory pointer. */
+ protected readonly long MemPtr;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ protected PlatformMemory(long memPtr)
+ {
+ MemPtr = memPtr;
+ }
+
+ /** <inheritdoc /> */
+ public virtual PlatformMemoryStream Stream()
+ {
+ return BitConverter.IsLittleEndian ? new PlatformMemoryStream(this) :
+ new PlatformBigEndianMemoryStream(this);
+ }
+
+ /** <inheritdoc /> */
+ public long Pointer
+ {
+ get { return MemPtr; }
+ }
+
+ /** <inheritdoc /> */
+ public long Data
+ {
+ get { return PlatformMemoryUtils.Data(MemPtr); }
+ }
+
+ /** <inheritdoc /> */
+ public int Capacity
+ {
+ get { return PlatformMemoryUtils.Capacity(MemPtr); }
+ }
+
+ /** <inheritdoc /> */
+ public int Length
+ {
+ get { return PlatformMemoryUtils.Length(MemPtr); }
+ set { PlatformMemoryUtils.Length(MemPtr, value); }
+ }
+
+ /** <inheritdoc /> */
+ public abstract void Reallocate(int cap);
+
+ /** <inheritdoc /> */
+ public abstract void Release();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs
new file mode 100644
index 0000000..2d52dd6
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ using System;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Threading;
+
+ /// <summary>
+ /// Memory manager implementation.
+ /// </summary>
+ [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable",
+ Justification = "This class instance usually lives as long as the app runs.")]
+ public class PlatformMemoryManager
+ {
+ /** Default capacity. */
+ private readonly int _dfltCap;
+
+ /** Thread-local pool. */
+ private readonly ThreadLocal<PlatformMemoryPool> _threadLocPool = new ThreadLocal<PlatformMemoryPool>();
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="dfltCap">Default capacity.</param>
+ public PlatformMemoryManager(int dfltCap)
+ {
+ _dfltCap = dfltCap;
+ }
+
+ /// <summary>
+ /// Allocate memory.
+ /// </summary>
+ /// <returns>Memory.</returns>
+ public IPlatformMemory Allocate()
+ {
+ return Allocate(_dfltCap);
+ }
+
+ /// <summary>
+ /// Allocate memory having at least the given capacity.
+ /// </summary>
+ /// <param name="cap">Minimum capacity.</param>
+ /// <returns>Memory.</returns>
+ public IPlatformMemory Allocate(int cap)
+ {
+ return Pool().Allocate(cap);
+ }
+
+ /// <summary>
+ /// Gets memory from existing pointer.
+ /// </summary>
+ /// <param name="memPtr">Cross-platform memory pointer.</param>
+ /// <returns>Memory.</returns>
+ public IPlatformMemory Get(long memPtr)
+ {
+ int flags = PlatformMemoryUtils.Flags(memPtr);
+
+ return PlatformMemoryUtils.IsExternal(flags) ? GetExternalMemory(memPtr)
+ : PlatformMemoryUtils.IsPooled(flags) ? Pool().Get(memPtr) : new PlatformUnpooledMemory(memPtr);
+ }
+
+ /// <summary>
+ /// Gets or creates thread-local memory pool.
+ /// </summary>
+ /// <returns>Memory pool.</returns>
+ public PlatformMemoryPool Pool()
+ {
+ PlatformMemoryPool pool = _threadLocPool.Value;
+
+ if (pool == null)
+ {
+ pool = new PlatformMemoryPool();
+
+ _threadLocPool.Value = pool;
+ }
+
+ return pool;
+ }
+
+ /// <summary>
+ /// Gets the external memory.
+ /// </summary>
+ /// <param name="memPtr">Cross-platform memory pointer.</param>
+ /// <returns>Memory.</returns>
+ protected virtual IPlatformMemory GetExternalMemory(long memPtr)
+ {
+ throw new NotSupportedException("Not supported in Ignite yet");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.cs
new file mode 100644
index 0000000..3cdcd2d
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.cs
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ using System;
+ using Microsoft.Win32.SafeHandles;
+
+ /// <summary>
+ /// Platform memory pool.
+ /// </summary>
+ public class PlatformMemoryPool : SafeHandleMinusOneIsInvalid
+ {
+ /** First pooled memory chunk. */
+ private PlatformPooledMemory _mem1;
+
+ /** Second pooled memory chunk. */
+ private PlatformPooledMemory _mem2;
+
+ /** Third pooled memory chunk. */
+ private PlatformPooledMemory _mem3;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ public PlatformMemoryPool() : base(true)
+ {
+ handle = (IntPtr)PlatformMemoryUtils.AllocatePool();
+ }
+
+ /// <summary>
+ /// Allocate memory chunk, optionally pooling it.
+ /// </summary>
+ /// <param name="cap">Minimum capacity.</param>
+ /// <returns>Memory chunk</returns>
+ public PlatformMemory Allocate(int cap)
+ {
+ var memPtr = PlatformMemoryUtils.AllocatePooled(handle.ToInt64(), cap);
+
+ // memPtr == 0 means that we failed to acquire thread-local memory chunk, so fallback to unpooled memory.
+ return memPtr != 0 ? Get(memPtr) : new PlatformUnpooledMemory(PlatformMemoryUtils.AllocateUnpooled(cap));
+ }
+
+ /// <summary>
+ /// Re-allocate existing pool memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <param name="cap">Minimum capacity.</param>
+ public void Reallocate(long memPtr, int cap)
+ {
+ PlatformMemoryUtils.ReallocatePooled(memPtr, cap);
+ }
+
+ /// <summary>
+ /// Release pooled memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ public void Release(long memPtr)
+ {
+ PlatformMemoryUtils.ReleasePooled(memPtr);
+ }
+
+ /// <summary>
+ /// Get pooled memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns>Memory chunk.</returns>
+ public PlatformMemory Get(long memPtr)
+ {
+ long delta = memPtr - handle.ToInt64();
+
+ if (delta == PlatformMemoryUtils.PoolHdrOffMem1)
+ return _mem1 ?? (_mem1 = new PlatformPooledMemory(this, memPtr));
+
+ if (delta == PlatformMemoryUtils.PoolHdrOffMem2)
+ return _mem2 ?? (_mem2 = new PlatformPooledMemory(this, memPtr));
+
+ return _mem3 ?? (_mem3 = new PlatformPooledMemory(this, memPtr));
+ }
+
+ /** <inheritdoc /> */
+ protected override bool ReleaseHandle()
+ {
+ PlatformMemoryUtils.ReleasePool(handle.ToInt64());
+
+ handle = new IntPtr(-1);
+
+ return true;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
new file mode 100644
index 0000000..7af8392
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
@@ -0,0 +1,676 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Apache.Ignite.Core.Impl.Portable.IO;
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ using System;
+ using System.IO;
+ using System.Text;
+
+ /// <summary>
+ /// Platform memory stream.
+ /// </summary>
+ public unsafe class PlatformMemoryStream : IPortableStream
+ {
+ /** Length: 1 byte. */
+ protected const int Len1 = 1;
+
+ /** Length: 2 bytes. */
+ protected const int Len2 = 2;
+
+ /** Length: 4 bytes. */
+ protected const int Len4 = 4;
+
+ /** Length: 8 bytes. */
+ protected const int Len8 = 8;
+
+ /** Shift: 2 bytes. */
+ protected const int Shift2 = 1;
+
+ /** Shift: 4 bytes. */
+ protected const int Shift4 = 2;
+
+ /** Shift: 8 bytes. */
+ protected const int Shift8 = 3;
+
+ /** Underlying memory. */
+ private readonly IPlatformMemory _mem;
+
+ /** Actual data. */
+ protected byte* Data;
+
+ /** CalculateCapacity. */
+ private int _cap;
+
+ /** Position. */
+ private int _pos;
+
+ /** Length. */
+ private int _len;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="mem">Memory.</param>
+ public PlatformMemoryStream(IPlatformMemory mem)
+ {
+ _mem = mem;
+
+ Data = (byte*)mem.Data;
+ _cap = mem.Capacity;
+ _len = mem.Length;
+ }
+
+ #region WRITE
+
+ /** <inheritdoc /> */
+ public void WriteByte(byte val)
+ {
+ int curPos = EnsureWriteCapacityAndShift(Len1);
+
+ *(Data + curPos) = val;
+ }
+
+ /** <inheritdoc /> */
+ public void WriteByteArray(byte[] val)
+ {
+ fixed (byte* val0 = val)
+ {
+ CopyFromAndShift(val0, val.Length);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public void WriteBool(bool val)
+ {
+ WriteByte(val ? (byte)1 : (byte)0);
+ }
+
+ /** <inheritdoc /> */
+ public void WriteBoolArray(bool[] val)
+ {
+ fixed (bool* val0 = val)
+ {
+ CopyFromAndShift((byte*)val0, val.Length);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteShort(short val)
+ {
+ int curPos = EnsureWriteCapacityAndShift(Len2);
+
+ *((short*)(Data + curPos)) = val;
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteShortArray(short[] val)
+ {
+ fixed (short* val0 = val)
+ {
+ CopyFromAndShift((byte*)val0, val.Length << Shift2);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteChar(char val)
+ {
+ int curPos = EnsureWriteCapacityAndShift(Len2);
+
+ *((char*)(Data + curPos)) = val;
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteCharArray(char[] val)
+ {
+ fixed (char* val0 = val)
+ {
+ CopyFromAndShift((byte*)val0, val.Length << Shift2);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteInt(int val)
+ {
+ int curPos = EnsureWriteCapacityAndShift(Len4);
+
+ *((int*)(Data + curPos)) = val;
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteInt(int writePos, int val)
+ {
+ EnsureWriteCapacity(writePos + 4);
+
+ *((int*)(Data + writePos)) = val;
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteIntArray(int[] val)
+ {
+ fixed (int* val0 = val)
+ {
+ CopyFromAndShift((byte*)val0, val.Length << Shift4);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteLong(long val)
+ {
+ int curPos = EnsureWriteCapacityAndShift(Len8);
+
+ *((long*)(Data + curPos)) = val;
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteLongArray(long[] val)
+ {
+ fixed (long* val0 = val)
+ {
+ CopyFromAndShift((byte*)val0, val.Length << Shift8);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteFloat(float val)
+ {
+ int curPos = EnsureWriteCapacityAndShift(Len4);
+
+ *((float*)(Data + curPos)) = val;
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteFloatArray(float[] val)
+ {
+ fixed (float* val0 = val)
+ {
+ CopyFromAndShift((byte*)val0, val.Length << Shift4);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteDouble(double val)
+ {
+ int curPos = EnsureWriteCapacityAndShift(Len8);
+
+ *((double*)(Data + curPos)) = val;
+ }
+
+ /** <inheritdoc /> */
+ public virtual void WriteDoubleArray(double[] val)
+ {
+ fixed (double* val0 = val)
+ {
+ CopyFromAndShift((byte*)val0, val.Length << Shift8);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public int WriteString(char* chars, int charCnt, int byteCnt, Encoding enc)
+ {
+ int curPos = EnsureWriteCapacityAndShift(byteCnt);
+
+ return enc.GetBytes(chars, charCnt, Data + curPos, byteCnt);
+ }
+
+ /** <inheritdoc /> */
+ public void Write(byte[] src, int off, int cnt)
+ {
+ fixed (byte* src0 = src)
+ {
+ CopyFromAndShift(src0 + off, cnt);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public void Write(byte* src, int cnt)
+ {
+ CopyFromAndShift(src, cnt);
+ }
+
+ #endregion WRITE
+
+ #region READ
+
+ /** <inheritdoc /> */
+ public byte ReadByte()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len1);
+
+ return *(Data + curPos);
+ }
+
+ /** <inheritdoc /> */
+
+ public byte[] ReadByteArray(int cnt)
+ {
+ int curPos = EnsureReadCapacityAndShift(cnt);
+
+ byte[] res = new byte[cnt];
+
+ fixed (byte* res0 = res)
+ {
+ PlatformMemoryUtils.CopyMemory(Data + curPos, res0, cnt);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public bool ReadBool()
+ {
+ return ReadByte() == 1;
+ }
+
+ /** <inheritdoc /> */
+ public bool[] ReadBoolArray(int cnt)
+ {
+ bool[] res = new bool[cnt];
+
+ fixed (bool* res0 = res)
+ {
+ CopyToAndShift((byte*)res0, cnt);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public virtual short ReadShort()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len2);
+
+ return *((short*)(Data + curPos));
+ }
+
+ /** <inheritdoc /> */
+ public virtual short[] ReadShortArray(int cnt)
+ {
+ short[] res = new short[cnt];
+
+ fixed (short* res0 = res)
+ {
+ CopyToAndShift((byte*)res0, cnt << Shift2);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public virtual char ReadChar()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len2);
+
+ return *((char*)(Data + curPos));
+ }
+
+ /** <inheritdoc /> */
+ public virtual char[] ReadCharArray(int cnt)
+ {
+ char[] res = new char[cnt];
+
+ fixed (char* res0 = res)
+ {
+ CopyToAndShift((byte*)res0, cnt << Shift2);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public virtual int ReadInt()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len4);
+
+ return *((int*)(Data + curPos));
+ }
+
+ /** <inheritdoc /> */
+ public virtual int[] ReadIntArray(int cnt)
+ {
+ int[] res = new int[cnt];
+
+ fixed (int* res0 = res)
+ {
+ CopyToAndShift((byte*)res0, cnt << Shift4);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public virtual long ReadLong()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len8);
+
+ return *((long*)(Data + curPos));
+ }
+
+ /** <inheritdoc /> */
+ public virtual long[] ReadLongArray(int cnt)
+ {
+ long[] res = new long[cnt];
+
+ fixed (long* res0 = res)
+ {
+ CopyToAndShift((byte*)res0, cnt << Shift8);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public virtual float ReadFloat()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len4);
+
+ return *((float*)(Data + curPos));
+ }
+
+ /** <inheritdoc /> */
+ public virtual float[] ReadFloatArray(int cnt)
+ {
+ float[] res = new float[cnt];
+
+ fixed (float* res0 = res)
+ {
+ CopyToAndShift((byte*)res0, cnt << Shift4);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public virtual double ReadDouble()
+ {
+ int curPos = EnsureReadCapacityAndShift(Len8);
+
+ return *((double*)(Data + curPos));
+ }
+
+ /** <inheritdoc /> */
+ public virtual double[] ReadDoubleArray(int cnt)
+ {
+ double[] res = new double[cnt];
+
+ fixed (double* res0 = res)
+ {
+ CopyToAndShift((byte*)res0, cnt << Shift8);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public void Read(byte[] dest, int off, int cnt)
+ {
+ fixed (byte* dest0 = dest)
+ {
+ Read(dest0 + off, cnt);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public void Read(byte* dest, int cnt)
+ {
+ CopyToAndShift(dest, cnt);
+ }
+
+ #endregion
+
+ #region MISC
+
+ /// <summary>
+ /// Get cross-platform memory pointer for the stream.
+ /// </summary>
+ public long MemoryPointer
+ {
+ get { return _mem.Pointer; }
+ }
+
+ /// <summary>
+ /// Synchronize stream write opeartions with underlying memory and return current memory pointer.
+ /// <returns>Memory pointer.</returns>
+ /// </summary>
+ public long SynchronizeOutput()
+ {
+ if (_pos > _len)
+ _len = _pos;
+
+ _mem.Length = _len;
+
+ return MemoryPointer;
+ }
+
+ /// <summary>
+ /// Synchronized stream read operations from underlying memory. This is required when
+ /// </summary>
+ public void SynchronizeInput()
+ {
+ Data = (byte*)_mem.Data;
+ _cap = _mem.Capacity;
+ _len = _mem.Length;
+ }
+
+ /// <summary>
+ /// Reset stream state. Sets both position and length to 0.
+ /// </summary>
+ public void Reset()
+ {
+ _pos = 0;
+ }
+
+ /// <summary>
+ /// Reset stream state as if it was just created.
+ /// </summary>
+ public void Reuse()
+ {
+ Data = (byte*)_mem.Data;
+ _cap = _mem.Capacity;
+ _len = _mem.Length;
+ _pos = 0;
+ }
+
+ /** <inheritdoc /> */
+ public int Seek(int offset, SeekOrigin origin)
+ {
+ int newPos;
+
+ switch (origin)
+ {
+ case SeekOrigin.Begin:
+ {
+ newPos = offset;
+
+ break;
+ }
+
+ case SeekOrigin.Current:
+ {
+ newPos = _pos + offset;
+
+ break;
+ }
+
+ default:
+ throw new ArgumentException("Unsupported seek origin: " + origin);
+ }
+
+ if (newPos < 0)
+ throw new ArgumentException("Seek before origin: " + newPos);
+
+ EnsureWriteCapacity(newPos);
+
+ _pos = newPos;
+
+ return _pos;
+ }
+
+ /// <summary>
+ /// Ensure capacity for write and shift position.
+ /// </summary>
+ /// <param name="cnt">Bytes count.</param>
+ /// <returns>Position before shift.</returns>
+ protected int EnsureWriteCapacityAndShift(int cnt)
+ {
+ int curPos = _pos;
+
+ int newPos = _pos + cnt;
+
+ EnsureWriteCapacity(newPos);
+
+ _pos = newPos;
+
+ return curPos;
+ }
+
+ /// <summary>
+ /// Ensure write capacity.
+ /// </summary>
+ /// <param name="reqCap">Required capacity.</param>
+ protected void EnsureWriteCapacity(int reqCap)
+ {
+ if (reqCap > _cap)
+ {
+ reqCap = CalculateCapacity(_cap, reqCap);
+
+ _mem.Reallocate(reqCap);
+
+ Data = (byte*)_mem.Data;
+ _cap = _mem.Capacity;
+ }
+ }
+
+ /// <summary>
+ /// Ensure capacity for read and shift position.
+ /// </summary>
+ /// <param name="cnt">Bytes count.</param>
+ /// <returns>Position before shift.</returns>
+ protected int EnsureReadCapacityAndShift(int cnt)
+ {
+ int curPos = _pos;
+
+ if (_len - _pos < cnt)
+ throw new EndOfStreamException("Not enough data in stream [expected=" + cnt +
+ ", remaining=" + (_len - _pos) + ']');
+
+ _pos += cnt;
+
+ return curPos;
+ }
+
+ /// <summary>
+ /// Copy (read) some data into destination and shift the stream forward.
+ /// </summary>
+ /// <param name="dest">Destination.</param>
+ /// <param name="cnt">Bytes count.</param>
+ private void CopyToAndShift(byte* dest, int cnt)
+ {
+ int curPos = EnsureReadCapacityAndShift(cnt);
+
+ PlatformMemoryUtils.CopyMemory(Data + curPos, dest, cnt);
+ }
+
+ /// <summary>
+ /// Copy (write) some data from source and shift the stream forward.
+ /// </summary>
+ /// <param name="src">Source.</param>
+ /// <param name="cnt">Bytes count.</param>
+ private void CopyFromAndShift(byte* src, int cnt)
+ {
+ int curPos = EnsureWriteCapacityAndShift(cnt);
+
+ PlatformMemoryUtils.CopyMemory(src, Data + curPos, cnt);
+ }
+
+ /// <summary>
+ /// Calculate new capacity.
+ /// </summary>
+ /// <param name="curCap">Current capacity.</param>
+ /// <param name="reqCap">Required capacity.</param>
+ /// <returns>New capacity.</returns>
+ private static int CalculateCapacity(int curCap, int reqCap)
+ {
+ int newCap;
+
+ if (reqCap < 256)
+ newCap = 256;
+ else
+ {
+ newCap = curCap << 1;
+
+ if (newCap < reqCap)
+ newCap = reqCap;
+ }
+
+ return newCap;
+ }
+
+ /** <inheritdoc /> */
+ public int Position
+ {
+ get { return _pos; }
+ }
+
+ /** <inheritdoc /> */
+ public int Remaining()
+ {
+ return _len - _pos;
+ }
+
+ /** <inheritdoc /> */
+ public void Dispose()
+ {
+ SynchronizeOutput();
+
+ _mem.Release();
+ }
+
+ #endregion
+
+ #region ARRAYS
+
+ /** <inheritdoc /> */
+ public byte[] Array()
+ {
+ return ArrayCopy();
+ }
+
+ /** <inheritdoc /> */
+ public byte[] ArrayCopy()
+ {
+ byte[] res = new byte[_mem.Length];
+
+ fixed (byte* res0 = res)
+ {
+ PlatformMemoryUtils.CopyMemory(Data, res0, res.Length);
+ }
+
+ return res;
+ }
+
+ /** <inheritdoc /> */
+ public bool IsSameArray(byte[] arr)
+ {
+ return false;
+ }
+
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs
new file mode 100644
index 0000000..fc942a0
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs
@@ -0,0 +1,462 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ using System;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Reflection;
+ using System.Runtime.InteropServices;
+
+ /// <summary>
+ /// Utility methods for platform memory management.
+ /// </summary>
+ public static unsafe class PlatformMemoryUtils
+ {
+ #region CONSTANTS
+
+ /** Header length. */
+ private const int PoolHdrLen = 64;
+
+ /** Pool header offset: first memory chunk. */
+ internal const int PoolHdrOffMem1 = 0;
+
+ /** Pool header offset: second memory chunk. */
+ internal const int PoolHdrOffMem2 = 20;
+
+ /** Pool header offset: third memory chunk. */
+ internal const int PoolHdrOffMem3 = 40;
+
+ /** Memory chunk header length. */
+ private const int MemHdrLen = 20;
+
+ /** Offset: capacity. */
+ private const int MemHdrOffCap = 8;
+
+ /** Offset: length. */
+ private const int MemHdrOffLen = 12;
+
+ /** Offset: flags. */
+ private const int MemHdrOffFlags = 16;
+
+ /** Flag: external. */
+ private const int FlagExt = 0x1;
+
+ /** Flag: pooled. */
+ private const int FlagPooled = 0x2;
+
+ /** Flag: whether this pooled memory chunk is acquired. */
+ private const int FlagAcquired = 0x4;
+
+ #endregion
+
+ #region COMMON
+
+ /// <summary>
+ /// Gets data pointer for the given memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns>Data pointer.</returns>
+ public static long Data(long memPtr)
+ {
+ return *((long*)memPtr);
+ }
+
+ /// <summary>
+ /// Gets capacity for the given memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns>CalculateCapacity.</returns>
+ public static int Capacity(long memPtr)
+ {
+ return *((int*)(memPtr + MemHdrOffCap));
+ }
+
+ /// <summary>
+ /// Sets capacity for the given memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <param name="cap">CalculateCapacity.</param>
+ public static void Capacity(long memPtr, int cap)
+ {
+ *((int*)(memPtr + MemHdrOffCap)) = cap;
+ }
+
+ /// <summary>
+ /// Gets length for the given memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns>Length.</returns>
+ public static int Length(long memPtr)
+ {
+ return *((int*)(memPtr + MemHdrOffLen));
+ }
+
+ /// <summary>
+ /// Sets length for the given memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <param name="len">Length.</param>
+ public static void Length(long memPtr, int len)
+ {
+ *((int*)(memPtr + MemHdrOffLen)) = len;
+ }
+
+ /// <summary>
+ /// Gets flags for the given memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns>Flags.</returns>
+ public static int Flags(long memPtr)
+ {
+ return *((int*)(memPtr + MemHdrOffFlags));
+ }
+
+ /// <summary>
+ /// Sets flags for the given memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <param name="flags">Flags.</param>
+ public static void Flags(long memPtr, int flags)
+ {
+ *((int*)(memPtr + MemHdrOffFlags)) = flags;
+ }
+
+ /// <summary>
+ /// Check whether this memory chunk is external.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns><c>True</c> if owned by Java.</returns>
+ public static bool IsExternal(long memPtr)
+ {
+ return IsExternal(Flags(memPtr));
+ }
+
+ /// <summary>
+ /// Check whether flags denote that this memory chunk is external.
+ /// </summary>
+ /// <param name="flags">Flags.</param>
+ /// <returns><c>True</c> if owned by Java.</returns>
+ public static bool IsExternal(int flags)
+ {
+ return (flags & FlagExt) != FlagExt;
+ }
+
+ /// <summary>
+ /// Check whether this memory chunk is pooled.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns><c>True</c> if pooled.</returns>
+ public static bool IsPooled(long memPtr)
+ {
+ return IsPooled(Flags(memPtr));
+ }
+
+ /// <summary>
+ /// Check whether flags denote pooled memory chunk.
+ /// </summary>
+ /// <param name="flags">Flags.</param>
+ /// <returns><c>True</c> if pooled.</returns>
+ public static bool IsPooled(int flags)
+ {
+ return (flags & FlagPooled) != 0;
+ }
+
+ /// <summary>
+ /// Check whether this memory chunk is pooled and acquired.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns><c>True</c> if acquired.</returns>
+ public static bool IsAcquired(long memPtr)
+ {
+ return IsAcquired(Flags(memPtr));
+ }
+
+ /// <summary>
+ /// Check whether flags denote pooled and acquired memory chunk.
+ /// </summary>
+ /// <param name="flags">Flags.</param>
+ /// <returns><c>True</c> if acquired.</returns>
+ public static bool IsAcquired(int flags)
+ {
+ return (flags & FlagAcquired) != 0;
+ }
+
+ #endregion
+
+ #region UNPOOLED MEMORY
+
+ /// <summary>
+ /// Allocate unpooled memory chunk.
+ /// </summary>
+ /// <param name="cap">Minimum capacity.</param>
+ /// <returns>New memory pointer.</returns>
+ public static long AllocateUnpooled(int cap)
+ {
+ long memPtr = Marshal.AllocHGlobal(MemHdrLen).ToInt64();
+ long dataPtr = Marshal.AllocHGlobal(cap).ToInt64();
+
+ *((long*)memPtr) = dataPtr;
+ *((int*)(memPtr + MemHdrOffCap)) = cap;
+ *((int*)(memPtr + MemHdrOffLen)) = 0;
+ *((int*)(memPtr + MemHdrOffFlags)) = FlagExt;
+
+ return memPtr;
+ }
+
+
+ /// <summary>
+ /// Reallocate unpooled memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <param name="cap">Minimum capacity.</param>
+ /// <returns></returns>
+ public static void ReallocateUnpooled(long memPtr, int cap)
+ {
+ long dataPtr = Data(memPtr);
+
+ long newDataPtr = Marshal.ReAllocHGlobal((IntPtr)dataPtr, (IntPtr)cap).ToInt64();
+
+ if (dataPtr != newDataPtr)
+ *((long*)memPtr) = newDataPtr; // Write new data address if needed.
+
+ *((int*)(memPtr + MemHdrOffCap)) = cap; // Write new capacity.
+ }
+
+ /// <summary>
+ /// Release unpooled memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ public static void ReleaseUnpooled(long memPtr)
+ {
+ Marshal.FreeHGlobal((IntPtr)Data(memPtr));
+ Marshal.FreeHGlobal((IntPtr)memPtr);
+ }
+
+ #endregion
+
+ #region POOLED MEMORY
+
+ /// <summary>
+ /// Allocate pool memory.
+ /// </summary>
+ /// <returns>Pool pointer.</returns>
+ public static long AllocatePool()
+ {
+ // 1. Allocate memory.
+ long poolPtr = Marshal.AllocHGlobal((IntPtr)PoolHdrLen).ToInt64();
+
+ // 2. Clear memory.
+ for (int i = 0; i < PoolHdrLen; i += 8)
+ *((long*)(poolPtr + i)) = 0;
+
+ // 3. Set flags for memory chunks.
+ Flags(poolPtr + PoolHdrOffMem1, FlagExt | FlagPooled);
+ Flags(poolPtr + PoolHdrOffMem2, FlagExt | FlagPooled);
+ Flags(poolPtr + PoolHdrOffMem3, FlagExt | FlagPooled);
+
+ return poolPtr;
+ }
+
+ /// <summary>
+ /// Release pool memory.
+ /// </summary>
+ /// <param name="poolPtr">Pool pointer.</param>
+ public static void ReleasePool(long poolPtr)
+ {
+ // Clean predefined memory chunks.
+ long mem = *((long*)(poolPtr + PoolHdrOffMem1));
+
+ if (mem != 0)
+ Marshal.FreeHGlobal((IntPtr)mem);
+
+ mem = *((long*)(poolPtr + PoolHdrOffMem2));
+
+ if (mem != 0)
+ Marshal.FreeHGlobal((IntPtr)mem);
+
+ mem = *((long*)(poolPtr + PoolHdrOffMem3));
+
+ if (mem != 0)
+ Marshal.FreeHGlobal((IntPtr)mem);
+
+ // Clean pool chunk.
+ Marshal.FreeHGlobal((IntPtr)poolPtr);
+ }
+
+ /// <summary>
+ /// Allocate pooled memory chunk.
+ /// </summary>
+ /// <param name="poolPtr">Pool pointer.</param>
+ /// <param name="cap">CalculateCapacity.</param>
+ /// <returns>Memory pointer or <c>0</c> in case there are no free memory chunks in the pool.</returns>
+ public static long AllocatePooled(long poolPtr, int cap)
+ {
+ long memPtr = poolPtr + PoolHdrOffMem1;
+
+ if (IsAcquired(memPtr))
+ {
+ memPtr = poolPtr + PoolHdrOffMem2;
+
+ if (IsAcquired(memPtr))
+ {
+ memPtr = poolPtr + PoolHdrOffMem3;
+
+ if (IsAcquired(memPtr))
+ memPtr = 0;
+ else
+ AllocatePooled0(memPtr, cap);
+ }
+ else
+ AllocatePooled0(memPtr, cap);
+ }
+ else
+ AllocatePooled0(memPtr, cap);
+
+ return memPtr;
+ }
+
+ /// <summary>
+ /// Internal pooled memory chunk allocation routine.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <param name="cap">CalculateCapacity.</param>
+ private static void AllocatePooled0(long memPtr, int cap)
+ {
+ long data = *((long*)memPtr);
+
+ if (data == 0) {
+ // First allocation of the chunk.
+ data = Marshal.AllocHGlobal(cap).ToInt64();
+
+ *((long*)memPtr) = data;
+ *((int*)(memPtr + MemHdrOffCap)) = cap;
+ }
+ else {
+ // Ensure that we have enough capacity.
+ int curCap = Capacity(memPtr);
+
+ if (cap > curCap) {
+ data = Marshal.ReAllocHGlobal((IntPtr)data, (IntPtr)cap).ToInt64();
+
+ *((long*)memPtr) = data;
+ *((int*)(memPtr + MemHdrOffCap)) = cap;
+ }
+ }
+
+ Flags(memPtr, FlagExt | FlagPooled | FlagAcquired);
+ }
+
+ /// <summary>
+ /// Reallocate pooled memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <param name="cap">Minimum capacity.</param>
+ public static void ReallocatePooled(long memPtr, int cap)
+ {
+ long data = *((long*)memPtr);
+
+ int curCap = Capacity(memPtr);
+
+ if (cap > curCap) {
+ data = Marshal.ReAllocHGlobal((IntPtr)data, (IntPtr)cap).ToInt64();
+
+ *((long*)memPtr) = data;
+ *((int*)(memPtr + MemHdrOffCap)) = cap;
+ }
+ }
+
+ /// <summary>
+ /// Release pooled memory chunk.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ public static void ReleasePooled(long memPtr)
+ {
+ Flags(memPtr, Flags(memPtr) ^ FlagAcquired);
+ }
+
+ #endregion
+
+ #region MEMCPY
+
+ /** Array copy delegate. */
+ private delegate void MemCopy(byte* a1, byte* a2, int len);
+
+ /** memcpy function handle. */
+ private static readonly MemCopy Memcpy;
+
+ /** Whether src and dest arguments are inverted. */
+ private static readonly bool MemcpyInverted;
+
+ /// <summary>
+ /// Static initializer.
+ /// </summary>
+ [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
+ static PlatformMemoryUtils()
+ {
+ Type type = typeof(Buffer);
+
+ const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic;
+ Type[] paramTypes = { typeof(byte*), typeof(byte*), typeof(int) };
+
+ // Assume .Net 4.5.
+ MethodInfo mthd = type.GetMethod("Memcpy", flags, null, paramTypes, null);
+
+ MemcpyInverted = true;
+
+ if (mthd == null)
+ {
+ // Assume .Net 4.0.
+ mthd = type.GetMethod("memcpyimpl", flags, null, paramTypes, null);
+
+ MemcpyInverted = false;
+
+ if (mthd == null)
+ throw new InvalidOperationException("Unable to get memory copy function delegate.");
+ }
+
+ Memcpy = (MemCopy)Delegate.CreateDelegate(typeof(MemCopy), mthd);
+ }
+
+ /// <summary>
+ /// Unsafe memory copy routine.
+ /// </summary>
+ /// <param name="src">Source.</param>
+ /// <param name="dest">Destination.</param>
+ /// <param name="len">Length.</param>
+ public static void CopyMemory(void* src, void* dest, int len)
+ {
+ CopyMemory((byte*)src, (byte*)dest, len);
+ }
+
+ /// <summary>
+ /// Unsafe memory copy routine.
+ /// </summary>
+ /// <param name="src">Source.</param>
+ /// <param name="dest">Destination.</param>
+ /// <param name="len">Length.</param>
+ public static void CopyMemory(byte* src, byte* dest, int len)
+ {
+ if (MemcpyInverted)
+ Memcpy.Invoke(dest, src, len);
+ else
+ Memcpy.Invoke(src, dest, len);
+ }
+
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformPooledMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformPooledMemory.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformPooledMemory.cs
new file mode 100644
index 0000000..7709ca4
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformPooledMemory.cs
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ /// <summary>
+ /// Platform pooled memory chunk.
+ /// </summary>
+ internal class PlatformPooledMemory : PlatformMemory
+ {
+ /** Pool. */
+ private readonly PlatformMemoryPool _pool;
+
+ /** Cached stream. */
+ private PlatformMemoryStream _stream;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="pool">Pool.</param>
+ /// <param name="memPtr">Memory pointer.</param>
+ public PlatformPooledMemory(PlatformMemoryPool pool, long memPtr) : base(memPtr)
+ {
+ this._pool = pool;
+ }
+
+ /** <inheritdoc /> */
+ public override PlatformMemoryStream Stream()
+ {
+ if (_stream == null)
+ _stream = base.Stream();
+ else
+ _stream.Reuse();
+
+ return _stream;
+ }
+
+ /** <inheritdoc /> */
+ public override void Reallocate(int cap)
+ {
+ // Try doubling capacity to avoid excessive allocations.
+ int doubledCap = PlatformMemoryUtils.Capacity(MemPtr) << 1;
+
+ if (doubledCap > cap)
+ cap = doubledCap;
+
+ _pool.Reallocate(MemPtr, cap);
+ }
+
+ /** <inheritdoc /> */
+ public override void Release()
+ {
+ _pool.Release(MemPtr); // Return to the pool.
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs
new file mode 100644
index 0000000..6de9f43
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ using System;
+
+ /// <summary>
+ /// Non-resizeable raw memory chunk without metadata header.
+ /// </summary>
+ public class PlatformRawMemory : IPlatformMemory
+ {
+ /** */
+ private readonly long _memPtr;
+
+ /** */
+ private readonly int _size;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PlatformRawMemory"/> class.
+ /// </summary>
+ /// <param name="memPtr">Heap pointer.</param>
+ /// <param name="size">Size.</param>
+ public unsafe PlatformRawMemory(void* memPtr, int size)
+ {
+ _memPtr = (long) memPtr;
+ _size = size;
+ }
+
+ /** <inheritdoc /> */
+ public PlatformMemoryStream Stream()
+ {
+ return BitConverter.IsLittleEndian ? new PlatformMemoryStream(this) :
+ new PlatformBigEndianMemoryStream(this);
+ }
+
+ /** <inheritdoc /> */
+ public long Pointer
+ {
+ get { throw new NotSupportedException(); }
+ }
+
+ /** <inheritdoc /> */
+ public long Data
+ {
+ get { return _memPtr; }
+ }
+
+ /** <inheritdoc /> */
+ public int Capacity
+ {
+ get { return _size; }
+ }
+
+ /** <inheritdoc /> */
+ public int Length
+ {
+ get { return _size; }
+ set { throw new NotSupportedException(); }
+ }
+
+ /** <inheritdoc /> */
+ public void Reallocate(int cap)
+ {
+ throw new NotSupportedException();
+ }
+
+ /** <inheritdoc /> */
+ public void Release()
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformUnpooledMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformUnpooledMemory.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformUnpooledMemory.cs
new file mode 100644
index 0000000..26c1bc1
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformUnpooledMemory.cs
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Memory
+{
+ /// <summary>
+ /// Platform unpooled memory chunk.
+ /// </summary>
+ internal class PlatformUnpooledMemory : PlatformMemory
+ {
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="memPtr">Memory pointer.</param>
+ public PlatformUnpooledMemory(long memPtr) : base(memPtr)
+ {
+ // No-op.
+ }
+
+ /** <inheritdoc /> */
+ public override void Reallocate(int cap)
+ {
+ // Try doubling capacity to avoid excessive allocations.
+ int doubledCap = ((PlatformMemoryUtils.Capacity(MemPtr) + 16) << 1) - 16;
+
+ if (doubledCap > cap)
+ cap = doubledCap;
+
+ PlatformMemoryUtils.ReallocateUnpooled(MemPtr, cap);
+ }
+
+ /** <inheritdoc /> */
+ public override void Release()
+ {
+ PlatformMemoryUtils.ReleaseUnpooled(MemPtr);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/Io/IPortableStream.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/Io/IPortableStream.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/Io/IPortableStream.cs
new file mode 100644
index 0000000..8111117
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/Io/IPortableStream.cs
@@ -0,0 +1,320 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Apache.Ignite.Core.Impl.Portable.IO
+{
+ using System;
+ using System.IO;
+ using System.Text;
+
+ /// <summary>
+ /// Stream capable of working with portable objects.
+ /// </summary>
+ [CLSCompliant(false)]
+ public unsafe interface IPortableStream : IDisposable
+ {
+ /// <summary>
+ /// Write bool.
+ /// </summary>
+ /// <param name="val">Bool value.</param>
+ void WriteBool(bool val);
+
+ /// <summary>
+ /// Read bool.
+ /// </summary>
+ /// <returns>Bool value.</returns>
+ bool ReadBool();
+
+ /// <summary>
+ /// Write bool array.
+ /// </summary>
+ /// <param name="val">Bool array.</param>
+ void WriteBoolArray(bool[] val);
+
+ /// <summary>
+ /// Read bool array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Bool array.</returns>
+ bool[] ReadBoolArray(int cnt);
+
+ /// <summary>
+ /// Write byte.
+ /// </summary>
+ /// <param name="val">Byte value.</param>
+ void WriteByte(byte val);
+
+ /// <summary>
+ /// Read byte.
+ /// </summary>
+ /// <returns>Byte value.</returns>
+ byte ReadByte();
+
+ /// <summary>
+ /// Write byte array.
+ /// </summary>
+ /// <param name="val">Byte array.</param>
+ void WriteByteArray(byte[] val);
+
+ /// <summary>
+ /// Read byte array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Byte array.</returns>
+ byte[] ReadByteArray(int cnt);
+
+ /// <summary>
+ /// Write short.
+ /// </summary>
+ /// <param name="val">Short value.</param>
+ void WriteShort(short val);
+
+ /// <summary>
+ /// Read short.
+ /// </summary>
+ /// <returns>Short value.</returns>
+ short ReadShort();
+
+ /// <summary>
+ /// Write short array.
+ /// </summary>
+ /// <param name="val">Short array.</param>
+ void WriteShortArray(short[] val);
+
+ /// <summary>
+ /// Read short array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Short array.</returns>
+ short[] ReadShortArray(int cnt);
+
+ /// <summary>
+ /// Write char.
+ /// </summary>
+ /// <param name="val">Char value.</param>
+ void WriteChar(char val);
+
+ /// <summary>
+ /// Read char.
+ /// </summary>
+ /// <returns>Char value.</returns>
+ char ReadChar();
+
+ /// <summary>
+ /// Write char array.
+ /// </summary>
+ /// <param name="val">Char array.</param>
+ void WriteCharArray(char[] val);
+
+ /// <summary>
+ /// Read char array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Char array.</returns>
+ char[] ReadCharArray(int cnt);
+
+ /// <summary>
+ /// Write int.
+ /// </summary>
+ /// <param name="val">Int value.</param>
+ void WriteInt(int val);
+
+ /// <summary>
+ /// Write int to specific position.
+ /// </summary>
+ /// <param name="writePos">Position.</param>
+ /// <param name="val">Value.</param>
+ void WriteInt(int writePos, int val);
+
+ /// <summary>
+ /// Read int.
+ /// </summary>
+ /// <returns>Int value.</returns>
+ int ReadInt();
+
+ /// <summary>
+ /// Write int array.
+ /// </summary>
+ /// <param name="val">Int array.</param>
+ void WriteIntArray(int[] val);
+
+ /// <summary>
+ /// Read int array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Int array.</returns>
+ int[] ReadIntArray(int cnt);
+
+ /// <summary>
+ /// Write long.
+ /// </summary>
+ /// <param name="val">Long value.</param>
+ void WriteLong(long val);
+
+ /// <summary>
+ /// Read long.
+ /// </summary>
+ /// <returns>Long value.</returns>
+ long ReadLong();
+
+ /// <summary>
+ /// Write long array.
+ /// </summary>
+ /// <param name="val">Long array.</param>
+ void WriteLongArray(long[] val);
+
+ /// <summary>
+ /// Read long array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Long array.</returns>
+ long[] ReadLongArray(int cnt);
+
+ /// <summary>
+ /// Write float.
+ /// </summary>
+ /// <param name="val">Float value.</param>
+ void WriteFloat(float val);
+
+ /// <summary>
+ /// Read float.
+ /// </summary>
+ /// <returns>Float value.</returns>
+ float ReadFloat();
+
+ /// <summary>
+ /// Write float array.
+ /// </summary>
+ /// <param name="val">Float array.</param>
+ void WriteFloatArray(float[] val);
+
+ /// <summary>
+ /// Read float array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Float array.</returns>
+ float[] ReadFloatArray(int cnt);
+
+ /// <summary>
+ /// Write double.
+ /// </summary>
+ /// <param name="val">Double value.</param>
+ void WriteDouble(double val);
+
+ /// <summary>
+ /// Read double.
+ /// </summary>
+ /// <returns>Double value.</returns>
+ double ReadDouble();
+
+ /// <summary>
+ /// Write double array.
+ /// </summary>
+ /// <param name="val">Double array.</param>
+ void WriteDoubleArray(double[] val);
+
+ /// <summary>
+ /// Read double array.
+ /// </summary>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Double array.</returns>
+ double[] ReadDoubleArray(int cnt);
+
+ /// <summary>
+ /// Write string.
+ /// </summary>
+ /// <param name="chars">Characters.</param>
+ /// <param name="charCnt">Char count.</param>
+ /// <param name="byteCnt">Byte count.</param>
+ /// <param name="encoding">Encoding.</param>
+ /// <returns>Amounts of bytes written.</returns>
+ int WriteString(char* chars, int charCnt, int byteCnt, Encoding encoding);
+
+ /// <summary>
+ /// Write arbitrary data.
+ /// </summary>
+ /// <param name="src">Source array.</param>
+ /// <param name="off">Offset</param>
+ /// <param name="cnt">Count.</param>
+ void Write(byte[] src, int off, int cnt);
+
+ /// <summary>
+ /// Read arbitrary data.
+ /// </summary>
+ /// <param name="dest">Destination array.</param>
+ /// <param name="off">Offset.</param>
+ /// <param name="cnt">Count.</param>
+ /// <returns>Amount of bytes read.</returns>
+ void Read(byte[] dest, int off, int cnt);
+
+ /// <summary>
+ /// Write arbitrary data.
+ /// </summary>
+ /// <param name="src">Source.</param>
+ /// <param name="cnt">Count.</param>
+ void Write(byte* src, int cnt);
+
+ /// <summary>
+ /// Read arbitrary data.
+ /// </summary>
+ /// <param name="dest">Destination.</param>
+ /// <param name="cnt">Count.</param>
+ void Read(byte* dest, int cnt);
+
+ /// <summary>
+ /// Position.
+ /// </summary>
+ int Position
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets remaining bytes in the stream.
+ /// </summary>
+ /// <returns>Remaining bytes.</returns>
+ int Remaining();
+
+ /// <summary>
+ /// Gets underlying array, avoiding copying if possible.
+ /// </summary>
+ /// <returns>Underlying array.</returns>
+ byte[] Array();
+
+ /// <summary>
+ /// Gets underlying data in a new array.
+ /// </summary>
+ /// <returns>New array with data.</returns>
+ byte[] ArrayCopy();
+
+ /// <summary>
+ /// Check whether array passed as argument is the same as the stream hosts.
+ /// </summary>
+ /// <param name="arr">Array.</param>
+ /// <returns><c>True</c> if they are same.</returns>
+ bool IsSameArray(byte[] arr);
+
+ /// <summary>
+ /// Seek to the given positoin.
+ /// </summary>
+ /// <param name="offset">Offset.</param>
+ /// <param name="origin">Seek origin.</param>
+ /// <returns>Position.</returns>
+ int Seek(int offset, SeekOrigin origin);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
index 9d99a3d..4127523 100644
--- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
@@ -15,7 +15,9 @@
* limitations under the License.
*/
+using System;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Apache.Ignite.Core")]
@@ -33,3 +35,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyVersion("1.4.1.0")]
[assembly: AssemblyFileVersion("1.4.1.0")]
+
+[assembly: CLSCompliant(true)]
+
+[assembly: InternalsVisibleTo("Apache.Ignite.Core.Tests")]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/main/dotnet/Apache.Ignite.sln.DotSettings
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.sln.DotSettings b/modules/platform/src/main/dotnet/Apache.Ignite.sln.DotSettings
new file mode 100644
index 0000000..187a909
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.sln.DotSettings
@@ -0,0 +1,4 @@
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
+
+ <s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/7b61a097/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index 21dc6ce..9e8f9d1 100644
--- a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -31,6 +31,13 @@
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Release\</OutputPath>
</PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="nunit-console-runner">
<HintPath>..\libs\nunit-console-runner.dll</HintPath>
@@ -44,6 +51,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="IgnitionTest.cs" />
+ <Compile Include="Memory\InteropMemoryTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestRunner.cs" />
</ItemGroup>