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