using RTG; using System.Collections.Concurrent; using UnityEngine; namespace UVC.Data { /// /// DataArray 객체의 재사용을 위한 풀링 클래스입니다. /// public static class DataArrayPool { private static readonly ConcurrentQueue _pool = new ConcurrentQueue(); private static int _maxPoolSize = 500; // DataArray는 DataObject보다 수가 적을 것이므로 기본값 조정 // --- 통계용 필드 --- private static int _inUseCount = 0; private static int _peakUsage = 0; private static int _poolMisses = 0; private static readonly object _statsLock = new object(); /// /// 풀의 최대 크기를 설정합니다. /// /// 설정할 최대 크기 public static void SetMaxPoolSize(int size) { _maxPoolSize = size > 0 ? size : 500; } /// /// 풀에서 DataArray 객체를 가져옵니다. 풀이 비어있으면 새로 생성합니다. /// /// 재사용 가능한 DataArray 객체 public static DataArray Get() { bool fromPool = _pool.TryDequeue(out var array); lock (_statsLock) { _inUseCount++; if (_inUseCount > _peakUsage) { _peakUsage = _inUseCount; } if (!fromPool) { _poolMisses++; if (_inUseCount > _maxPoolSize) { int oldSize = _maxPoolSize; _maxPoolSize += 100; // 증가량 조정 Debug.Log($"DataArrayPool size automatically increased from {oldSize} to {_maxPoolSize}. Peak usage: {_peakUsage}"); } } } if(_peakUsage % 100 == 0) Debug.Log($"DataArrayPool stats: {GetStats()}"); if (fromPool) { array.IsInPool = false; array.Reset(); } return fromPool ? array : new DataArray(); } /// /// 사용이 끝난 DataArray 객체를 풀에 반환합니다. /// /// 반환할 DataArray 객체 public static void Return(DataArray array) { if (array == null || array.IsInPool) return; lock (_statsLock) { _inUseCount--; } if (_pool.Count < _maxPoolSize) { array.Reset(); array.IsInPool = true; _pool.Enqueue(array); } } /// /// 풀의 현재 성능 통계를 문자열로 반환합니다. /// /// 풀 통계 (최대 사용량, 현재 사용량, 풀 비어있을 때 생성 횟수, 현재 풀 크기) public static string GetStats() { return $"Peak Usage: {_peakUsage}, In Use: {_inUseCount}, Misses: {_poolMisses}, Pooled: {_pool.Count}, Max Size: {_maxPoolSize}"; } /// /// 풀 통계를 초기화합니다. /// public static void ResetStats() { lock (_statsLock) { _peakUsage = 0; _poolMisses = 0; } } } }