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/ignite-884 Commit: 7b61a0973027ac5a7c3d508018503ca2621a1092 Parents: 14718f9 Author: vozerov-gridgain <voze...@gridgain.com> Authored: Tue Aug 25 13:05:16 2015 +0300 Committer: vozerov-gridgain <voze...@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>