From 8d2a2cd5de40e2b94ef5007c32832ed9a063dc40 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Thu, 12 Oct 2023 22:09:49 +0800 Subject: +hazel-networking --- Tools/Hazel-Networking/Hazel/ObjectPool.cs | 108 +++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 Tools/Hazel-Networking/Hazel/ObjectPool.cs (limited to 'Tools/Hazel-Networking/Hazel/ObjectPool.cs') diff --git a/Tools/Hazel-Networking/Hazel/ObjectPool.cs b/Tools/Hazel-Networking/Hazel/ObjectPool.cs new file mode 100644 index 0000000..510e55a --- /dev/null +++ b/Tools/Hazel-Networking/Hazel/ObjectPool.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading; + +namespace Hazel +{ + /// + /// A fairly simple object pool for items that will be created a lot. + /// + /// The type that is pooled. + /// + public sealed class ObjectPool where T : IRecyclable + { + private int numberCreated; + public int NumberCreated { get { return numberCreated; } } + + public int NumberInUse { get { return this.inuse.Count; } } + public int NumberNotInUse { get { return this.pool.Count; } } + public int Size { get { return this.NumberInUse + this.NumberNotInUse; } } + +#if HAZEL_BAG + private readonly ConcurrentBag pool = new ConcurrentBag(); +#else + private readonly List pool = new List(); +#endif + + // Unavailable objects + private readonly ConcurrentDictionary inuse = new ConcurrentDictionary(); + + /// + /// The generator for creating new objects. + /// + /// + private readonly Func objectFactory; + + /// + /// Internal constructor for our ObjectPool. + /// + internal ObjectPool(Func objectFactory) + { + this.objectFactory = objectFactory; + } + + /// + /// Returns a pooled object of type T, if none are available another is created. + /// + /// An instance of T. + internal T GetObject() + { +#if HAZEL_BAG + if (!pool.TryTake(out T item)) + { + Interlocked.Increment(ref numberCreated); + item = objectFactory.Invoke(); + } +#else + T item; + lock (this.pool) + { + if (this.pool.Count > 0) + { + var idx = this.pool.Count - 1; + item = this.pool[idx]; + this.pool.RemoveAt(idx); + } + else + { + Interlocked.Increment(ref numberCreated); + item = objectFactory.Invoke(); + } + } +#endif + + if (!inuse.TryAdd(item, true)) + { + throw new Exception("Duplicate pull " + typeof(T).Name); + } + + return item; + } + + /// + /// Returns an object to the pool. + /// + /// The item to return. + internal void PutObject(T item) + { + if (inuse.TryRemove(item, out bool b)) + { +#if HAZEL_BAG + pool.Add(item); +#else + lock (this.pool) + { + pool.Add(item); + } +#endif + } + else + { +#if DEBUG + throw new Exception("Duplicate add " + typeof(T).Name); +#endif + } + } + } +} -- cgit v1.1-26-g67d0