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/09/21 16:27:34 UTC
[38/52] [partial] ignite git commit: IGNITE-1513: Moved .Net.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs
new file mode 100644
index 0000000..3a9ed26
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemory.cs
@@ -0,0 +1,78 @@
+/*
+ * 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>
+ [CLSCompliant(false)]
+ 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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs
new file mode 100644
index 0000000..b280140
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryManager.cs
@@ -0,0 +1,107 @@
+/*
+ * 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.")]
+ [CLSCompliant(false)]
+ 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)
+ {
+ return new InteropExternalMemory(memPtr);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.cs
new file mode 100644
index 0000000..75e8965
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryPool.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 Microsoft.Win32.SafeHandles;
+
+ /// <summary>
+ /// Platform memory pool.
+ /// </summary>
+ [CLSCompliant(false)]
+ 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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
new file mode 100644
index 0000000..71da18f
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
@@ -0,0 +1,677 @@
+/*
+ * 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.IO;
+ using System.Text;
+ using Apache.Ignite.Core.Impl.Portable.IO;
+
+ /// <summary>
+ /// Platform memory stream.
+ /// </summary>
+ [CLSCompliant(false)]
+ 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 stream was passed
+ /// to Java and something might have been written there.
+ /// </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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs
new file mode 100644
index 0000000..dd53281
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryUtils.cs
@@ -0,0 +1,463 @@
+/*
+ * 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>
+ [CLSCompliant(false)]
+ 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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformPooledMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformPooledMemory.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformPooledMemory.cs
new file mode 100644
index 0000000..206df4b
--- /dev/null
+++ b/modules/platform/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)
+ {
+ _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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs
new file mode 100644
index 0000000..59c915b
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformRawMemory.cs
@@ -0,0 +1,89 @@
+/*
+ * 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>
+ [CLSCompliant(false)]
+ 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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformUnpooledMemory.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformUnpooledMemory.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformUnpooledMemory.cs
new file mode 100644
index 0000000..26c1bc1
--- /dev/null
+++ b/modules/platform/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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs
new file mode 100644
index 0000000..21c66bf
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs
@@ -0,0 +1,179 @@
+/*
+ * 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.Messaging
+{
+ using System;
+ using System.Diagnostics;
+ using Apache.Ignite.Core.Impl.Common;
+ using Apache.Ignite.Core.Impl.Handle;
+ using Apache.Ignite.Core.Impl.Portable;
+ using Apache.Ignite.Core.Impl.Portable.IO;
+ using Apache.Ignite.Core.Impl.Resource;
+ using Apache.Ignite.Core.Messaging;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Non-generic portable filter wrapper.
+ /// </summary>
+ internal class MessageFilterHolder : IPortableWriteAware, IHandle
+ {
+ /** Invoker function that takes key and value and invokes wrapped IMessageFilter */
+ private readonly Func<Guid, object, bool> _invoker;
+
+ /** Current Ignite instance. */
+ private readonly Ignite _ignite;
+
+ /** Underlying filter. */
+ private readonly object _filter;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MessageFilterHolder" /> class.
+ /// </summary>
+ /// <param name="grid">Grid.</param>
+ /// <param name="filter">The <see cref="IMessageFilter{T}" /> to wrap.</param>
+ /// <param name="invoker">The invoker func that takes key and value and invokes wrapped IMessageFilter.</param>
+ private MessageFilterHolder(Ignite grid, object filter, Func<Guid, object, bool> invoker)
+ {
+ Debug.Assert(filter != null);
+ Debug.Assert(invoker != null);
+
+ _invoker = invoker;
+
+ _filter = filter;
+
+ // 1. Set fields.
+ Debug.Assert(grid != null);
+
+ _ignite = grid;
+ _invoker = invoker;
+
+ // 2. Perform injections.
+ ResourceProcessor.Inject(filter, grid);
+ }
+
+ /// <summary>
+ /// Invoke the filter.
+ /// </summary>
+ /// <param name="input">Input.</param>
+ /// <returns></returns>
+ public int Invoke(IPortableStream input)
+ {
+ var rawReader = _ignite.Marshaller.StartUnmarshal(input).RawReader();
+
+ var nodeId = rawReader.ReadGuid();
+
+ Debug.Assert(nodeId != null);
+
+ return _invoker(nodeId.Value, rawReader.ReadObject<object>()) ? 1 : 0;
+ }
+
+ /// <summary>
+ /// Wrapped <see cref="IMessageFilter{T}" />.
+ /// </summary>
+ public object Filter
+ {
+ get { return _filter; }
+ }
+
+ /// <summary>
+ /// Destroy callback.
+ /// </summary>
+ public Action DestroyAction { private get; set; }
+
+ /** <inheritDoc /> */
+ public void Release()
+ {
+ if (DestroyAction != null)
+ DestroyAction();
+ }
+
+ /** <inheritDoc /> */
+ public bool Released
+ {
+ get { return false; } // Multiple releases are allowed.
+ }
+
+ /// <summary>
+ /// Creates local holder instance.
+ /// </summary>
+ /// <param name="grid">Ignite instance.</param>
+ /// <param name="filter">Filter.</param>
+ /// <returns>
+ /// New instance of <see cref="MessageFilterHolder" />
+ /// </returns>
+ public static MessageFilterHolder CreateLocal<T>(Ignite grid, IMessageFilter<T> filter)
+ {
+ Debug.Assert(filter != null);
+
+ return new MessageFilterHolder(grid, filter, (id, msg) => filter.Invoke(id, (T)msg));
+ }
+
+ /// <summary>
+ /// Creates remote holder instance.
+ /// </summary>
+ /// <param name="grid">Grid.</param>
+ /// <param name="memPtr">Memory pointer.</param>
+ /// <returns>Deserialized instance of <see cref="MessageFilterHolder"/></returns>
+ public static MessageFilterHolder CreateRemote(Ignite grid, long memPtr)
+ {
+ Debug.Assert(grid != null);
+
+ var stream = IgniteManager.Memory.Get(memPtr).Stream();
+
+ var holder = grid.Marshaller.Unmarshal<MessageFilterHolder>(stream);
+
+ return holder;
+ }
+
+ /// <summary>
+ /// Gets the invoker func.
+ /// </summary>
+ private static Func<Guid, object, bool> GetInvoker(object pred)
+ {
+ var func = DelegateTypeDescriptor.GetMessageFilter(pred.GetType());
+
+ return (id, msg) => func(pred, id, msg);
+ }
+
+ /** <inheritdoc /> */
+ public void WritePortable(IPortableWriter writer)
+ {
+ var writer0 = (PortableWriterImpl)writer.RawWriter();
+
+ writer0.DetachNext();
+ PortableUtils.WritePortableOrSerializable(writer0, Filter);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MessageFilterHolder"/> class.
+ /// </summary>
+ /// <param name="reader">The reader.</param>
+ public MessageFilterHolder(IPortableReader reader)
+ {
+ var reader0 = (PortableReaderImpl)reader.RawReader();
+
+ _filter = PortableUtils.ReadPortableOrSerializable<object>(reader0);
+
+ _invoker = GetInvoker(_filter);
+
+ _ignite = reader0.Marshaller.Ignite;
+
+ ResourceProcessor.Inject(_filter, _ignite);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/Messaging.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/Messaging.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/Messaging.cs
new file mode 100644
index 0000000..e8c4b4b
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/Messaging.cs
@@ -0,0 +1,262 @@
+/*
+ * 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.Messaging
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl.Collections;
+ using Apache.Ignite.Core.Impl.Common;
+ using Apache.Ignite.Core.Impl.Portable;
+ using Apache.Ignite.Core.Impl.Resource;
+ using Apache.Ignite.Core.Impl.Unmanaged;
+ using Apache.Ignite.Core.Messaging;
+ using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils;
+
+ /// <summary>
+ /// Messaging functionality.
+ /// </summary>
+ internal class Messaging : PlatformTarget, IMessaging
+ {
+ /// <summary>
+ /// Opcodes.
+ /// </summary>
+ private enum Op
+ {
+ LocalListen = 1,
+ RemoteListen = 2,
+ Send = 3,
+ SendMulti = 4,
+ SendOrdered = 5,
+ StopLocalListen = 6,
+ StopRemoteListen = 7
+ }
+
+ /** Map from user (func+topic) -> id, needed for unsubscription. */
+ private readonly MultiValueDictionary<KeyValuePair<object, object>, long> _funcMap =
+ new MultiValueDictionary<KeyValuePair<object, object>, long>();
+
+ /** Grid */
+ private readonly Ignite _ignite;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Messaging" /> class.
+ /// </summary>
+ /// <param name="target">Target.</param>
+ /// <param name="marsh">Marshaller.</param>
+ /// <param name="prj">Cluster group.</param>
+ public Messaging(IUnmanagedTarget target, PortableMarshaller marsh, IClusterGroup prj)
+ : base(target, marsh)
+ {
+ Debug.Assert(prj != null);
+
+ ClusterGroup = prj;
+
+ _ignite = (Ignite) prj.Ignite;
+ }
+
+ /** <inheritdoc /> */
+ public IClusterGroup ClusterGroup { get; private set; }
+
+ /** <inheritdoc /> */
+ public void Send(object message, object topic = null)
+ {
+ IgniteArgumentCheck.NotNull(message, "message");
+
+ DoOutOp((int) Op.Send, topic, message);
+ }
+
+ /** <inheritdoc /> */
+ public void Send(IEnumerable messages, object topic = null)
+ {
+ IgniteArgumentCheck.NotNull(messages, "messages");
+
+ DoOutOp((int) Op.SendMulti, writer =>
+ {
+ writer.Write(topic);
+
+ WriteEnumerable(writer, messages.OfType<object>());
+ });
+ }
+
+ /** <inheritdoc /> */
+ public void SendOrdered(object message, object topic = null, TimeSpan? timeout = null)
+ {
+ IgniteArgumentCheck.NotNull(message, "message");
+
+ DoOutOp((int) Op.SendOrdered, writer =>
+ {
+ writer.Write(topic);
+ writer.Write(message);
+
+ writer.WriteLong((long)(timeout == null ? 0 : timeout.Value.TotalMilliseconds));
+ });
+ }
+
+ /** <inheritdoc /> */
+ public void LocalListen<T>(IMessageFilter<T> filter, object topic = null)
+ {
+ IgniteArgumentCheck.NotNull(filter, "filter");
+
+ ResourceProcessor.Inject(filter, _ignite);
+
+ lock (_funcMap)
+ {
+ var key = GetKey(filter, topic);
+
+ MessageFilterHolder filter0 = MessageFilterHolder.CreateLocal(_ignite, filter);
+
+ var filterHnd = _ignite.HandleRegistry.Allocate(filter0);
+
+ filter0.DestroyAction = () =>
+ {
+ lock (_funcMap)
+ {
+ _funcMap.Remove(key, filterHnd);
+ }
+ };
+
+ try
+ {
+ DoOutOp((int) Op.LocalListen, writer =>
+ {
+ writer.WriteLong(filterHnd);
+ writer.Write(topic);
+ });
+ }
+ catch (Exception)
+ {
+ _ignite.HandleRegistry.Release(filterHnd);
+
+ throw;
+ }
+
+ _funcMap.Add(key, filterHnd);
+ }
+ }
+
+ /** <inheritdoc /> */
+ public void StopLocalListen<T>(IMessageFilter<T> filter, object topic = null)
+ {
+ IgniteArgumentCheck.NotNull(filter, "filter");
+
+ long filterHnd;
+ bool removed;
+
+ lock (_funcMap)
+ {
+ removed = _funcMap.TryRemove(GetKey(filter, topic), out filterHnd);
+ }
+
+ if (removed)
+ {
+ DoOutOp((int) Op.StopLocalListen, writer =>
+ {
+ writer.WriteLong(filterHnd);
+ writer.Write(topic);
+ });
+ }
+ }
+
+ /** <inheritdoc /> */
+ public Guid RemoteListen<T>(IMessageFilter<T> filter, object topic = null)
+ {
+ IgniteArgumentCheck.NotNull(filter, "filter");
+
+ var filter0 = MessageFilterHolder.CreateLocal(_ignite, filter);
+ var filterHnd = _ignite.HandleRegistry.AllocateSafe(filter0);
+
+ try
+ {
+ Guid id = Guid.Empty;
+
+ DoOutInOp((int) Op.RemoteListen, writer =>
+ {
+ writer.Write(filter0);
+ writer.WriteLong(filterHnd);
+ writer.Write(topic);
+ },
+ input =>
+ {
+ var id0 = Marshaller.StartUnmarshal(input).RawReader().ReadGuid();
+
+ Debug.Assert(IsAsync || id0.HasValue);
+
+ if (id0.HasValue)
+ id = id0.Value;
+ });
+
+ return id;
+ }
+ catch (Exception)
+ {
+ _ignite.HandleRegistry.Release(filterHnd);
+
+ throw;
+ }
+ }
+
+ /** <inheritdoc /> */
+ public void StopRemoteListen(Guid opId)
+ {
+ DoOutOp((int) Op.StopRemoteListen, writer =>
+ {
+ writer.WriteGuid(opId);
+ });
+ }
+
+ /** <inheritdoc /> */
+ public virtual IMessaging WithAsync()
+ {
+ return new MessagingAsync(UU.MessagingWithASync(Target), Marshaller, ClusterGroup);
+ }
+
+ /** <inheritdoc /> */
+ public virtual bool IsAsync
+ {
+ get { return false; }
+ }
+
+ /** <inheritdoc /> */
+ public virtual IFuture GetFuture()
+ {
+ throw IgniteUtils.GetAsyncModeDisabledException();
+ }
+
+ /** <inheritdoc /> */
+ public virtual IFuture<TResult> GetFuture<TResult>()
+ {
+ throw IgniteUtils.GetAsyncModeDisabledException();
+ }
+
+ /// <summary>
+ /// Gets the key for user-provided filter and topic.
+ /// </summary>
+ /// <param name="filter">Filter.</param>
+ /// <param name="topic">Topic.</param>
+ /// <returns>Compound dictionary key.</returns>
+ private static KeyValuePair<object, object> GetKey(object filter, object topic)
+ {
+ return new KeyValuePair<object, object>(filter, topic);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessagingAsync.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessagingAsync.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessagingAsync.cs
new file mode 100644
index 0000000..e899d4e
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/Messaging/MessagingAsync.cs
@@ -0,0 +1,68 @@
+/*
+ * 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.Messaging
+{
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl.Portable;
+ using Apache.Ignite.Core.Impl.Unmanaged;
+ using Apache.Ignite.Core.Messaging;
+ using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils;
+
+ /// <summary>
+ /// Async messaging implementation.
+ /// </summary>
+ internal class MessagingAsync : Messaging
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MessagingAsync" /> class.
+ /// </summary>
+ /// <param name="target">Target.</param>
+ /// <param name="marsh">Marshaller.</param>
+ /// <param name="prj">Cluster group.</param>
+ public MessagingAsync(IUnmanagedTarget target, PortableMarshaller marsh,
+ IClusterGroup prj) : base(target, marsh, prj)
+ {
+ // No-op.
+ }
+
+ /** <inheritdoc /> */
+ public override IMessaging WithAsync()
+ {
+ return this;
+ }
+
+ /** <inheritdoc /> */
+ public override bool IsAsync
+ {
+ get { return true; }
+ }
+
+ /** <inheritdoc /> */
+ public override IFuture GetFuture()
+ {
+ return GetFuture<object>();
+ }
+
+ /** <inheritdoc /> */
+ public override IFuture<T> GetFuture<T>()
+ {
+ return GetFuture<T>((futId, futTyp) => UU.TargetListenFuture(Target, futId, futTyp));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Impl/NativeMethods.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Impl/NativeMethods.cs b/modules/platform/dotnet/Apache.Ignite.Core/Impl/NativeMethods.cs
new file mode 100644
index 0000000..6e25e7e
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Impl/NativeMethods.cs
@@ -0,0 +1,47 @@
+/*
+ * 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
+{
+ using System;
+ using System.Runtime.InteropServices;
+
+ /// <summary>
+ /// Native methods.
+ /// </summary>
+ internal static class NativeMethods
+ {
+ /// <summary>
+ /// Load DLL with WinAPI.
+ /// </summary>
+ /// <param name="path">Path to dll.</param>
+ /// <returns></returns>
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+ ThrowOnUnmappableChar = true)]
+ internal static extern IntPtr LoadLibrary(string path);
+
+ /// <summary>
+ /// Get procedure address with WinAPI.
+ /// </summary>
+ /// <param name="ptr">DLL pointer.</param>
+ /// <param name="name">Procedure name.</param>
+ /// <returns>Procedure address.</returns>
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+ ThrowOnUnmappableChar = true)]
+ internal static extern IntPtr GetProcAddress(IntPtr ptr, string name);
+ }
+}
\ No newline at end of file