Cleanup CategorizedPool.

This commit is contained in:
2023-02-12 17:27:54 +08:00
parent f60ba1088d
commit 87362b47c5
3 changed files with 63 additions and 11 deletions

View File

@@ -1,38 +1,82 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Cryville.Common.Buffers { namespace Cryville.Common.Buffers {
/// <summary>
/// A set of resource pools categorized by a category type.
/// </summary>
/// <typeparam name="TCategory">The category type.</typeparam>
/// <typeparam name="TObject">The type of the objects in the pool.</typeparam>
public abstract class CategorizedPool<TCategory, TObject> where TObject : class { public abstract class CategorizedPool<TCategory, TObject> where TObject : class {
protected readonly Dictionary<TCategory, ObjectPool<TObject>> Buckets /// <summary>
= new Dictionary<TCategory, ObjectPool<TObject>>(); /// The set of underlying pools.
/// </summary>
/// <remarks>
/// <para>The <see cref="Rent(TCategory)" /> and <see cref="Return(TCategory, TObject)" /> method select an underlying pool directly from this set with the category as the key. When overridden, this set must be available since construction.</para>
/// </remarks>
protected abstract IReadOnlyDictionary<TCategory, ObjectPool<TObject>> Buckets { get; }
/// <summary>
/// The count of objects rented from the set of pools.
/// </summary>
public int RentedCount { get; private set; } public int RentedCount { get; private set; }
public TObject Rent(TCategory name) { /// <summary>
var obj = Buckets[name].Rent(); /// Rents an object from the pool.
/// </summary>
/// <param name="category">The category.</param>
/// <returns>The rented object.</returns>
public TObject Rent(TCategory category) {
var obj = Buckets[category].Rent();
RentedCount++; RentedCount++;
return obj; return obj;
} }
public void Return(TCategory name, TObject obj) { /// <summary>
Buckets[name].Return(obj); /// Returns a rented object to the pool.
/// </summary>
/// <param name="category">The category.</param>
/// <param name="obj">The object to return.</param>
public void Return(TCategory category, TObject obj) {
Buckets[category].Return(obj);
--RentedCount; --RentedCount;
} }
} }
/// <summary>
/// A utility to access a categorized pool, representing a single unit that uses a shared categorized pool.
/// </summary>
/// <typeparam name="TCategory">The category type.</typeparam>
/// <typeparam name="TObject">The type of the objects in the pool.</typeparam>
public class CategorizedPoolAccessor<TCategory, TObject> where TObject : class { public class CategorizedPoolAccessor<TCategory, TObject> where TObject : class {
readonly CategorizedPool<TCategory, TObject> _pool; readonly CategorizedPool<TCategory, TObject> _pool;
static readonly SimpleObjectPool<Dictionary<TObject, TCategory>> _dictPool static readonly SimpleObjectPool<Dictionary<TObject, TCategory>> _dictPool
= new SimpleObjectPool<Dictionary<TObject, TCategory>>(1024); = new SimpleObjectPool<Dictionary<TObject, TCategory>>(1024);
Dictionary<TObject, TCategory> _rented; Dictionary<TObject, TCategory> _rented;
/// <summary>
/// Creates an instance of the <see cref="CategorizedPoolAccessor{TCategory, TObject}" /> class.
/// </summary>
/// <param name="pool">The categorized pool.</param>
public CategorizedPoolAccessor(CategorizedPool<TCategory, TObject> pool) { public CategorizedPoolAccessor(CategorizedPool<TCategory, TObject> pool) {
_pool = pool; _pool = pool;
} }
public TObject Rent(TCategory name) { /// <summary>
var obj = _pool.Rent(name); /// Rents an object from the pool.
/// </summary>
/// <param name="category">The category.</param>
/// <returns>The rented object.</returns>
public TObject Rent(TCategory category) {
var obj = _pool.Rent(category);
if (_rented == null) _rented = _dictPool.Rent(); if (_rented == null) _rented = _dictPool.Rent();
_rented.Add(obj, name); _rented.Add(obj, category);
return obj; return obj;
} }
/// <summary>
/// Returns a rented object to the pool.
/// </summary>
/// <param name="obj">The object to return.</param>
public void Return(TObject obj) { public void Return(TObject obj) {
_pool.Return(_rented[obj], obj); _pool.Return(_rented[obj], obj);
_rented.Remove(obj); _rented.Remove(obj);
} }
/// <summary>
/// Returns all objects rented by this accessor to the pool.
/// </summary>
public void ReturnAll() { public void ReturnAll() {
if (_rented == null) return; if (_rented == null) return;
foreach (var obj in _rented) { foreach (var obj in _rented) {

View File

@@ -1,5 +1,6 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using System.Collections.Generic;
namespace Cryville.Crtr.Event { namespace Cryville.Crtr.Event {
internal class MotionCache { internal class MotionCache {
@@ -25,9 +26,12 @@ namespace Cryville.Crtr.Event {
obj.Valid = false; obj.Valid = false;
} }
} }
readonly Dictionary<Identifier, ObjectPool<MotionCache>> m_buckets;
protected override IReadOnlyDictionary<Identifier, ObjectPool<MotionCache>> Buckets { get { return m_buckets; } }
public MotionCachePool() { public MotionCachePool() {
m_buckets = new Dictionary<Identifier, ObjectPool<MotionCache>>(ChartPlayer.motionRegistry.Count);
foreach (var reg in ChartPlayer.motionRegistry) foreach (var reg in ChartPlayer.motionRegistry)
Buckets.Add(reg.Key, new Bucket(reg.Key, 4096)); m_buckets.Add(reg.Key, new Bucket(reg.Key, 4096));
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using System.Collections.Generic;
namespace Cryville.Crtr.Event { namespace Cryville.Crtr.Event {
internal class RMVPool : CategorizedPool<Identifier, RealtimeMotionValue> { internal class RMVPool : CategorizedPool<Identifier, RealtimeMotionValue> {
@@ -12,9 +13,12 @@ namespace Cryville.Crtr.Event {
return new RealtimeMotionValue().Init(_reg.InitValue); return new RealtimeMotionValue().Init(_reg.InitValue);
} }
} }
readonly Dictionary<Identifier, ObjectPool<RealtimeMotionValue>> m_buckets;
protected override IReadOnlyDictionary<Identifier, ObjectPool<RealtimeMotionValue>> Buckets { get { return m_buckets; } }
public RMVPool() { public RMVPool() {
m_buckets = new Dictionary<Identifier, ObjectPool<RealtimeMotionValue>>(ChartPlayer.motionRegistry.Count);
foreach (var reg in ChartPlayer.motionRegistry) foreach (var reg in ChartPlayer.motionRegistry)
Buckets.Add(reg.Key, new Bucket(reg.Key, 4096)); m_buckets.Add(reg.Key, new Bucket(reg.Key, 4096));
} }
} }
} }