Last active
August 21, 2019 07:06
-
-
Save gamemachine/d9ab8246558dac8e6db747d52de127c6 to your computer and use it in GitHub Desktop.
Revisions
-
gamemachine revised this gist
Feb 2, 2019 . 1 changed file with 6 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -33,6 +33,7 @@ private ByteArrayPool() public void Clear() { Pools.Clear(); Wrappers.Clear(); } public ByteArrayPoolStats Update() @@ -95,19 +96,20 @@ public ByteArrayWrapper Rent(int length) return result; } public void Return(ByteArrayWrapper wrapper) { ConcurrentQueue<ByteArrayWrapper> pool; if (!Pools.TryGetValue(wrapper.Length, out pool)) { throw new ByteArrayPoolException("Return failed - pool not found"); } wrapper.Reclaim(); pool.Enqueue(wrapper); } } } namespace GameCommon.Pooling { public class ByteArrayWrapper -
gamemachine revised this gist
Feb 2, 2019 . 1 changed file with 20 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -176,3 +176,23 @@ public struct ByteArrayPoolStats public int ForceReturnCount; } } using System; namespace GameCommon.Pooling { public class ByteArrayPoolException : Exception { public ByteArrayPoolException() { } public ByteArrayPoolException(string message) : base(message) { } } } -
gamemachine revised this gist
Feb 2, 2019 . 1 changed file with 93 additions and 23 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,14 +1,21 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; namespace GameCommon.Pooling { public class ByteArrayPool { private const int MaxArrayLength = 512; private const int MaxRentTime = 1000; // in milliseconds static readonly ByteArrayPool instance = new ByteArrayPool(); private ConcurrentDictionary<int, ConcurrentQueue<ByteArrayWrapper>> Pools = new ConcurrentDictionary<int, ConcurrentQueue<ByteArrayWrapper>>(); private List<ByteArrayWrapper> Wrappers = new List<ByteArrayWrapper>(); private int LargeMessageCount = 0; private int ForceReturnCount = 0; private Stopwatch StopWatch; public static ByteArrayPool Instance { @@ -18,35 +25,79 @@ public static ByteArrayPool Instance } } private ByteArrayPool() { StopWatch = Stopwatch.StartNew(); } public void Clear() { Pools.Clear(); } public ByteArrayPoolStats Update() { ByteArrayPoolStats stats = new ByteArrayPoolStats(); stats.WrapperCount = Wrappers.Count; stats.LargeMessageCount = LargeMessageCount; long now = StopWatch.ElapsedMilliseconds; foreach (ByteArrayWrapper wrapper in Wrappers) { if (wrapper.IsRented) { long elapsed = now - wrapper.RentedAt; if (elapsed > MaxRentTime) { wrapper.Return(); ForceReturnCount++; } else { stats.RentedCount++; } } } stats.ForceReturnCount = ForceReturnCount; return stats; } public ByteArrayWrapper Rent(int length) { ByteArrayWrapper wrapper = null; if (length > MaxArrayLength) { LargeMessageCount++; wrapper = new ByteArrayWrapper(length); wrapper.Rent(StopWatch.ElapsedMilliseconds); wrapper.InPool = false; return wrapper; } ConcurrentQueue<ByteArrayWrapper> pool; if (!Pools.TryGetValue(length, out pool)) { pool = new ConcurrentQueue<ByteArrayWrapper>(); Pools[length] = pool; } ByteArrayWrapper result; while (!pool.TryDequeue(out result)) { wrapper = new ByteArrayWrapper(length); Wrappers.Add(wrapper); pool.Enqueue(wrapper); } result.Rent(StopWatch.ElapsedMilliseconds); return result; } public void Return(ByteArrayWrapper value) { ConcurrentQueue<ByteArrayWrapper> pool; if (!Pools.TryGetValue(value.Length, out pool)) { throw new ByteArrayPoolException("Return failed - pool not found"); @@ -59,21 +110,23 @@ public void Return(PooledByteArray value) namespace GameCommon.Pooling { public class ByteArrayWrapper { public bool InPool; public int Length; public bool IsRented { get; private set; } private byte[] Value; public long RentedAt { get; private set; } public ByteArrayWrapper(int length) { InPool = true; Length = length; IsRented = false; Value = new byte[length]; } public byte[] GetBytes() { if (!IsRented) { @@ -85,6 +138,11 @@ public byte[] GetValue() public void Return() { if (!InPool) { return; } if (!IsRented) { throw new ByteArrayPoolException("Already returned"); @@ -94,8 +152,9 @@ public void Return() } public void Rent(long rentedAt) { RentedAt = rentedAt; IsRented = true; } @@ -106,3 +165,14 @@ public void Reclaim() } } namespace GameCommon.Pooling { public struct ByteArrayPoolStats { public int WrapperCount; public int RentedCount; public int LargeMessageCount; public int ForceReturnCount; } } -
gamemachine created this gist
Feb 1, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,108 @@ using System.Collections.Concurrent; namespace GameCommon.Pooling { public class ByteArrayPool { static readonly ByteArrayPool instance = new ByteArrayPool(); private static ConcurrentDictionary<int, ConcurrentQueue<PooledByteArray>> Pools = new ConcurrentDictionary<int, ConcurrentQueue<PooledByteArray>>(); public static ByteArrayPool Instance { get { return instance; } } public PooledByteArray Rent(int length) { ConcurrentQueue<PooledByteArray> pool; if (!Pools.TryGetValue(length, out pool)) { pool = new ConcurrentQueue<PooledByteArray>(); Pools[length] = pool; } if (pool.Count == 0) { pool.Enqueue(new PooledByteArray(length)); } PooledByteArray result; if (pool.TryDequeue(out result)) { result.Rent(); return result; } else { throw new ByteArrayPoolException("Rent failed"); } } public void Return(PooledByteArray value) { ConcurrentQueue<PooledByteArray> pool; if (!Pools.TryGetValue(value.Length, out pool)) { throw new ByteArrayPoolException("Return failed - pool not found"); } value.Reclaim(); pool.Enqueue(value); } } } namespace GameCommon.Pooling { public class PooledByteArray { public int Length; public bool IsRented { get; private set; } private byte[] Value; public PooledByteArray(int length) { Length = length; IsRented = false; Value = new byte[length]; } public byte[] GetValue() { if (!IsRented) { throw new ByteArrayPoolException("Attempt to access value before renting"); } return Value; } public void Return() { if (!IsRented) { throw new ByteArrayPoolException("Already returned"); } ByteArrayPool.Instance.Return(this); } public void Rent() { IsRented = true; } public void Reclaim() { IsRented = false; } } }