Decompiled source of Agrona v1.40.0

BepInEx/core/Agrona/netstandard2.0/Adaptive.Agrona.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using Adaptive.Agrona.Collections;
using Adaptive.Agrona.Concurrent;
using Adaptive.Agrona.Concurrent.Status;
using Adaptive.Agrona.Util;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Adaptive Financial Consulting Ltd.")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2023")]
[assembly: AssemblyDescription("Agrona provides a library of data structures and utility methods that are a common need when building high-performance applications in .NET")]
[assembly: AssemblyFileVersion("1.40.0.0")]
[assembly: AssemblyInformationalVersion("1.40.0")]
[assembly: AssemblyProduct("Agrona libraries initially included in Aeron Client")]
[assembly: AssemblyTitle("Adaptive.Agrona")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.40.0.0")]
[module: UnverifiableCode]
namespace Adaptive.Agrona
{
	public class BitUtil
	{
		public const int SIZE_OF_BYTE = 1;

		public const int SIZE_OF_BOOLEAN = 1;

		public const int SIZE_OF_CHAR = 2;

		public const int SIZE_OF_SHORT = 2;

		public const int SIZE_OF_INT = 4;

		public const int SIZE_OF_FLOAT = 4;

		public const int SIZE_OF_LONG = 8;

		public const int SIZE_OF_DOUBLE = 8;

		public const int CACHE_LINE_LENGTH = 64;

		private static readonly byte[] HexDigitTable;

		private static readonly byte[] FromHexDigitTable;

		private const int LastDigitMask = 1;

		private static readonly Encoding Utf8Encoding;

		static BitUtil()
		{
			HexDigitTable = new byte[16]
			{
				48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
				97, 98, 99, 100, 101, 102
			};
			Utf8Encoding = Encoding.UTF8;
			FromHexDigitTable = new byte[128];
			FromHexDigitTable[48] = 0;
			FromHexDigitTable[49] = 1;
			FromHexDigitTable[50] = 2;
			FromHexDigitTable[51] = 3;
			FromHexDigitTable[52] = 4;
			FromHexDigitTable[53] = 5;
			FromHexDigitTable[54] = 6;
			FromHexDigitTable[55] = 7;
			FromHexDigitTable[56] = 8;
			FromHexDigitTable[57] = 9;
			FromHexDigitTable[97] = 10;
			FromHexDigitTable[65] = 10;
			FromHexDigitTable[98] = 11;
			FromHexDigitTable[66] = 11;
			FromHexDigitTable[99] = 12;
			FromHexDigitTable[67] = 12;
			FromHexDigitTable[100] = 13;
			FromHexDigitTable[68] = 13;
			FromHexDigitTable[101] = 14;
			FromHexDigitTable[69] = 14;
			FromHexDigitTable[102] = 15;
			FromHexDigitTable[70] = 15;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FindNextPositivePowerOfTwo(int value)
		{
			return 1 << 32 - IntUtil.NumberOfLeadingZeros(value - 1);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int Align(int value, int alignment)
		{
			return (value + (alignment - 1)) & ~(alignment - 1);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte[] FromHexByteArray(byte[] buffer)
		{
			byte[] array = new byte[buffer.Length >> 1];
			for (int i = 0; i < buffer.Length; i += 2)
			{
				array[i >> 1] = (byte)((FromHexDigitTable[buffer[i]] << 4) | FromHexDigitTable[buffer[i + 1]]);
			}
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte[] ToHexByteArray(byte[] buffer)
		{
			return ToHexByteArray(buffer, 0, buffer.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte[] ToHexByteArray(byte[] buffer, int offset, int length)
		{
			byte[] array = new byte[length << 1];
			for (int i = 0; i < length << 1; i += 2)
			{
				byte b = buffer[offset + (i >> 1)];
				array[i] = HexDigitTable[(b >> 4) & 0xF];
				array[i + 1] = HexDigitTable[b & 0xF];
			}
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte[] FromHex(string value)
		{
			return FromHexByteArray(Utf8Encoding.GetBytes(value));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string ToHex(byte[] buffer, int offset, int length)
		{
			byte[] array = ToHexByteArray(buffer, offset, length);
			return Utf8Encoding.GetString(array, 0, array.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string ToHex(byte[] buffer)
		{
			byte[] array = ToHexByteArray(buffer);
			return Utf8Encoding.GetString(array, 0, array.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsEven(int value)
		{
			return (value & 1) == 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsPowerOfTwo(int value)
		{
			if (value > 0)
			{
				return (value & (~value + 1)) == value;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int Next(int current, int max)
		{
			int num = current + 1;
			if (num == max)
			{
				num = 0;
			}
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int Previous(int current, int max)
		{
			if (current == 0)
			{
				return max - 1;
			}
			return current - 1;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsAligned(long address, int alignment)
		{
			if (!IsPowerOfTwo(alignment))
			{
				ThrowHelper.ThrowArgumentException("Alignment must be a power of 2: alignment=" + alignment);
			}
			return (address & (alignment - 1)) == 0;
		}
	}
	public class BufferUtil
	{
		public static readonly byte[] NullBytes = Encoding.UTF8.GetBytes("null");

		public static void BoundsCheck(byte[] buffer, long index, int length)
		{
			int num = buffer.Length;
			long num2 = index + length;
			if (index < 0 || num2 > num)
			{
				ThrowHelper.ThrowIndexOutOfRangeException($"index={index:D}, length={length:D}, capacity={num:D}");
			}
		}

		public static ByteBuffer AllocateDirectAligned(int capacity, int alignment)
		{
			return new ByteBuffer(capacity, alignment);
		}

		public static ByteBuffer AllocateDirect(int capacity)
		{
			return new ByteBuffer(capacity, 8);
		}
	}
	public class ByteBuffer : IDisposable
	{
		private GCHandle _bufferHandle;

		private bool _disposed;

		public IntPtr BufferPointer { get; }

		public int Capacity { get; }

		public ByteBuffer(int capacity, int byteAlignment)
		{
			Capacity = capacity;
			byte[] value = new byte[capacity + byteAlignment];
			_bufferHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
			long num = _bufferHandle.AddrOfPinnedObject().ToInt64();
			num = (num + byteAlignment - 1) & ~(byteAlignment - 1);
			BufferPointer = new IntPtr(num);
		}

		~ByteBuffer()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		private void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				_bufferHandle.Free();
				_disposed = true;
			}
		}
	}
	public enum ByteOrder
	{
		BigEndian,
		LittleEndian
	}
	public struct CacheLinePadding
	{
		private long p1;

		private long p2;

		private long p3;

		private long p4;

		private long p5;

		private long p6;

		private long p7;

		private long p8;

		private long p9;

		private long p10;

		private long p11;

		private long p12;

		private long p13;

		private long p14;

		private long p15;

		public override string ToString()
		{
			return string.Format("{0}: {1}, {2}: {3}, {4}: {5}, {6}: {7}, {8}: {9}, {10}: {11}, {12}: {13}, {14}: {15}, {16}: {17}, {18}: {19}, {20}: {21}, {22}: {23}, {24}: {25}, {26}: {27}, {28}: {29}", "p1", p1, "p2", p2, "p3", p3, "p4", p4, "p5", p5, "p6", p6, "p7", p7, "p8", p8, "p9", p9, "p10", p10, "p11", p11, "p12", p12, "p13", p13, "p14", p14, "p15", p15);
		}
	}
	public static class CloseHelper
	{
		public static void QuietDispose(IDisposable disposable)
		{
			try
			{
				disposable?.Dispose();
			}
			catch
			{
			}
		}

		public static void QuietDispose(Action disposable)
		{
			try
			{
				disposable?.Invoke();
			}
			catch
			{
			}
		}

		public static void Dispose(ErrorHandler errorHandler, IDisposable disposable)
		{
			try
			{
				disposable?.Dispose();
			}
			catch (Exception exception)
			{
				errorHandler(exception);
			}
		}

		public static void Dispose(IErrorHandler errorHandler, IDisposable disposable)
		{
			try
			{
				disposable?.Dispose();
			}
			catch (Exception exception)
			{
				errorHandler.OnError(exception);
			}
		}

		public static void Dispose(ErrorHandler errorHandler, Action disposable)
		{
			try
			{
				disposable?.Invoke();
			}
			catch (Exception exception)
			{
				errorHandler(exception);
			}
		}

		public static void CloseAll(IEnumerable<IDisposable> disposables)
		{
			if (disposables == null || !disposables.Any())
			{
				return;
			}
			Exception ex = null;
			foreach (IDisposable disposable in disposables)
			{
				if (disposable != null)
				{
					try
					{
						disposable.Dispose();
					}
					catch (Exception ex2)
					{
						ex = ((ex != null) ? new Exception(null, ex2) : ex2);
					}
				}
			}
			if (ex == null)
			{
				return;
			}
			throw ex;
		}
	}
	public interface DelegatingErrorHandler
	{
		void Next(ErrorHandler errorHandler);

		void OnError(Exception exception);
	}
	public static class EndianessConverter
	{
		private static readonly ByteOrder NativeByteOrder = (BitConverter.IsLittleEndian ? ByteOrder.LittleEndian : ByteOrder.BigEndian);

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short ApplyInt16(ByteOrder byteOrder, short value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			return (short)((long)(((ulong)value & 0xFFuL) << 8) | ((long)((ulong)value & 0xFF00uL) >> 8));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ushort ApplyUint16(ByteOrder byteOrder, ushort value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			return (ushort)((uint)((value & 0xFF) << 8) | ((uint)(value & 0xFF00) >> 8));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int ApplyInt32(ByteOrder byteOrder, int value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			return (int)((long)((((ulong)value & 0xFFuL) << 24) | (((ulong)value & 0xFF00uL) << 8)) | ((long)((ulong)value & 0xFF0000uL) >> 8) | ((value & 0xFF000000u) >> 24));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint ApplyUint32(ByteOrder byteOrder, uint value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0xFF0000) >> 8) | ((value & 0xFF000000u) >> 24);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong ApplyUint64(ByteOrder byteOrder, ulong value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			return ((value & 0xFF) << 56) | ((value & 0xFF00) << 40) | ((value & 0xFF0000) << 24) | ((value & 0xFF000000u) << 8) | ((value & 0xFF00000000L) >> 8) | ((value & 0xFF0000000000L) >> 24) | ((value & 0xFF000000000000L) >> 40) | ((value & 0xFF00000000000000uL) >> 56);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long ApplyInt64(ByteOrder byteOrder, long value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			return IPAddress.HostToNetworkOrder(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static double ApplyDouble(ByteOrder byteOrder, double value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			return BitConverter.Int64BitsToDouble(IPAddress.HostToNetworkOrder(BitConverter.DoubleToInt64Bits(value)));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static float ApplyFloat(ByteOrder byteOrder, float value)
		{
			if (byteOrder == NativeByteOrder)
			{
				return value;
			}
			int value2 = *(int*)(&value);
			int num = ApplyInt32(byteOrder, value2);
			return *(float*)(&num);
		}
	}
	public delegate void ErrorHandler(Exception exception);
	public class ExpandableArrayBuffer : IMutableDirectBuffer, IDirectBuffer, IComparable<IDirectBuffer>
	{
		public static readonly int MAX_ARRAY_LENGTH = 2147483639;

		public const int INITIAL_CAPACITY = 128;

		private byte[] _byteArray;

		private GCHandle _pinnedGcHandle;

		private unsafe byte* _pBuffer;

		public unsafe IntPtr BufferPointer => new IntPtr(_pBuffer);

		public byte[] ByteArray => _byteArray;

		public ByteBuffer ByteBuffer => null;

		public int Capacity => _byteArray.Length;

		public bool IsExpandable => true;

		public ExpandableArrayBuffer()
			: this(128)
		{
		}

		public ExpandableArrayBuffer(int initialCapacity)
		{
			AllocateAndPinArray(initialCapacity);
		}

		private unsafe void AllocateAndPinArray(int capacity)
		{
			_byteArray = new byte[capacity];
			_pinnedGcHandle = GCHandle.Alloc(_byteArray, GCHandleType.Pinned);
			_pBuffer = (byte*)_pinnedGcHandle.AddrOfPinnedObject().ToPointer();
		}

		~ExpandableArrayBuffer()
		{
			if (_pinnedGcHandle.IsAllocated)
			{
				_pinnedGcHandle.Free();
			}
		}

		public void Wrap(byte[] buffer)
		{
			throw new NotSupportedException();
		}

		public void Wrap(byte[] buffer, int offset, int length)
		{
			throw new NotSupportedException();
		}

		public void Wrap(IDirectBuffer buffer)
		{
			throw new NotSupportedException();
		}

		public void Wrap(IDirectBuffer buffer, int offset, int length)
		{
			throw new NotSupportedException();
		}

		public void Wrap(IntPtr pointer, int length)
		{
			throw new NotSupportedException();
		}

		public void Wrap(IntPtr pointer, int offset, int length)
		{
			throw new NotSupportedException();
		}

		public int CompareTo(IDirectBuffer other)
		{
			throw new NotSupportedException();
		}

		public void CheckLimit(int limit)
		{
			EnsureCapacity(limit, 1);
		}

		public unsafe long GetLong(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 8);
			long value = *(long*)(_pBuffer + index);
			return EndianessConverter.ApplyInt64(byteOrder, value);
		}

		public unsafe long GetLong(int index)
		{
			BoundsCheck0(index, 8);
			return *(long*)(_pBuffer + index);
		}

		public unsafe int GetInt(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 4);
			int value = *(int*)(_pBuffer + index);
			return EndianessConverter.ApplyInt32(byteOrder, value);
		}

		public unsafe int GetInt(int index)
		{
			BoundsCheck0(index, 4);
			return *(int*)(_pBuffer + index);
		}

		public unsafe double GetDouble(int index)
		{
			BoundsCheck0(index, 8);
			return *(double*)(_pBuffer + index);
		}

		public unsafe float GetFloat(int index)
		{
			BoundsCheck0(index, 4);
			return *(float*)(_pBuffer + index);
		}

		public unsafe short GetShort(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 2);
			short value = *(short*)(_pBuffer + index);
			return EndianessConverter.ApplyInt16(byteOrder, value);
		}

		public unsafe short GetShort(int index)
		{
			BoundsCheck0(index, 2);
			return *(short*)(_pBuffer + index);
		}

		public unsafe char GetChar(int index)
		{
			BoundsCheck0(index, 2);
			return *(char*)(_pBuffer + index);
		}

		public byte GetByte(int index)
		{
			return _byteArray[index];
		}

		public void GetBytes(int index, byte[] dst)
		{
			Array.Copy(_byteArray, index, dst, 0, dst.Length);
		}

		public void GetBytes(int index, byte[] dst, int offset, int length)
		{
			Array.Copy(_byteArray, index, dst, offset, length);
		}

		public void GetBytes(int index, IMutableDirectBuffer dstBuffer, int dstIndex, int length)
		{
			dstBuffer.PutBytes(dstIndex, _byteArray, index, length);
		}

		public string GetStringUtf8(int index)
		{
			int @int = GetInt(index);
			return GetStringUtf8(index, @int);
		}

		public string GetStringAscii(int index)
		{
			int @int = GetInt(index);
			return GetStringAscii(index, @int);
		}

		public int GetStringAscii(int index, StringBuilder appendable)
		{
			int @int = GetInt(index);
			return GetStringAscii(index, @int, appendable);
		}

		public unsafe int GetStringAscii(int index, int length, StringBuilder appendable)
		{
			int i = index + 4;
			for (int num = index + 4 + length; i < num; i++)
			{
				char c = *(char*)(_pBuffer + index);
				appendable.Append((c > '\u007f') ? '?' : c);
			}
			return length;
		}

		public string GetStringUtf8(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index + 4, array);
			return Encoding.UTF8.GetString(array);
		}

		public string GetStringAscii(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index + 4, array);
			return Encoding.ASCII.GetString(array);
		}

		public string GetStringWithoutLengthUtf8(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index, array);
			return Encoding.UTF8.GetString(array);
		}

		public string GetStringWithoutLengthAscii(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index, array);
			return Encoding.ASCII.GetString(array);
		}

		public void BoundsCheck(int index, int length)
		{
			BoundsCheck0(index, length);
		}

		public unsafe void SetMemory(int index, int length, byte value)
		{
			EnsureCapacity(index, length);
			Unsafe.InitBlock(_pBuffer + index, value, (uint)length);
		}

		public unsafe void PutLong(int index, long value, ByteOrder byteOrder)
		{
			EnsureCapacity(index, 8);
			value = EndianessConverter.ApplyInt64(byteOrder, value);
			*(long*)(_pBuffer + index) = value;
		}

		public unsafe void PutLong(int index, long value)
		{
			EnsureCapacity(index, 8);
			BoundsCheck0(index, 8);
			*(long*)(_pBuffer + index) = value;
		}

		public unsafe void PutInt(int index, int value, ByteOrder byteOrder)
		{
			EnsureCapacity(index, 4);
			value = EndianessConverter.ApplyInt32(byteOrder, value);
			*(int*)(_pBuffer + index) = value;
		}

		public unsafe void PutInt(int index, int value)
		{
			EnsureCapacity(index, 4);
			*(int*)(_pBuffer + index) = value;
		}

		public unsafe void PutDouble(int index, double value)
		{
			EnsureCapacity(index, 8);
			*(double*)(_pBuffer + index) = value;
		}

		public unsafe void PutFloat(int index, float value)
		{
			EnsureCapacity(index, 4);
			*(float*)(_pBuffer + index) = value;
		}

		public unsafe void PutShort(int index, short value, ByteOrder byteOrder)
		{
			EnsureCapacity(index, 2);
			value = EndianessConverter.ApplyInt16(byteOrder, value);
			*(short*)(_pBuffer + index) = value;
		}

		public unsafe void PutShort(int index, short value)
		{
			EnsureCapacity(index, 2);
			*(short*)(_pBuffer + index) = value;
		}

		public unsafe void PutChar(int index, char value)
		{
			EnsureCapacity(index, 2);
			*(char*)(_pBuffer + index) = value;
		}

		public unsafe void PutByte(int index, byte value)
		{
			EnsureCapacity(index, 1);
			_pBuffer[index] = value;
		}

		public void PutBytes(int index, byte[] src)
		{
			PutBytes(index, src, 0, src.Length);
		}

		public void PutBytes(int index, byte[] src, int offset, int length)
		{
			EnsureCapacity(index, length);
			Array.Copy(src, offset, _byteArray, index, length);
		}

		public unsafe void PutBytes(int index, IDirectBuffer srcBuffer, int srcIndex, int length)
		{
			if (length != 0)
			{
				EnsureCapacity(index, length);
				srcBuffer.BoundsCheck(srcIndex, length);
				byte* destination = _pBuffer + index;
				byte* source = (byte*)srcBuffer.BufferPointer.ToPointer() + srcIndex;
				ByteUtil.MemoryCopy(destination, source, (uint)length);
			}
		}

		public int PutStringUtf8(int index, string value)
		{
			return PutStringUtf8(index, value, int.MaxValue);
		}

		public int PutStringAscii(int index, string value)
		{
			return PutStringAscii(index, value, int.MaxValue);
		}

		public int PutStringAscii(int index, string value, int maxEncodedSize)
		{
			byte[] array = ((value == null) ? BufferUtil.NullBytes : Encoding.ASCII.GetBytes(value));
			if (array.Length > maxEncodedSize)
			{
				ThrowHelper.ThrowArgumentException("Encoded string larger than maximum size: " + maxEncodedSize);
			}
			EnsureCapacity(index, 4 + array.Length);
			PutInt(index, array.Length);
			PutBytes(index + 4, array);
			return 4 + array.Length;
		}

		public unsafe int PutStringWithoutLengthAscii(int index, string value)
		{
			int num = value?.Length ?? 0;
			EnsureCapacity(index, num);
			for (int i = 0; i < num; i++)
			{
				char c = value[i];
				if (c > '\u007f')
				{
					c = '?';
				}
				*(char*)(_pBuffer + index + i) = c;
			}
			return num;
		}

		public unsafe int PutStringWithoutLengthAscii(int index, string value, int valueOffset, int length)
		{
			int num = ((value != null) ? Math.Min(value.Length - valueOffset, length) : 0);
			EnsureCapacity(index, num);
			for (int i = 0; i < num; i++)
			{
				char c = value[valueOffset + i];
				if (c > '\u007f')
				{
					c = '?';
				}
				*(char*)(_pBuffer + index + i) = c;
			}
			return num;
		}

		public int PutStringUtf8(int index, string value, int maxEncodedSize)
		{
			byte[] array = ((value == null) ? BufferUtil.NullBytes : Encoding.UTF8.GetBytes(value));
			if (array.Length > maxEncodedSize)
			{
				ThrowHelper.ThrowArgumentException("Encoded string larger than maximum size: " + maxEncodedSize);
			}
			EnsureCapacity(index, 4 + array.Length);
			PutInt(index, array.Length);
			PutBytes(index + 4, array);
			return 4 + array.Length;
		}

		public int PutStringWithoutLengthUtf8(int index, string value)
		{
			byte[] array = ((value == null) ? BufferUtil.NullBytes : Encoding.UTF8.GetBytes(value));
			EnsureCapacity(index, array.Length);
			PutBytes(index, array);
			return array.Length;
		}

		private void EnsureCapacity(int index, int length)
		{
			if (index < 0 || length < 0)
			{
				throw new IndexOutOfRangeException("negative value: index=" + index + " length=" + length);
			}
			long num = (long)index + (long)length;
			int num2 = _byteArray.Length;
			if (num > num2)
			{
				if (num > MAX_ARRAY_LENGTH)
				{
					string[] obj = new string[6]
					{
						"index=",
						index.ToString(),
						" length=",
						length.ToString(),
						" maxCapacity=",
						null
					};
					int mAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH;
					obj[5] = mAX_ARRAY_LENGTH.ToString();
					throw new IndexOutOfRangeException(string.Concat(obj));
				}
				int capacity = CalculateExpansion(num2, num);
				byte[] byteArray = _byteArray;
				_pinnedGcHandle.Free();
				AllocateAndPinArray(capacity);
				Array.Copy(byteArray, _byteArray, byteArray.Length);
			}
		}

		private int CalculateExpansion(int currentLength, long requiredLength)
		{
			long num = Math.Max(currentLength, 128);
			while (num < requiredLength)
			{
				num += num >> 1;
				if (num > MAX_ARRAY_LENGTH)
				{
					num = MAX_ARRAY_LENGTH;
				}
			}
			return (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void BoundsCheck0(int index, int length)
		{
			int num = _byteArray.Length;
			long num2 = (long)index + (long)length;
			if (index < 0 || length < 0 || num2 > num)
			{
				ThrowHelper.ThrowIndexOutOfRangeException($"index={index:D}, length={length:D}, capacity={Capacity:D}");
			}
		}
	}
	public interface IDirectBuffer : IComparable<IDirectBuffer>
	{
		IntPtr BufferPointer { get; }

		byte[] ByteArray { get; }

		ByteBuffer ByteBuffer { get; }

		int Capacity { get; }

		void Wrap(byte[] buffer);

		void Wrap(byte[] buffer, int offset, int length);

		void Wrap(IDirectBuffer buffer);

		void Wrap(IDirectBuffer buffer, int offset, int length);

		void Wrap(IntPtr pointer, int length);

		void Wrap(IntPtr pointer, int offset, int length);

		void CheckLimit(int limit);

		long GetLong(int index, ByteOrder byteOrder);

		long GetLong(int index);

		int GetInt(int index, ByteOrder byteOrder);

		int GetInt(int index);

		double GetDouble(int index);

		float GetFloat(int index);

		short GetShort(int index, ByteOrder byteOrder);

		short GetShort(int index);

		char GetChar(int index);

		byte GetByte(int index);

		void GetBytes(int index, byte[] dst);

		void GetBytes(int index, byte[] dst, int offset, int length);

		void GetBytes(int index, IMutableDirectBuffer dstBuffer, int dstIndex, int length);

		string GetStringUtf8(int index);

		string GetStringAscii(int index);

		int GetStringAscii(int index, StringBuilder appendable);

		int GetStringAscii(int index, int length, StringBuilder appendable);

		string GetStringUtf8(int index, int length);

		string GetStringAscii(int index, int length);

		string GetStringWithoutLengthUtf8(int index, int length);

		string GetStringWithoutLengthAscii(int index, int length);

		void BoundsCheck(int index, int length);
	}
	public interface IErrorHandler
	{
		void OnError(Exception exception);
	}
	public interface IManagedResource
	{
		void TimeOfLastStateChange(long time);

		long TimeOfLastStateChange();

		void Delete();
	}
	public interface IMutableDirectBuffer : IDirectBuffer, IComparable<IDirectBuffer>
	{
		bool IsExpandable { get; }

		void SetMemory(int index, int length, byte value);

		void PutLong(int index, long value, ByteOrder byteOrder);

		void PutLong(int index, long value);

		void PutInt(int index, int value, ByteOrder byteOrder);

		void PutInt(int index, int value);

		void PutDouble(int index, double value);

		void PutFloat(int index, float value);

		void PutShort(int index, short value, ByteOrder byteOrder);

		void PutShort(int index, short value);

		void PutChar(int index, char value);

		void PutByte(int index, byte value);

		void PutBytes(int index, byte[] src);

		void PutBytes(int index, byte[] src, int offset, int length);

		void PutBytes(int index, IDirectBuffer srcBuffer, int srcIndex, int length);

		int PutStringUtf8(int index, string value);

		int PutStringAscii(int index, string value);

		int PutStringWithoutLengthAscii(int index, string value);

		int PutStringWithoutLengthAscii(int index, string value, int valueOffset, int length);

		int PutStringUtf8(int index, string value, int maxEncodedSize);

		int PutStringWithoutLengthUtf8(int index, string value);
	}
	public enum MapMode
	{
		ReadOnly,
		ReadWrite
	}
	public class IoUtil
	{
		public static MappedByteBuffer MapExistingFile(string path, MapMode mapMode)
		{
			return new MappedByteBuffer(OpenMemoryMappedFile(path));
		}

		public static MappedByteBuffer MapExistingFile(FileInfo path, long offset, long length)
		{
			return new MappedByteBuffer(OpenMemoryMappedFile(path.FullName), offset, length);
		}

		public static MappedByteBuffer MapNewFile(FileInfo cncFile, long length, bool fillWithZeros = true)
		{
			FileAccess access = FileAccess.ReadWrite;
			FileShare share = FileShare.ReadWrite | FileShare.Delete;
			MemoryMappedFileAccess access2 = MemoryMappedFileAccess.ReadWrite;
			MappedByteBuffer mappedByteBuffer = new MappedByteBuffer(MemoryMappedFile.CreateFromFile(new FileStream(cncFile.FullName, FileMode.CreateNew, access, share), null, length, access2, HandleInheritability.None, leaveOpen: false), 0L, length);
			if (fillWithZeros)
			{
				mappedByteBuffer.FillWithZeros();
			}
			return mappedByteBuffer;
		}

		public static MappedByteBuffer MapNewOrExistingFile(FileInfo cncFile, long length)
		{
			FileAccess access = FileAccess.ReadWrite;
			FileShare share = FileShare.ReadWrite | FileShare.Delete;
			MemoryMappedFileAccess access2 = MemoryMappedFileAccess.ReadWrite;
			return new MappedByteBuffer(MemoryMappedFile.CreateFromFile(new FileStream(cncFile.FullName, FileMode.OpenOrCreate, access, share), null, length, access2, HandleInheritability.None, leaveOpen: false), 0L, length);
		}

		public static MemoryMappedFile OpenMemoryMappedFile(string path)
		{
			CheckFileExists(path);
			FileAccess access = FileAccess.ReadWrite;
			FileShare share = FileShare.ReadWrite | FileShare.Delete;
			return OpenMemoryMappedFile(new FileStream(path, FileMode.Open, access, share));
		}

		private static MemoryMappedFile OpenMemoryMappedFile(FileStream f)
		{
			MemoryMappedFileAccess access = MemoryMappedFileAccess.ReadWrite;
			return MemoryMappedFile.CreateFromFile(f, null, 0L, access, HandleInheritability.None, leaveOpen: false);
		}

		public static MappedByteBuffer MapExistingFile(FileStream fileStream)
		{
			return new MappedByteBuffer(OpenMemoryMappedFile(fileStream));
		}

		public static MappedByteBuffer MapExistingFile(FileInfo location, string descriptionLabel)
		{
			CheckFileExists(location, descriptionLabel);
			return new MappedByteBuffer(OpenMemoryMappedFile(location.FullName));
		}

		public static void Unmap(MappedByteBuffer wrapper)
		{
			wrapper?.Dispose();
		}

		public static void CheckFileExists(FileInfo file, string name)
		{
			if (!file.Exists)
			{
				throw new InvalidOperationException("Missing file for " + name + " : " + file.FullName);
			}
		}

		public static void CheckFileExists(string path)
		{
			if (!File.Exists(path))
			{
				throw new InvalidOperationException("Missing file " + path);
			}
		}

		public static void Delete(DirectoryInfo directory, bool b)
		{
			if (directory.Exists)
			{
				directory.Delete(recursive: true);
			}
		}

		public static void EnsureDirectoryExists(DirectoryInfo directory, string descriptionLabel)
		{
			if (!directory.Exists)
			{
				directory.Create();
				if (!directory.Exists)
				{
					throw new ArgumentException("could not create " + descriptionLabel + " directory: " + directory.FullName);
				}
			}
		}
	}
	public class MarkFile : IDisposable
	{
		private readonly int versionFieldOffset;

		private readonly int timestampFieldOffset;

		private readonly DirectoryInfo parentDir;

		private readonly FileInfo markFile;

		private readonly MappedByteBuffer mappedBuffer;

		private readonly UnsafeBuffer buffer;

		private volatile bool isClosed;

		public MarkFile(DirectoryInfo directory, string filename, bool warnIfDirectoryExists, bool dirDeleteOnStart, int versionFieldOffset, int timestampFieldOffset, int totalFileLength, long timeoutMs, IEpochClock epochClock, Action<int> versionCheck, Action<string> logger)
		{
			ValidateOffsets(versionFieldOffset, timestampFieldOffset);
			EnsureDirectoryExists(directory, filename, warnIfDirectoryExists, dirDeleteOnStart, versionFieldOffset, timestampFieldOffset, timeoutMs, epochClock, versionCheck, logger);
			parentDir = directory;
			markFile = new FileInfo(Path.Combine(directory.Name, filename));
			mappedBuffer = MapNewFile(markFile, totalFileLength);
			buffer = new UnsafeBuffer(mappedBuffer.Pointer, totalFileLength);
			this.versionFieldOffset = versionFieldOffset;
			this.timestampFieldOffset = timestampFieldOffset;
		}

		public MarkFile(FileInfo markFile, bool shouldPreExist, int versionFieldOffset, int timestampFieldOffset, int totalFileLength, long timeoutMs, IEpochClock epochClock, Action<int> versionCheck, Action<string> logger)
		{
			ValidateOffsets(versionFieldOffset, timestampFieldOffset);
			parentDir = markFile.Directory;
			this.markFile = markFile;
			mappedBuffer = mapNewOrExistingMarkFile(markFile, shouldPreExist, versionFieldOffset, timestampFieldOffset, totalFileLength, timeoutMs, epochClock, versionCheck, logger);
			buffer = new UnsafeBuffer(mappedBuffer.Pointer, totalFileLength);
			this.versionFieldOffset = versionFieldOffset;
			this.timestampFieldOffset = timestampFieldOffset;
		}

		public MarkFile(DirectoryInfo directory, string filename, int versionFieldOffset, int timestampFieldOffset, long timeoutMs, IEpochClock epochClock, Action<int> versionCheck, Action<string> logger)
		{
			ValidateOffsets(versionFieldOffset, timestampFieldOffset);
			parentDir = directory;
			markFile = new FileInfo(Path.Combine(directory.FullName, filename));
			mappedBuffer = MapExistingMarkFile(markFile, versionFieldOffset, timestampFieldOffset, timeoutMs, epochClock, versionCheck, logger);
			buffer = new UnsafeBuffer(mappedBuffer);
			this.versionFieldOffset = versionFieldOffset;
			this.timestampFieldOffset = timestampFieldOffset;
		}

		public MarkFile(MappedByteBuffer mappedBuffer, int versionFieldOffset, int timestampFieldOffset)
		{
			ValidateOffsets(versionFieldOffset, timestampFieldOffset);
			parentDir = null;
			markFile = null;
			this.mappedBuffer = mappedBuffer;
			buffer = new UnsafeBuffer(mappedBuffer);
			this.versionFieldOffset = versionFieldOffset;
			this.timestampFieldOffset = timestampFieldOffset;
		}

		public MarkFile(UnsafeBuffer buffer, int versionFieldOffset, int timestampFieldOffset)
		{
			ValidateOffsets(versionFieldOffset, timestampFieldOffset);
			parentDir = null;
			markFile = null;
			mappedBuffer = null;
			this.buffer = buffer;
			this.versionFieldOffset = versionFieldOffset;
			this.timestampFieldOffset = timestampFieldOffset;
		}

		public bool IsClosed()
		{
			return isClosed;
		}

		public void Dispose()
		{
			if (!isClosed)
			{
				if (mappedBuffer != null)
				{
					IoUtil.Unmap(mappedBuffer);
				}
				isClosed = true;
			}
		}

		public void SignalReady(int version)
		{
			buffer.PutIntOrdered(versionFieldOffset, version);
		}

		public int VersionVolatile()
		{
			return buffer.GetIntVolatile(versionFieldOffset);
		}

		public int VersionWeak()
		{
			return buffer.GetInt(versionFieldOffset);
		}

		public void TimestampOrdered(long timestamp)
		{
			buffer.PutLongOrdered(timestampFieldOffset, timestamp);
		}

		public long TimestampVolatile()
		{
			return buffer.GetLongVolatile(timestampFieldOffset);
		}

		public long TimestampWeak()
		{
			return buffer.GetLong(timestampFieldOffset);
		}

		public void DeleteDirectory(bool ignoreFailures)
		{
			IoUtil.Delete(parentDir, ignoreFailures);
		}

		public DirectoryInfo CncDirectory()
		{
			return parentDir;
		}

		public FileInfo FileName()
		{
			return markFile;
		}

		public MappedByteBuffer MappedByteBuffer()
		{
			return mappedBuffer;
		}

		public UnsafeBuffer Buffer()
		{
			return buffer;
		}

		public static void EnsureDirectoryExists(DirectoryInfo directory, string filename, bool warnIfDirectoryExists, bool dirDeleteOnStart, int versionFieldOffset, int timestampFieldOffset, long timeoutMs, IEpochClock epochClock, Action<int> versionCheck, Action<string> logger)
		{
			FileInfo cncFile = new FileInfo(Path.Combine(directory.FullName, filename));
			if (directory.Exists)
			{
				if (warnIfDirectoryExists)
				{
					logger?.Invoke("WARNING: " + directory?.ToString() + " already exists.");
				}
				if (!dirDeleteOnStart)
				{
					int num = Math.Min(versionFieldOffset, timestampFieldOffset);
					int num2 = Math.Max(versionFieldOffset, timestampFieldOffset) + 8 - num;
					MappedByteBuffer mappedByteBuffer = MapExistingFile(cncFile, logger, num, num2);
					try
					{
						if (IsActive(mappedByteBuffer, epochClock, timeoutMs, versionFieldOffset, timestampFieldOffset, versionCheck, logger))
						{
							throw new InvalidOperationException("active mark file detected");
						}
					}
					finally
					{
						IoUtil.Unmap(mappedByteBuffer);
					}
				}
				IoUtil.Delete(directory, b: false);
			}
			IoUtil.EnsureDirectoryExists(directory, directory.ToString());
		}

		public static MappedByteBuffer MapExistingMarkFile(FileInfo markFile, int versionFieldOffset, int timestampFieldOffset, long timeoutMs, IEpochClock epochClock, Action<int> versionCheck, Action<string> logger)
		{
			long num = epochClock.Time();
			while (!markFile.Exists)
			{
				if (epochClock.Time() > num + timeoutMs)
				{
					throw new InvalidOperationException("CnC file not found: " + markFile.FullName);
				}
				Sleep(16);
			}
			MappedByteBuffer result = MapExistingFile(markFile, logger);
			UnsafeBuffer unsafeBuffer = new UnsafeBuffer(result);
			int intVolatile;
			while ((intVolatile = unsafeBuffer.GetIntVolatile(versionFieldOffset)) == 0)
			{
				if (epochClock.Time() > num + timeoutMs)
				{
					throw new InvalidOperationException("CnC file is created but not initialised.");
				}
				Sleep(1);
			}
			versionCheck(intVolatile);
			while (unsafeBuffer.GetLongVolatile(timestampFieldOffset) == 0L)
			{
				if (epochClock.Time() > num + timeoutMs)
				{
					throw new InvalidOperationException("No non-0 timestamp detected.");
				}
				Sleep(1);
			}
			return result;
		}

		public static MappedByteBuffer mapNewOrExistingMarkFile(FileInfo markFile, bool shouldPreExist, int versionFieldOffset, int timestampFieldOffset, long totalFileLength, long timeoutMs, IEpochClock epochClock, Action<int> versionCheck, Action<string> logger)
		{
			MappedByteBuffer mappedByteBuffer = null;
			try
			{
				mappedByteBuffer = IoUtil.MapNewOrExistingFile(markFile, totalFileLength);
				UnsafeBuffer unsafeBuffer = new UnsafeBuffer(mappedByteBuffer);
				if (shouldPreExist)
				{
					int intVolatile = unsafeBuffer.GetIntVolatile(versionFieldOffset);
					logger?.Invoke("INFO: Mark file exists: " + markFile);
					versionCheck(intVolatile);
					long longVolatile = unsafeBuffer.GetLongVolatile(timestampFieldOffset);
					long num = epochClock.Time() - longVolatile;
					logger?.Invoke("INFO: heartbeat is (ms): " + num);
					if (num < timeoutMs)
					{
						throw new InvalidOperationException("Active mark file detected");
					}
				}
			}
			catch (Exception)
			{
				if (mappedByteBuffer != null)
				{
					IoUtil.Unmap(mappedByteBuffer);
				}
				throw;
			}
			return mappedByteBuffer;
		}

		public static MappedByteBuffer MapExistingFile(FileInfo cncFile, Action<string> logger, long offset, long length)
		{
			if (cncFile.Exists)
			{
				logger?.Invoke("INFO: Mark file exists: " + cncFile);
				return IoUtil.MapExistingFile(cncFile, offset, length);
			}
			return null;
		}

		public static MappedByteBuffer MapExistingFile(FileInfo cncFile, Action<string> logger)
		{
			if (cncFile.Exists)
			{
				logger?.Invoke("INFO: Mark file exists: " + cncFile);
				return IoUtil.MapExistingFile(cncFile, cncFile.ToString());
			}
			return null;
		}

		public static MappedByteBuffer MapNewFile(FileInfo cncFile, long length)
		{
			return IoUtil.MapNewFile(cncFile, length);
		}

		public static bool IsActive(MappedByteBuffer cncByteBuffer, IEpochClock epochClock, long timeoutMs, int versionFieldOffset, int timestampFieldOffset, Action<int> versionCheck, Action<string> logger)
		{
			if (cncByteBuffer == null)
			{
				return false;
			}
			UnsafeBuffer unsafeBuffer = new UnsafeBuffer(cncByteBuffer);
			long num = epochClock.Time();
			int intVolatile;
			while ((intVolatile = unsafeBuffer.GetIntVolatile(versionFieldOffset)) == 0)
			{
				if (epochClock.Time() > num + timeoutMs)
				{
					throw new InvalidOperationException("Mark file is created but not initialised.");
				}
				Sleep(1);
			}
			versionCheck(intVolatile);
			long longVolatile = unsafeBuffer.GetLongVolatile(timestampFieldOffset);
			long num2 = epochClock.Time() - longVolatile;
			logger?.Invoke("INFO: heartbeat is (ms): " + num2);
			return num2 <= timeoutMs;
		}

		private static void ValidateOffsets(int versionFieldOffset, int timestampFieldOffset)
		{
			if (versionFieldOffset + 4 > timestampFieldOffset)
			{
				throw new ArgumentException("version field must precede the timestamp field");
			}
		}

		internal static void Sleep(int durationMs)
		{
			try
			{
				Thread.Sleep(durationMs);
			}
			catch (ThreadInterruptedException)
			{
				Thread.CurrentThread.Interrupt();
			}
		}
	}
	public static class Objects
	{
		public static T RequireNonNull<T>(T obj, string name)
		{
			if (obj == null)
			{
				throw new NullReferenceException(name);
			}
			return obj;
		}
	}
	public class SemanticVersion
	{
		public static int Compose(int major, int minor, int patch)
		{
			if (major < 0 || major > 255)
			{
				throw new ArgumentException("major must be 0-255: " + major);
			}
			if (minor < 0 || minor > 255)
			{
				throw new ArgumentException("minor must be 0-255: " + minor);
			}
			if (patch < 0 || patch > 255)
			{
				throw new ArgumentException("patch must be 0-255: " + patch);
			}
			if (major + minor + patch == 0)
			{
				throw new ArgumentException("all parts cannot be zero");
			}
			return (major << 16) | (minor << 8) | patch;
		}

		public static int Major(int version)
		{
			return (version >> 16) & 0xFF;
		}

		public static int Minor(int version)
		{
			return (version >> 8) & 0xFF;
		}

		public static int Patch(int version)
		{
			return version & 0xFF;
		}

		public static string ToString(int version)
		{
			return Major(version) + "." + Minor(version) + "." + Patch(version);
		}
	}
	public class SystemUtil
	{
		private const long MAX_G_VALUE = 8589934591L;

		private const long MAX_M_VALUE = 8796093022207L;

		private const long MAX_K_VALUE = 9007199254739968L;

		private const long SECONDS_TO_NANOS = 1000000000L;

		private const long MILLS_TO_NANOS = 1000000L;

		private const long MICROS_TO_NANOS = 1000L;

		public static long ParseSize(string propertyName, string propertyValue)
		{
			int num = propertyValue.Length - 1;
			char c = propertyValue[num];
			if (char.IsDigit(c))
			{
				return long.Parse(propertyValue);
			}
			long num2 = Convert.ToInt64(propertyValue.Substring(0, num));
			switch (c)
			{
			case 'K':
			case 'k':
				if (num2 > 9007199254739968L)
				{
					throw new FormatException(propertyName + " would overflow long: " + propertyValue);
				}
				return num2 * 1024;
			case 'M':
			case 'm':
				if (num2 > 8796093022207L)
				{
					throw new FormatException(propertyName + " would overflow long: " + propertyValue);
				}
				return num2 * 1024 * 1024;
			case 'G':
			case 'g':
				if (num2 > 8589934591L)
				{
					throw new FormatException(propertyName + " would overflow long: " + propertyValue);
				}
				return num2 * 1024 * 1024 * 1024;
			default:
				throw new FormatException(propertyName + ": " + propertyValue + " should end with: k, m, or g.");
			}
		}

		public static long ParseDuration(string propertyName, string propertyValue)
		{
			char c = propertyValue[propertyValue.Length - 1];
			if (char.IsDigit(c))
			{
				return long.Parse(propertyValue);
			}
			if (c != 's' && c != 'S')
			{
				throw new FormatException(propertyName + ": " + propertyValue + " should end with: s, ms, us, or ns.");
			}
			char c2 = propertyValue[propertyValue.Length - 2];
			if (char.IsDigit(c2))
			{
				long num = Convert.ToInt64(propertyValue.Substring(0, propertyValue.Length - 1));
				return 1000000000 * num;
			}
			long num2 = Convert.ToInt64(propertyValue.Substring(0, propertyValue.Length - 2));
			switch (c2)
			{
			case 'N':
			case 'n':
				return num2;
			case 'U':
			case 'u':
				return 1000 * num2;
			case 'M':
			case 'm':
				return 1000000 * num2;
			default:
				throw new FormatException(propertyName + ": " + propertyValue + " should end with: s, ms, us, or ns.");
			}
		}
	}
	public class TimeUnit
	{
		public static readonly TimeUnit NANOSECONDS = new TimeUnit();

		public static readonly TimeUnit MILLIS = new TimeUnit();

		private TimeUnit()
		{
		}

		public long Convert(long sourceValue, TimeUnit destinationTimeUnit)
		{
			if (destinationTimeUnit == NANOSECONDS)
			{
				if (this == MILLIS)
				{
					return sourceValue * 1000000;
				}
				if (this == NANOSECONDS)
				{
					return sourceValue;
				}
			}
			if (destinationTimeUnit == MILLIS)
			{
				if (this == MILLIS)
				{
					return sourceValue;
				}
				if (this == NANOSECONDS)
				{
					return sourceValue / 1000000;
				}
			}
			throw new ArgumentException();
		}

		public long ToMillis(long value)
		{
			return Convert(value, MILLIS);
		}

		public long ToNanos(long value)
		{
			return Convert(value, NANOSECONDS);
		}
	}
}
namespace Adaptive.Agrona.Util
{
	public class ByteUtil
	{
		[StructLayout(LayoutKind.Sequential, Pack = 32, Size = 32)]
		internal struct CopyChunk32
		{
			private readonly long _l1;

			private readonly long _l2;

			private readonly long _l3;

			private readonly long _l4;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void MemoryCopy(byte* destination, byte* source, uint length)
		{
			int i = 0;
			for (int j = i + 32; j <= length; j += 32)
			{
				*(CopyChunk32*)(destination + i) = *(CopyChunk32*)(source + i);
				i = j;
			}
			for (int j = i + 8; j <= length; j += 8)
			{
				*(long*)(destination + i) = *(long*)(source + i);
				i = j;
			}
			for (; i < length; i++)
			{
				destination[i] = source[i];
			}
		}
	}
	public static class IntUtil
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int NumberOfTrailingZeros(int i)
		{
			if (i == 0)
			{
				return 32;
			}
			int num = 31;
			int num2 = i << 16;
			if (num2 != 0)
			{
				num -= 16;
				i = num2;
			}
			num2 = i << 8;
			if (num2 != 0)
			{
				num -= 8;
				i = num2;
			}
			num2 = i << 4;
			if (num2 != 0)
			{
				num -= 4;
				i = num2;
			}
			num2 = i << 2;
			if (num2 != 0)
			{
				num -= 2;
				i = num2;
			}
			return num - (i << 1 >>> 31);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int NumberOfLeadingZeros(int i)
		{
			if (i == 0)
			{
				return 32;
			}
			int num = 1;
			if (i >>> 16 == 0)
			{
				num += 16;
				i <<= 16;
			}
			if (i >>> 24 == 0)
			{
				num += 8;
				i <<= 8;
			}
			if (i >>> 28 == 0)
			{
				num += 4;
				i <<= 4;
			}
			if (i >>> 30 == 0)
			{
				num += 2;
				i <<= 2;
			}
			return num - (i >>> 31);
		}
	}
	public static class LockSupport
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ParkNanos(long nanos)
		{
			Thread.SpinWait((int)(15 * nanos / 1000));
		}
	}
	public class MappedByteBuffer : IDisposable
	{
		private readonly MemoryMappedFile _memoryMappedFile;

		private readonly MemoryMappedViewAccessor _view;

		private bool _disposed;

		public IntPtr Pointer { get; }

		public long Capacity { get; }

		public unsafe MappedByteBuffer(MemoryMappedFile memoryMappedFile)
		{
			_memoryMappedFile = memoryMappedFile;
			byte* pointer = null;
			_view = memoryMappedFile.CreateViewAccessor();
			_view.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
			Pointer = new IntPtr(pointer);
			Capacity = _view.Capacity;
		}

		public unsafe MappedByteBuffer(MemoryMappedFile memoryMappedFile, long offset, long length)
		{
			_memoryMappedFile = memoryMappedFile;
			byte* pointer = null;
			_view = memoryMappedFile.CreateViewAccessor(offset, length);
			_view.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
			Pointer = new IntPtr(pointer);
			Capacity = length;
		}

		public void FillWithZeros()
		{
			for (int i = 0; i < Capacity; i++)
			{
				_view.Write((long)i, (byte)0);
			}
		}

		public void Flush()
		{
			_view.Flush();
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		~MappedByteBuffer()
		{
			Dispose(disposing: false);
		}

		private void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				if (_view != null)
				{
					_view.SafeMemoryMappedViewHandle.ReleasePointer();
					_view.Dispose();
				}
				_memoryMappedFile?.Dispose();
				_disposed = true;
			}
		}
	}
	public static class NanoUtil
	{
		public static long FromSeconds(long seconds)
		{
			return seconds * 1000 * 1000 * 1000;
		}

		public static long FromMilliseconds(long milliseconds)
		{
			return milliseconds * 1000 * 1000;
		}

		public static int ToMillis(long resourceLingerDurationNs)
		{
			return (int)(resourceLingerDurationNs / 1000000);
		}
	}
	public static class ThrowHelper
	{
		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowArgumentException()
		{
			throw GetArgumentException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowArgumentException(string message)
		{
			throw GetArgumentException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowArgumentOutOfRangeException()
		{
			throw GetArgumentOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowArgumentOutOfRangeException(string argument)
		{
			throw GetArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowIndexOutOfRangeException(string message)
		{
			throw GetIndexOutOfRangeException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowInvalidOperationException()
		{
			throw GetInvalidOperationException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowInvalidCastException()
		{
			throw GetInvalidCastException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowInvalidOperationException(string message)
		{
			throw GetInvalidOperationException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowInvalidOperationException_ForVariantTypeMissmatch()
		{
			throw GetInvalidOperationException_ForVariantTypeMissmatch();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowNotImplementedException()
		{
			throw GetNotImplementedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowNotImplementedException(string message)
		{
			throw GetNotImplementedException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowNotSupportedException()
		{
			throw GetNotSupportedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowKeyNotFoundException(string message)
		{
			throw GetKeyNotFoundException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowArgumentNullException(string argument)
		{
			throw new ArgumentNullException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowObjectDisposedException(string objectName)
		{
			throw GetObjectDisposedException(objectName);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArgumentException GetArgumentException()
		{
			return new ArgumentException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArgumentException GetArgumentException(string message)
		{
			return new ArgumentException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArgumentOutOfRangeException GetArgumentOutOfRangeException()
		{
			return new ArgumentOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(string argument)
		{
			return new ArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static IndexOutOfRangeException GetIndexOutOfRangeException(string message)
		{
			return new IndexOutOfRangeException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static InvalidOperationException GetInvalidOperationException()
		{
			return new InvalidOperationException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static InvalidCastException GetInvalidCastException()
		{
			return new InvalidCastException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static InvalidOperationException GetInvalidOperationException(string message)
		{
			return new InvalidOperationException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static InvalidOperationException GetInvalidOperationException_ForVariantTypeMissmatch()
		{
			return new InvalidOperationException("Variant type doesn't match typeof(T)");
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static NotImplementedException GetNotImplementedException()
		{
			return new NotImplementedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static NotImplementedException GetNotImplementedException(string message)
		{
			return new NotImplementedException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static NotSupportedException GetNotSupportedException()
		{
			return new NotSupportedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static KeyNotFoundException GetKeyNotFoundException(string message)
		{
			return new KeyNotFoundException(message);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ObjectDisposedException GetObjectDisposedException(string objectName)
		{
			return new ObjectDisposedException(objectName);
		}
	}
	public static class UnixTimeConverter
	{
		private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long CurrentUnixTimeMillis()
		{
			return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static DateTime FromUnixTimeMillis(long epoch)
		{
			DateTime jan1st = Jan1st1970;
			return jan1st.AddMilliseconds(epoch);
		}
	}
}
namespace Adaptive.Agrona.SBE
{
	public interface ICompositeDecoderFlyweight : IDecoderFlyweight, IFlyweight
	{
		ICompositeDecoderFlyweight Wrap(IDirectBuffer buffer, int offset);
	}
	public interface ICompositeEncoderFlyweight : IEncoderFlyweight, IFlyweight
	{
	}
	public interface IDecoderFlyweight : IFlyweight
	{
	}
	public interface IEncoderFlyweight : IFlyweight
	{
		IEncoderFlyweight Wrap(IMutableDirectBuffer buffer, int offset);
	}
	public interface IFlyweight
	{
		int EncodedLength();
	}
	public interface IMessageDecoderFlyweight : IMessageFlyweight, IFlyweight, IDecoderFlyweight
	{
		IMessageDecoderFlyweight Wrap(IDirectBuffer buffer, int offset, int actingBlockLength, int actingVersion);
	}
	public interface IMessageEncoderFlyweight : IMessageFlyweight, IFlyweight, IEncoderFlyweight
	{
	}
	public interface IMessageFlyweight : IFlyweight
	{
		int SbeBlockLength();

		int SbeTemplateId();

		int SbeSchemaId();

		int SbeSchemaVersion();

		string SbeSemanticType();

		int Offset();
	}
}
namespace Adaptive.Agrona.Concurrent
{
	public class AgentInvoker : IDisposable
	{
		private readonly AtomicCounter _errorCounter;

		private readonly ErrorHandler _errorHandler;

		private readonly IAgent _agent;

		public bool IsClosed { get; private set; }

		public bool IsStarted { get; private set; }

		public bool IsRunning { get; private set; }

		public AgentInvoker(ErrorHandler errorHandler, AtomicCounter errorCounter, IAgent agent)
		{
			Objects.RequireNonNull(errorHandler, "errorHandler");
			Objects.RequireNonNull(agent, "agent");
			_errorHandler = errorHandler;
			_errorCounter = errorCounter;
			_agent = agent;
		}

		public IAgent Agent()
		{
			return _agent;
		}

		public void Start()
		{
			try
			{
				if (!IsStarted)
				{
					IsStarted = true;
					_agent.OnStart();
					IsRunning = true;
				}
			}
			catch (Exception exception)
			{
				HandleError(exception);
				Dispose();
			}
		}

		public int Invoke()
		{
			int result = 0;
			if (IsRunning)
			{
				try
				{
					result = _agent.DoWork();
				}
				catch (ThreadInterruptedException)
				{
					Dispose();
					Thread.CurrentThread.Interrupt();
				}
				catch (AgentTerminationException exception)
				{
					HandleError(exception);
					Dispose();
				}
				catch (Exception exception2)
				{
					if (_errorCounter != null)
					{
						_errorCounter.Increment();
					}
					_errorHandler(exception2);
				}
			}
			return result;
		}

		public void Dispose()
		{
			try
			{
				if (!IsClosed)
				{
					IsRunning = false;
					IsClosed = true;
					_agent.OnClose();
				}
			}
			catch (Exception exception)
			{
				HandleError(exception);
			}
		}

		private void HandleError(Exception exception)
		{
			if (_errorCounter != null)
			{
				_errorCounter.Increment();
			}
			_errorHandler(exception);
		}
	}
	public class AgentRunner : IDisposable
	{
		private static readonly Thread TOMBSTONE = new Thread((ThreadStart)delegate
		{
		});

		public static readonly int RETRY_CLOSE_TIMEOUT_MS = 3000;

		private volatile bool _isRunning = true;

		private readonly AtomicCounter _errorCounter;

		private readonly ErrorHandler _errorHandler;

		private readonly IIdleStrategy _idleStrategy;

		private readonly IAgent _agent;

		private readonly AtomicReference<Thread> _thread = new AtomicReference<Thread>();

		public bool IsClosed { get; private set; }

		public AgentRunner(IIdleStrategy idleStrategy, ErrorHandler errorHandler, AtomicCounter errorCounter, IAgent agent)
		{
			if (idleStrategy == null)
			{
				throw new ArgumentNullException("idleStrategy");
			}
			if (errorHandler == null)
			{
				throw new ArgumentNullException("errorHandler");
			}
			if (agent == null)
			{
				throw new ArgumentNullException("agent");
			}
			_idleStrategy = idleStrategy;
			_errorHandler = errorHandler;
			_errorCounter = errorCounter;
			_agent = agent;
		}

		public static Thread StartOnThread(AgentRunner runner)
		{
			Thread thread = new Thread(runner.Run);
			ConfigureThread(thread, runner);
			thread.Start();
			return thread;
		}

		public static Thread StartOnThread(AgentRunner runner, IThreadFactory threadFactory)
		{
			Thread thread = threadFactory.NewThread(runner.Run);
			ConfigureThread(thread, runner);
			thread.Start();
			return thread;
		}

		private static void ConfigureThread(Thread thread, AgentRunner runner)
		{
			thread.Name = runner.Agent().RoleName();
			thread.IsBackground = true;
		}

		public IAgent Agent()
		{
			return _agent;
		}

		public Thread Thread()
		{
			return _thread.Get();
		}

		public void Run()
		{
			try
			{
				if (!_thread.CompareAndSet(null, System.Threading.Thread.CurrentThread))
				{
					return;
				}
				IIdleStrategy idleStrategy = _idleStrategy;
				IAgent agent = _agent;
				try
				{
					agent.OnStart();
				}
				catch (Exception exception)
				{
					HandleError(exception);
					_isRunning = false;
				}
				while (_isRunning && !DoDutyCycle(idleStrategy, agent))
				{
				}
				try
				{
					agent.OnClose();
				}
				catch (Exception exception2)
				{
					HandleError(exception2);
				}
			}
			finally
			{
				IsClosed = true;
			}
		}

		public void Dispose()
		{
			_isRunning = false;
			Thread andSet = _thread.GetAndSet(TOMBSTONE);
			if (andSet == null)
			{
				try
				{
					IsClosed = true;
					_agent.OnClose();
				}
				catch (Exception exception)
				{
					_errorHandler(exception);
				}
			}
			if (TOMBSTONE == andSet)
			{
				return;
			}
			while (true)
			{
				try
				{
					andSet.Join(RETRY_CLOSE_TIMEOUT_MS);
					if (!andSet.IsAlive || IsClosed)
					{
						break;
					}
					Console.Error.WriteLine("Timeout waiting for agent '" + _agent.RoleName() + "' to close, Retrying...");
					andSet.Interrupt();
				}
				catch (ThreadInterruptedException)
				{
					System.Threading.Thread.CurrentThread.Interrupt();
					break;
				}
			}
		}

		private bool DoDutyCycle(IIdleStrategy idleStrategy, IAgent agent)
		{
			try
			{
				idleStrategy.Idle(agent.DoWork());
			}
			catch (ThreadInterruptedException)
			{
				System.Threading.Thread.CurrentThread.Interrupt();
				return true;
			}
			catch (AgentTerminationException exception)
			{
				HandleError(exception);
				return true;
			}
			catch (Exception exception2)
			{
				HandleError(exception2);
			}
			return false;
		}

		private void HandleError(Exception exception)
		{
			if (_isRunning)
			{
				_errorCounter?.Increment();
				_errorHandler(exception);
			}
		}
	}
	public class AgentTerminationException : Exception
	{
		public AgentTerminationException()
		{
		}

		public AgentTerminationException(string message)
			: base(message)
		{
		}
	}
	public class AtomicBoolean
	{
		private int _value;

		private const int TRUE = 1;

		private const int FALSE = 0;

		public AtomicBoolean(bool initialValue)
		{
			Interlocked.Exchange(ref _value, initialValue ? 1 : 0);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool CompareAndSet(bool comparand, bool newValue)
		{
			int value = ToInt(newValue);
			int num = ToInt(comparand);
			return Interlocked.CompareExchange(ref _value, value, num) == num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool Get()
		{
			return ToBool(Volatile.Read(ref _value));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static implicit operator bool(AtomicBoolean value)
		{
			return value.Get();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool ToBool(int value)
		{
			if (value != 0 && value != 1)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException("value");
			}
			return value == 1;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static int ToInt(bool value)
		{
			if (!value)
			{
				return 0;
			}
			return 1;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Set(bool value)
		{
			Volatile.Write(ref _value, ToInt(value));
		}
	}
	public class AtomicLong
	{
		private long _long;

		public long Get()
		{
			return Interlocked.Read(ref _long);
		}

		public void LazySet(long newValue)
		{
			Interlocked.Exchange(ref _long, newValue);
		}

		public void Set(long value)
		{
			Interlocked.Exchange(ref _long, value);
		}

		public void Add(long add)
		{
			Interlocked.Add(ref _long, add);
		}

		public long IncrementAndGet()
		{
			return Interlocked.Increment(ref _long);
		}
	}
	public class AtomicReference<T> where T : class
	{
		private T _value;

		public T Get()
		{
			return Volatile.Read(ref _value);
		}

		public void LazySet(T newValue)
		{
			Volatile.Write(ref _value, newValue);
		}

		public T GetAndSet(T value)
		{
			return Interlocked.Exchange(ref _value, value);
		}

		public bool CompareAndSet(T compareValue, T newValue)
		{
			return Interlocked.CompareExchange(ref _value, newValue, compareValue) == compareValue;
		}
	}
	public class BackgroundThreadFactory : IThreadFactory
	{
		public static readonly BackgroundThreadFactory Instance = new BackgroundThreadFactory();

		public Thread NewThread(ThreadStart runner)
		{
			return new Thread(runner)
			{
				IsBackground = true
			};
		}
	}
	public class BackoffIdleStrategy : IIdleStrategy
	{
		private enum State
		{
			NOT_IDLE,
			SPINNING,
			YIELDING,
			PARKING
		}

		private readonly long _maxSpins;

		private readonly long _maxYields;

		private readonly int _minParkPeriodMs;

		private readonly int _maxParkPeriodMs;

		private State _state;

		private long _spins;

		private long _yields;

		private int _parkPeriodMs;

		public BackoffIdleStrategy(long maxSpins, long maxYields, long minParkPeriodMs, long maxParkPeriodMs)
		{
			_maxSpins = maxSpins;
			_maxYields = maxYields;
			_minParkPeriodMs = (int)minParkPeriodMs;
			_maxParkPeriodMs = (int)maxParkPeriodMs;
			_state = State.NOT_IDLE;
		}

		public void Idle(int workCount)
		{
			if (workCount > 0)
			{
				Reset();
			}
			else
			{
				Idle();
			}
		}

		public void Idle()
		{
			switch (_state)
			{
			case State.NOT_IDLE:
				_state = State.SPINNING;
				_spins++;
				break;
			case State.SPINNING:
				if (++_spins > _maxSpins)
				{
					_state = State.YIELDING;
					_yields = 0L;
				}
				break;
			case State.YIELDING:
				if (++_yields > _maxYields)
				{
					_state = State.PARKING;
					_parkPeriodMs = _minParkPeriodMs;
				}
				else
				{
					Thread.Yield();
				}
				break;
			case State.PARKING:
				Thread.Sleep(_parkPeriodMs);
				_parkPeriodMs = Math.Min(_parkPeriodMs << 1, _maxParkPeriodMs);
				break;
			}
		}

		public void Reset()
		{
			_spins = 0L;
			_yields = 0L;
			_state = State.NOT_IDLE;
		}
	}
	public sealed class BusySpinIdleStrategy : IIdleStrategy
	{
		public void Idle(int workCount)
		{
			if (workCount <= 0)
			{
				Thread.SpinWait(0);
			}
		}

		public void Idle()
		{
			Thread.SpinWait(0);
		}

		public void Reset()
		{
		}
	}
	public class CachedEpochClock : IEpochClock
	{
		private long timeMs;

		public long Time()
		{
			return timeMs;
		}

		public void Update(long timeMs)
		{
			this.timeMs = timeMs;
		}
	}
	public class CompositeAgent : IAgent
	{
		private readonly IAgent[] _agents;

		private readonly string _roleName;

		private int _workIndex;

		public CompositeAgent(List<IAgent> agents)
			: this(agents.ToArray())
		{
		}

		public CompositeAgent(params IAgent[] agents)
		{
			if (agents.Length == 0)
			{
				throw new ArgumentException("CompsiteAgent requires at least one sub-agent");
			}
			_agents = agents;
			StringBuilder stringBuilder = new StringBuilder(agents.Length * 16);
			stringBuilder.Append('[');
			foreach (IAgent agent in agents)
			{
				Objects.RequireNonNull(agent, "Agent cannot be null");
				stringBuilder.Append(agent.RoleName()).Append(',');
			}
			stringBuilder[stringBuilder.Length - 1] = ']';
			_roleName = stringBuilder.ToString();
		}

		public string RoleName()
		{
			return _roleName;
		}

		public void OnStart()
		{
			Exception ex = null;
			IAgent[] agents = _agents;
			foreach (IAgent agent in agents)
			{
				try
				{
					agent.OnStart();
				}
				catch (Exception innerException)
				{
					if (ex == null)
					{
						ex = new Exception("CompositeAgent: underlying agent error on start", innerException);
					}
				}
			}
			if (ex != null)
			{
				throw ex;
			}
		}

		public int DoWork()
		{
			int num = 0;
			IAgent[] agents = _agents;
			while (_workIndex < agents.Length)
			{
				IAgent agent = agents[_workIndex++];
				num += agent.DoWork();
			}
			_workIndex = 0;
			return num;
		}

		public void OnClose()
		{
			Exception ex = null;
			IAgent[] agents = _agents;
			foreach (IAgent agent in agents)
			{
				try
				{
					agent.OnClose();
				}
				catch (Exception innerException)
				{
					if (ex == null)
					{
						ex = new Exception("CompositeAgent: underlying agent error on close", innerException);
					}
				}
			}
			if (ex != null)
			{
				throw ex;
			}
		}
	}
	public class Configuration
	{
		public const long IDLE_MAX_SPINS = 10L;

		public const long IDLE_MAX_YIELDS = 40L;

		public const long IDLE_MIN_PARK_MS = 1L;

		public static readonly long IDLE_MAX_PARK_MS = 16L;
	}
	public class ControllableIdleStrategy : IIdleStrategy
	{
		public const int NOT_CONTROLLED = 0;

		public const int NOOP = 1;

		public const int BUSY_SPIN = 2;

		public const int YIELD = 3;

		public const int PARK = 4;

		private const long PARK_PERIOD_NANOSECONDS = 1000L;

		private readonly StatusIndicatorReader statusIndicatorReader;

		public ControllableIdleStrategy(StatusIndicatorReader statusIndicatorReader)
		{
			this.statusIndicatorReader = statusIndicatorReader;
		}

		public void Idle(int workCount)
		{
			if (workCount <= 0)
			{
				Idle();
			}
		}

		public void Idle()
		{
			switch ((int)statusIndicatorReader.GetVolatile())
			{
			case 2:
				Thread.SpinWait(0);
				break;
			case 3:
				Thread.Yield();
				break;
			default:
				LockSupport.ParkNanos(1000L);
				break;
			case 1:
				break;
			}
		}

		public void Reset()
		{
		}

		public override string ToString()
		{
			return "ControllableIdleStrategy{statusIndicatorReader=" + statusIndicatorReader?.ToString() + "}";
		}
	}
	public class CountedErrorHandler : IErrorHandler
	{
		private readonly ErrorHandler _errorHandler;

		private readonly AtomicCounter _errorCounter;

		public readonly ErrorHandler AsErrorHandler;

		public CountedErrorHandler(ErrorHandler errorHandler, AtomicCounter errorCounter)
		{
			Objects.RequireNonNull(errorHandler, "errorHandler");
			Objects.RequireNonNull(errorCounter, "errorCounter");
			_errorHandler = errorHandler;
			_errorCounter = errorCounter;
			AsErrorHandler = OnError;
		}

		public void OnError(Exception throwable)
		{
			_errorCounter.Increment();
			_errorHandler(throwable);
		}
	}
	public class DefaultThreadFactory : IThreadFactory
	{
		public Thread NewThread(ThreadStart runner)
		{
			return new Thread(runner);
		}
	}
	public interface IAgent
	{
		void OnStart();

		int DoWork();

		void OnClose();

		string RoleName();
	}
	public interface IAtomicBuffer : IMutableDirectBuffer, IDirectBuffer, IComparable<IDirectBuffer>
	{
		void VerifyAlignment();

		long GetLongVolatile(int index);

		void PutLongVolatile(int index, long value);

		void PutLongOrdered(int index, long value);

		long AddLongOrdered(int index, long increment);

		bool CompareAndSetLong(int index, long expectedValue, long updateValue);

		long GetAndAddLong(int index, long delta);

		int GetIntVolatile(int index);

		void PutIntVolatile(int index, int value);

		void PutIntOrdered(int index, int value);

		int AddIntOrdered(int index, int increment);

		bool CompareAndSetInt(int index, int expectedValue, int updateValue);

		int GetAndAddInt(int index, int delta);

		short GetShortVolatile(int index);

		void PutShortVolatile(int index, short value);

		byte GetByteVolatile(int index);

		void PutByteVolatile(int index, byte value);
	}
	public static class IdleStrategyFactory
	{
		public static IIdleStrategy Create(string strategyName, StatusIndicator controllableStatus)
		{
			switch (strategyName)
			{
			case "ControllableIdleStrategy":
			{
				ControllableIdleStrategy result = new ControllableIdleStrategy(controllableStatus);
				controllableStatus.SetOrdered(4L);
				return result;
			}
			case "YieldingIdleStrategy":
				return new YieldingIdleStrategy();
			case "SleepingIdleStrategy":
				return new SleepingIdleStrategy(1);
			case "BusySpinIdleStrategy":
				return new BusySpinIdleStrategy();
			case "NoOpIdleStrategy":
				return new NoOpIdleStrategy();
			default:
				return new BackoffIdleStrategy(10L, 40L, 1L, Configuration.IDLE_MAX_PARK_MS);
			}
		}
	}
	public interface IEpochClock
	{
		long Time();
	}
	public interface IIdleStrategy
	{
		void Idle(int workCount);

		void Idle();

		void Reset();
	}
	public interface ILock
	{
		void Lock();

		void Unlock();

		bool TryLock();
	}
	public interface INanoClock
	{
		long NanoTime();
	}
	public interface IThreadFactory
	{
		Thread NewThread(ThreadStart runner);
	}
	public delegate void MessageHandler(int msgTypeId, IMutableDirectBuffer buffer, int index, int length);
	public sealed class NoOpIdleStrategy : IIdleStrategy
	{
		public void Idle(int workCount)
		{
		}

		public void Idle()
		{
		}

		public void Reset()
		{
		}
	}
	public class NoOpLock : ILock
	{
		public static readonly NoOpLock Instance = new NoOpLock();

		public void Lock()
		{
		}

		public void Unlock()
		{
		}

		public bool TryLock()
		{
			return true;
		}
	}
	public class NullEpochClock : IEpochClock
	{
		public long Time()
		{
			return 0L;
		}
	}
	public class ReentrantLock : ILock
	{
		private readonly object _lockObj = new object();

		public void Lock()
		{
			Monitor.Enter(_lockObj);
		}

		public void Unlock()
		{
			Monitor.Exit(_lockObj);
		}

		public bool TryLock()
		{
			return Monitor.TryEnter(_lockObj);
		}
	}
	public class ShutdownSignalBarrier
	{
		private readonly ManualResetEventSlim _latch = new ManualResetEventSlim(initialState: false);

		public void Signal()
		{
			_latch.Set();
		}

		public void Await()
		{
			try
			{
				_latch.Wait();
			}
			catch (ThreadInterruptedException)
			{
				Thread.CurrentThread.Interrupt();
			}
		}
	}
	public sealed class SleepingIdleStrategy : IIdleStrategy
	{
		private readonly int _sleepPeriodMs;

		public SleepingIdleStrategy(int sleepPeriodMs)
		{
			_sleepPeriodMs = sleepPeriodMs;
		}

		public void Idle(int workCount)
		{
			if (workCount <= 0)
			{
				Thread.Sleep(_sleepPeriodMs);
			}
		}

		public void Idle()
		{
			Thread.Sleep(_sleepPeriodMs);
		}

		public void Reset()
		{
		}
	}
	public class SpinWaitIdleStrategy : IIdleStrategy
	{
		private SpinWait _spinWait;

		public void Idle(int workCount)
		{
			if (workCount <= 0)
			{
				_spinWait.SpinOnce();
			}
		}

		public void Idle()
		{
			_spinWait.SpinOnce();
		}

		public void Reset()
		{
			_spinWait.Reset();
		}
	}
	public abstract class StatusIndicator : StatusIndicatorReader
	{
		public abstract void SetOrdered(long value);
	}
	public abstract class StatusIndicatorReader
	{
		public abstract int Id { get; }

		public abstract long GetVolatile();
	}
	public class StopwatchClock : INanoClock
	{
		private readonly Stopwatch _stopwatch;

		public StopwatchClock()
		{
			_stopwatch = Stopwatch.StartNew();
		}

		public long NanoTime()
		{
			return _stopwatch.ElapsedTicks / Stopwatch.Frequency * 1000000000;
		}
	}
	public class SystemEpochClock : IEpochClock
	{
		public static readonly SystemEpochClock INSTANCE = new SystemEpochClock();

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long Time()
		{
			return UnixTimeConverter.CurrentUnixTimeMillis();
		}
	}
	public class SystemNanoClock : INanoClock
	{
		public static readonly SystemNanoClock INSTANCE = new SystemNanoClock();

		private readonly Stopwatch _stopwatch;

		public SystemNanoClock()
		{
			_stopwatch = Stopwatch.StartNew();
		}

		public long NanoTime()
		{
			return _stopwatch.ElapsedMilliseconds * 1000 * 1000;
		}
	}
	public class UnsafeBuffer : IAtomicBuffer, IMutableDirectBuffer, IDirectBuffer, IComparable<IDirectBuffer>, IDisposable
	{
		public const int ALIGNMENT = 8;

		public static readonly string DISABLE_BOUNDS_CHECKS_PROP_NAME = "AGRONA_DISABLE_BOUNDS_CHECKS";

		private static readonly bool SHOULD_BOUNDS_CHECK = !bool.Parse(Environment.GetEnvironmentVariable(DISABLE_BOUNDS_CHECKS_PROP_NAME) ?? "false");

		private unsafe byte* _pBuffer;

		private bool _disposed;

		private GCHandle _pinnedGcHandle;

		private bool _needToFreeGcHandle;

		public unsafe IntPtr BufferPointer
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return new IntPtr(_pBuffer);
			}
		}

		public byte[] ByteArray { get; private set; }

		public ByteBuffer ByteBuffer { get; private set; }

		public int Capacity { get; private set; }

		public bool IsExpandable => false;

		public UnsafeBuffer(byte[] buffer)
		{
			Wrap(buffer);
		}

		public UnsafeBuffer()
		{
			Capacity = -1;
		}

		public UnsafeBuffer(byte[] buffer, int offset, int length)
		{
			Wrap(buffer, offset, length);
		}

		public UnsafeBuffer(ByteBuffer buffer)
		{
			Wrap(buffer);
		}

		public UnsafeBuffer(IDirectBuffer buffer)
		{
			Wrap(buffer);
		}

		public UnsafeBuffer(IDirectBuffer buffer, int offset, int length)
		{
			Wrap(buffer, offset, length);
		}

		public UnsafeBuffer(IntPtr address, int length)
		{
			Wrap(address, length);
		}

		public UnsafeBuffer(IntPtr address, int offset, int length)
		{
			Wrap(address, offset, length);
		}

		public UnsafeBuffer(MappedByteBuffer buffer)
		{
			Wrap(buffer.Pointer, 0, (int)buffer.Capacity);
		}

		public unsafe void Wrap(byte[] buffer)
		{
			if (buffer == null)
			{
				ThrowHelper.ThrowArgumentNullException("buffer");
			}
			FreeGcHandle();
			_pinnedGcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
			_needToFreeGcHandle = true;
			_pBuffer = (byte*)_pinnedGcHandle.AddrOfPinnedObject().ToPointer();
			Capacity = buffer.Length;
			ByteArray = buffer;
			ByteBuffer = null;
		}

		public unsafe void Wrap(byte[] buffer, int offset, int length)
		{
			if (buffer == null)
			{
				ThrowHelper.ThrowArgumentException("buffer");
			}
			if (SHOULD_BOUNDS_CHECK)
			{
				int num = buffer.Length;
				if (offset != 0 && (offset < 0 || offset > num - 1))
				{
					ThrowHelper.ThrowArgumentException("offset=" + offset + " not valid for capacity=" + num);
				}
				if (length < 0 || length > num - offset)
				{
					ThrowHelper.ThrowArgumentException("offset=" + offset + " length=" + length + " not valid for capacity=" + num);
				}
			}
			FreeGcHandle();
			_pinnedGcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
			_needToFreeGcHandle = true;
			_pBuffer = (byte*)_pinnedGcHandle.AddrOfPinnedObject().ToPointer() + offset;
			Capacity = length;
			ByteArray = buffer;
			ByteBuffer = null;
		}

		public unsafe void Wrap(IDirectBuffer buffer)
		{
			FreeGcHandle();
			_needToFreeGcHandle = false;
			_pBuffer = (byte*)buffer.BufferPointer.ToPointer();
			Capacity = buffer.Capacity;
			ByteArray = buffer.ByteArray;
			ByteBuffer = buffer.ByteBuffer;
		}

		public unsafe void Wrap(ByteBuffer buffer)
		{
			FreeGcHandle();
			_needToFreeGcHandle = false;
			_pBuffer = (byte*)buffer.BufferPointer.ToPointer();
			Capacity = buffer.Capacity;
			ByteArray = null;
			ByteBuffer = buffer;
		}

		public unsafe void Wrap(IDirectBuffer buffer, int offset, int length)
		{
			if (SHOULD_BOUNDS_CHECK)
			{
				int capacity = buffer.Capacity;
				if (offset != 0 && (offset < 0 || offset > capacity - 1))
				{
					ThrowHelper.ThrowArgumentException("offset=" + offset + " not valid for capacity=" + capacity);
				}
				if (length < 0 || length > capacity - offset)
				{
					ThrowHelper.ThrowArgumentException("offset=" + offset + " length=" + length + " not valid for capacity=" + capacity);
				}
			}
			FreeGcHandle();
			_needToFreeGcHandle = false;
			_pBuffer = (byte*)buffer.BufferPointer.ToPointer() + offset;
			Capacity = length;
			ByteArray = buffer.ByteArray;
			ByteBuffer = buffer.ByteBuffer;
		}

		public unsafe void Wrap(IntPtr pointer, int length)
		{
			FreeGcHandle();
			_needToFreeGcHandle = false;
			_pBuffer = (byte*)pointer.ToPointer();
			Capacity = length;
			ByteBuffer = null;
			ByteArray = null;
		}

		public void Wrap(int memoryAddress, int length)
		{
		}

		public unsafe void Wrap(IntPtr pointer, int offset, int length)
		{
			FreeGcHandle();
			_needToFreeGcHandle = false;
			_pBuffer = (byte*)pointer.ToPointer() + offset;
			Capacity = length;
			ByteBuffer = null;
			ByteArray = null;
		}

		public unsafe void Wrap(byte* pointer, int length)
		{
			FreeGcHandle();
			_needToFreeGcHandle = false;
			_pBuffer = pointer;
			Capacity = length;
			ByteBuffer = null;
			ByteArray = null;
		}

		public unsafe void Wrap(byte* pointer, int offset, int length)
		{
			FreeGcHandle();
			_needToFreeGcHandle = false;
			_pBuffer = pointer + offset;
			Capacity = length;
			ByteBuffer = null;
			ByteArray = null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void SetMemory(int index, int length, byte value)
		{
			BoundsCheck0(index, length);
			Unsafe.InitBlock(_pBuffer + index, value, (uint)length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void CheckLimit(int limit)
		{
			if (limit > Capacity)
			{
				ThrowHelper.ThrowIndexOutOfRangeException($"limit={limit:D} is beyond capacity={Capacity:D}");
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void VerifyAlignment()
		{
			long num = new IntPtr(_pBuffer).ToInt64();
			if ((num & 7) != 0L)
			{
				ThrowHelper.ThrowInvalidOperationException($"AtomicBuffer is not correctly aligned: addressOffset={num:D} in not divisible by {8:D}");
			}
		}

		public unsafe long GetLong(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 8);
			long value = *(long*)(_pBuffer + index);
			return EndianessConverter.ApplyInt64(byteOrder, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe long GetLong(int index)
		{
			BoundsCheck0(index, 8);
			return *(long*)(_pBuffer + index);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutLong(int index, long value)
		{
			BoundsCheck0(index, 8);
			*(long*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutLong(int index, long value, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 8);
			value = EndianessConverter.ApplyInt64(byteOrder, value);
			*(long*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe long GetLongVolatile(int index)
		{
			BoundsCheck0(index, 8);
			return Volatile.Read(ref *(long*)(_pBuffer + index));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutLongVolatile(int index, long value)
		{
			BoundsCheck0(index, 8);
			Interlocked.Exchange(ref *(long*)(_pBuffer + index), value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutLongOrdered(int index, long value)
		{
			BoundsCheck0(index, 8);
			Volatile.Write(ref *(long*)(_pBuffer + index), value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long AddLongOrdered(int index, long increment)
		{
			BoundsCheck0(index, 8);
			long @long = GetLong(index);
			PutLongOrdered(index, @long + increment);
			return @long;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe bool CompareAndSetLong(int index, long expectedValue, long updateValue)
		{
			BoundsCheck0(index, 8);
			return Interlocked.CompareExchange(ref *(long*)(_pBuffer + index), updateValue, expectedValue) == expectedValue;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe long GetAndAddLong(int index, long delta)
		{
			BoundsCheck0(index, 8);
			return Interlocked.Add(ref *(long*)(_pBuffer + index), delta) - delta;
		}

		public unsafe void PutInt(int index, int value, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 4);
			value = EndianessConverter.ApplyInt32(byteOrder, value);
			*(int*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe int GetInt(int index)
		{
			BoundsCheck0(index, 4);
			return *(int*)(_pBuffer + index);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe int GetInt(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 4);
			int value = *(int*)(_pBuffer + index);
			return EndianessConverter.ApplyInt32(byteOrder, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutInt(int index, int value)
		{
			BoundsCheck0(index, 4);
			*(int*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe int GetIntVolatile(int index)
		{
			BoundsCheck0(index, 4);
			return Volatile.Read(ref *(int*)(_pBuffer + index));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutIntVolatile(int index, int value)
		{
			BoundsCheck0(index, 4);
			Interlocked.Exchange(ref *(int*)(_pBuffer + index), value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutIntOrdered(int index, int value)
		{
			BoundsCheck0(index, 4);
			Volatile.Write(ref *(int*)(_pBuffer + index), value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int AddIntOrdered(int index, int increment)
		{
			BoundsCheck0(index, 4);
			int @int = GetInt(index);
			PutIntOrdered(index, @int + increment);
			return @int;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe bool CompareAndSetInt(int index, int expectedValue, int updateValue)
		{
			BoundsCheck0(index, 4);
			return Interlocked.CompareExchange(ref *(int*)(_pBuffer + index), updateValue, expectedValue) == expectedValue;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe int GetAndAddInt(int index, int delta)
		{
			BoundsCheck0(index, 4);
			return Interlocked.Add(ref *(int*)(_pBuffer + index), delta) - delta;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe double GetDouble(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 8);
			return EndianessConverter.ApplyDouble(byteOrder, *(double*)(_pBuffer + index));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutDouble(int index, double value, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 8);
			value = EndianessConverter.ApplyDouble(byteOrder, value);
			*(double*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe double GetDouble(int index)
		{
			BoundsCheck0(index, 8);
			return *(double*)(_pBuffer + index);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutDouble(int index, double value)
		{
			BoundsCheck0(index, 8);
			*(double*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe float GetFloat(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 4);
			return EndianessConverter.ApplyFloat(byteOrder, *(float*)(_pBuffer + index));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutFloat(int index, float value, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 4);
			value = EndianessConverter.ApplyFloat(byteOrder, value);
			*(float*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe float GetFloat(int index)
		{
			BoundsCheck0(index, 4);
			return *(float*)(_pBuffer + index);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutFloat(int index, float value)
		{
			BoundsCheck0(index, 4);
			*(float*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe short GetShort(int index)
		{
			BoundsCheck0(index, 2);
			return *(short*)(_pBuffer + index);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe short GetShort(int index, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 2);
			short value = *(short*)(_pBuffer + index);
			return EndianessConverter.ApplyInt16(byteOrder, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutShort(int index, short value)
		{
			BoundsCheck0(index, 2);
			*(short*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutShort(int index, short value, ByteOrder byteOrder)
		{
			BoundsCheck0(index, 2);
			value = EndianessConverter.ApplyInt16(byteOrder, value);
			*(short*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe short GetShortVolatile(int index)
		{
			BoundsCheck0(index, 2);
			return Volatile.Read(ref *(short*)(_pBuffer + index));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutShortVolatile(int index, short value)
		{
			BoundsCheck0(index, 2);
			Volatile.Write(ref *(short*)(_pBuffer + index), value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe byte GetByte(int index)
		{
			BoundsCheck(index);
			return _pBuffer[index];
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutByte(int index, byte value)
		{
			BoundsCheck(index);
			_pBuffer[index] = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe byte GetByteVolatile(int index)
		{
			BoundsCheck(index);
			return Volatile.Read(ref _pBuffer[index]);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutByteVolatile(int index, byte value)
		{
			BoundsCheck(index);
			Volatile.Write(ref _pBuffer[index], value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void GetBytes(int index, byte[] dst)
		{
			GetBytes(index, dst, 0, dst.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void GetBytes(int index, byte[] dst, int offset, int length)
		{
			if (length != 0)
			{
				BoundsCheck0(index, length);
				if (SHOULD_BOUNDS_CHECK)
				{
					BufferUtil.BoundsCheck(dst, offset, length);
				}
				byte* source = _pBuffer + index;
				fixed (byte* destination = &dst[offset])
				{
					ByteUtil.MemoryCopy(destination, source, (uint)length);
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void GetBytes(int index, IMutableDirectBuffer dstBuffer, int dstIndex, int length)
		{
			dstBuffer.PutBytes(dstIndex, this, index, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void PutBytes(int index, byte[] src)
		{
			PutBytes(index, src, 0, src.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutBytes(int index, byte[] src, int offset, int length)
		{
			if (length != 0)
			{
				BoundsCheck0(index, length);
				if (SHOULD_BOUNDS_CHECK)
				{
					BufferUtil.BoundsCheck(src, offset, length);
				}
				byte* destination = _pBuffer + index;
				fixed (byte* source = &src[offset])
				{
					ByteUtil.MemoryCopy(destination, source, (uint)length);
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutBytes(int index, IDirectBuffer srcBuffer, int srcIndex, int length)
		{
			if (length != 0)
			{
				BoundsCheck0(index, length);
				srcBuffer.BoundsCheck(srcIndex, length);
				byte* destination = _pBuffer + index;
				byte* source = (byte*)srcBuffer.BufferPointer.ToPointer() + srcIndex;
				ByteUtil.MemoryCopy(destination, source, (uint)length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe char GetChar(int index)
		{
			BoundsCheck0(index, 2);
			return *(char*)(_pBuffer + index);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void PutChar(int index, char value)
		{
			BoundsCheck0(index, 2);
			*(char*)(_pBuffer + index) = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public string GetStringUtf8(int index)
		{
			int @int = GetInt(index);
			return GetStringUtf8(index, @int);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public string GetStringAscii(int index)
		{
			int @int = GetInt(index);
			return GetStringAscii(index, @int);
		}

		public int GetStringAscii(int index, StringBuilder appendable)
		{
			int @int = GetInt(index);
			return GetStringAscii(index, @int, appendable);
		}

		public unsafe int GetStringAscii(int index, int length, StringBuilder appendable)
		{
			int i = index + 4;
			for (int num = index + 4 + length; i < num; i++)
			{
				char c = *(char*)(_pBuffer + index);
				appendable.Append((c > '\u007f') ? '?' : c);
			}
			return length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public string GetStringUtf8(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index + 4, array);
			return Encoding.UTF8.GetString(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public string GetStringAscii(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index + 4, array);
			return Encoding.ASCII.GetString(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int PutStringUtf8(int index, string value)
		{
			return PutStringUtf8(index, value, int.MaxValue);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int PutStringAscii(int index, string value)
		{
			return PutStringAscii(index, value, int.MaxValue);
		}

		public unsafe int PutStringWithoutLengthAscii(int index, string value)
		{
			int num = value?.Length ?? 0;
			BoundsCheck0(index, num);
			for (int i = 0; i < num; i++)
			{
				char c = value[i];
				if (c > '\u007f')
				{
					c = '?';
				}
				*(char*)(_pBuffer + index + i) = c;
			}
			return num;
		}

		public unsafe int PutStringWithoutLengthAscii(int index, string value, int valueOffset, int length)
		{
			int num = ((value != null) ? Math.Min(value.Length - valueOffset, length) : 0);
			BoundsCheck0(index, num);
			for (int i = 0; i < num; i++)
			{
				char c = value[valueOffset + i];
				if (c > '\u007f')
				{
					c = '?';
				}
				*(char*)(_pBuffer + index + i) = c;
			}
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int PutStringUtf8(int index, string value, int maxEncodedSize)
		{
			byte[] array = ((value == null) ? BufferUtil.NullBytes : Encoding.UTF8.GetBytes(value));
			if (array.Length > maxEncodedSize)
			{
				ThrowHelper.ThrowArgumentException("Encoded string larger than maximum size: " + maxEncodedSize);
			}
			PutInt(index, array.Length);
			PutBytes(index + 4, array);
			return 4 + array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int PutStringAscii(int index, string value, int maxEncodedSize)
		{
			byte[] array = ((value == null) ? BufferUtil.NullBytes : Encoding.ASCII.GetBytes(value));
			if (array.Length > maxEncodedSize)
			{
				ThrowHelper.ThrowArgumentException("Encoded string larger than maximum size: " + maxEncodedSize);
			}
			PutInt(index, array.Length);
			PutBytes(index + 4, array);
			return 4 + array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public string GetStringWithoutLengthUtf8(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index, array);
			return Encoding.UTF8.GetString(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public string GetStringWithoutLengthAscii(int index, int length)
		{
			byte[] array = new byte[length];
			GetBytes(index, array);
			return Encoding.ASCII.GetString(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int PutStringWithoutLengthUtf8(int index, string value)
		{
			byte[] array = ((value == null) ? BufferUtil.NullBytes : Encoding.UTF8.GetBytes(value));
			PutBytes(index, array);
			return array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void BoundsCheck(int index)
		{
			if (SHOULD_BOUNDS_CHECK && (index < 0 || index >= Capacity))
			{
				ThrowHelper.ThrowIndexOutOfRangeException($"index={index:D}, capacity={Capacity:D}");
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void BoundsCheck0(int index, int length)
		{
			if (SHOULD_BOUNDS_CHECK)
			{
				long num = (long)index + (long)length;
				if (index < 0 || num > Capacity)
				{
					ThrowHelper.ThrowIndexOutOfRangeException($"index={index:D}, length={length:D}, capacity={Capacity:D}");
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void BoundsCheck(int index, int length)
		{
			BoundsCheck0(index, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe int CompareTo(IDirectBuffer that)
		{
			int capacity = Capacity;
			int capacity2 = that.Capacity;
			byte* pBuffer = _pBuffer;
			byte* ptr = (byte*)that.BufferPointer.ToPointer();
			int i = 0;
			for (int num = Math.Min(capacity, capacity2); i < num; i++)
			{
				int num2 = pBuffer[i] - ptr[i];
				if (num2 != 0)
				{
					return num2;
				}
			}
			if (capacity != capacity2)
			{
				return capacity - capacity2;
			}
			return 0;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		~UnsafeBuffer()
		{
			Dispose(disposing: false);
		}

		private void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				FreeGcHandle();
				ByteArray = null;
				ByteBuffer = null;
				_disposed = true;
			}
		}

		private void FreeGcHandle()
		{
			if (_needToFreeGcHandle)
			{
				_pinnedGcHandle.Free();
				_needToFreeGcHandle = false;
			}
		}
	}
	public sealed class YieldingIdleStrategy : IIdleStrategy
	{
		public static readonly YieldingIdleStrategy INSTANCE = new YieldingIdleStrategy();

		public void Idle(int workCount)
		{
			if (workCount <= 0)
			{
				Thread.Yield();
			}
		}

		public void Idle()
		{
			Thread.Yield();
		}

		public void Reset()
		{
		}
	}
}
namespace Adaptive.Agrona.Concurrent.Status
{
	public class AtomicCounter : IDisposable
	{
		private readonly int _offset;

		private readonly IAtomicBuffer _buffer;

		private readonly CountersManager _countersManager;

		public int Id { get; }

		public virtual bool IsClosed { get; private set; }

		public AtomicCounter(IAtomicBuffer buffer, int counterId)
			: this(buffer, counterId, null)
		{
		}

		public AtomicCounter(IAtomicBuffer buffer, int counterId, CountersManager countersManager)
		{
			_buffer = buffer;
			Id = counterId;
			_countersManager = countersManager;
			_offset = CountersReader.CounterOffset(counterId);
			buffer.BoundsCheck(_offset, 8);
		}

		public long Increment()
		{
			return _buffer.GetAndAddLong(_offset, 1L);
		}

		public long IncrementOrdered()
		{
			return _buffer.AddLongOrdered(_offset, 1L);
		}

		public void Set(long value)
		{
			_buffer.PutLongVolatile(_offset, value);
		}

		public void SetOrdered(long value)
		{
			_buffer.PutLongOrdered(_offset, value);
		}

		public long GetAndAdd(long increment)
		{
			return _buffer.GetAndAddLong(_offset, increment);
		}

		public long GetAndAddOrdered(long increment)
		{
			return _buffer.AddLongOrdered(_offset, increment);
		}

		public bool CompareAndSet(long expectedValue, long updateValue)
		{
			return _buffer.CompareAndSetLong(_offset, expectedValue, updateValue);
		}

		public long Get()
		{
			return _buffer.GetLongVolatile(_offset);
		}

		public long GetWeak()
		{
			return _buffer.GetLong(_offset);
		}

		public bool ProposeMaxOrdered(long proposedValue)
		{
			bool result = false;
			if (_buffer.GetLong(_offset) < proposedValue)
			{
				_buffer.PutLongOrdered(_offset, proposedValue);
				result = true;
			}
			return result;
		}

		public virtual void Dispose()
		{
			if (!IsClosed)
			{
				IsClosed = true;
				_countersManager?.Free(Id);
			}
		}
	}
	public class AtomicLongPosition : IPosition, IReadablePosition, IDisposable
	{
		private readonly AtomicLong _value = new AtomicLong();

		public int Id => 0;

		public void Dispose()
		{
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long GetVolatile()
		{
			return _value.Get();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long Get()
		{
			return _value.Get();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Set(long value)
		{
			_value.Set(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void SetOrdered(long value)
		{
			_value.Set(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void SetVolatile(long value)
		{
			_value.Set(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool ProposeMax(long proposedValue)
		{
			return ProposeMaxOrdered(proposedValue);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool ProposeMaxOrdered(long proposedValue)
		{
			bool result = false;
			if (Get() < proposedValue)
			{
				SetOrdered(proposedValue);
				result = true;
			}
			return result;
		}
	}
	public class CountersManager : CountersReader
	{
		private readonly long _freeToReuseTimeoutMs;

		private int _idHighWaterMark = -1;

		private readonly List<int> _freeList = new List<int>();

		private readonly IEpochClock _epochClock;

		public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer, Encoding labelCharset, IEpochClock epochClock, long freeToReuseTimeoutMs)
			: base(metaDataBuffer, valuesBuffer, labelCharset)
		{
			valuesBuffer.VerifyAlignment();
			_epochClock = epochClock;
			_freeToReuseTimeoutMs = freeToReuseTimeoutMs;
			if (metaDataBuffer.Capacity < valuesBuffer.Capacity * 2)
			{
				throw new ArgumentException("Meta data buffer not sufficiently large");
			}
		}

		public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer)
			: base(metaDataBuffer, valuesBuffer)
		{
			valuesBuffer.VerifyAlignment();
			_epochClock = new NullEpochClock();
			if (metaDataBuffer.Capacity < valuesBuffer.Capacity * 2)
			{
				throw new ArgumentException("Meta data buffer not sufficiently large");
			}
		}

		public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer, Encoding labelCharset)
			: this(metaDataBuffer, valuesBuffer, labelCharset, new NullEpochClock(), 0L)
		{
			valuesBuffer.VerifyAlignment();
			if (metaDataBuffer.Capacity < valuesBuffer.Capacity * 2)
			{
				throw new ArgumentException("Meta data buffer not sufficiently large");
			}
		}

		public int Allocate(string label, int typeId = 0)
		{
			int num = NextCounterId();
			CheckCountersCapacity(num);
			int num2 = CountersReader.MetaDataOffset(num);
			CheckMetaDataCapacity(num2);
			try
			{
				base.MetaDataBuffer.PutInt(num2 + CountersReader.TYPE_ID_OFFSET, typeId);
				base.MetaDataBuffer.PutLong(num2 + CountersReader.FREE_FOR_REUSE_DEADLINE_OFFSET, CountersReader.NOT_FREE_TO_REUSE);
				PutLabel(num2, label);
				base.MetaDataBuffer.PutIntOrdered(num2, 1);
				return num;
			}
			catch (Exception)
			{
				_freeList.Add(num);
				throw;
			}
		}

		public int Allocate(string label, int typeId, Action<IMutableDirectBuffer> keyFunc)
		{
			int num = NextCounterId();
			CheckCountersCapacity(num);
			int num2 = CountersReader.MetaDataOffset(num);
			CheckMetaDataCapacity(num2);
			try
			{
				base.MetaDataBuffer.PutInt(num2 + CountersReader.TYPE_ID_OFFSET, typeId);
				keyFunc(new UnsafeBuffer(base.MetaDataBuffer, num2 + CountersReader.KEY_OFFSET, CountersReader.MAX_KEY_LENGTH));
				base.MetaDataBuffer.PutLong(num2 + CountersReader.FREE_FOR_REUSE_DEADLINE_OFFSET, CountersReader.NOT_FREE_TO_REUSE);
				PutLabel(num2, label);
				base.MetaDataBuffer.PutIntOrdered(num2, 1);
				return num;
			}
			catch (Exception)
			{
				_freeList.Add(num);
				throw;
			}
		}

		public int Allocate(int typeId, IDirectBuffer keyBuffer, int keyOffset, int keyLength, IDirectBuffer labelBuffer, int labelOffset, int labelLength)
		{
			int num = NextCounterId();
			CheckCountersCapacity(num);
			int num2 = CountersReader.MetaDataOffset(num);
			CheckMetaDataCapacity(num2);
			try
			{
				base.MetaDataBuffer.PutInt(num2 + CountersReader.TYPE_ID_OFFSET, typeId);
				base.MetaDataBuffer.PutLong(num2 + CountersReader.FREE_FOR_REUSE_DEADLINE_OFFSET, CountersReader.NOT_FREE_TO_REUSE);
				int length;
				if (keyBuffer != null)
				{
					length = Math.Min(keyLength, CountersReader.MAX_KEY_LENGTH);
					base.MetaDataBuffer.PutBytes(num2 + CountersReader.KEY_OFFSET, keyBuffer, keyOffset, length);
				}
				length = Math.Min(labelLength, CountersReader.MAX_LABEL_LENGTH);
				base.MetaDataBuffer.PutInt(num2 + CountersReader.LABEL_OFFSET, length);
				base.MetaDataBuffer.PutBytes(num2 + CountersReader.LABEL_OFFSET + 4, labelBuffer, labelOffset, length);
				base.MetaDataBuffer.PutIntOrdered(num2, 1);
				return num;
			}
			catch (Exception)
			{
				_freeList.Add(num);
				throw;
			}
		}

		public AtomicCounter NewCounter(string label)
		{
			return new AtomicCounter(base.ValuesBuffer, Allocate(label), this);
		}

		public AtomicCounter NewCounter(string label, int typeId)
		{
			return new AtomicCounter(base.ValuesBuffer, Allocate(label, typeId), this);
		}

		public AtomicCounter NewCounter(string label, int typeId, Action<IMutableDirectBuffer> keyFunc)
		{
			return new AtomicCounter(base.ValuesBuffer, Allocate(label, typeId, keyFu