using System.Collections.Concurrent;
using UnityEngine;
namespace UVC.Data.Core
{
///
/// DataArray 객체의 재사용을 위한 풀링 클래스입니다.
///
public static class DataArrayPool
{
private static readonly ConcurrentQueue _pool = new ConcurrentQueue();
private static int _maxPoolSize = 100; // DataArray는 DataObject보다 수가 적을 것이므로 기본값 조정
// --- 통계용 필드 ---
private static int _inUseCount = 0;
private static int _peakUsage = 0;
private static int _poolMisses = 0;
private static readonly object _statsLock = new object();
static DataArrayPool()
{
// maxPoolSize만큼의 DataObject 인스턴스를 미리 생성하여 풀에 추가합니다.
for (int i = 0; i < _maxPoolSize; i++)
{
_pool.Enqueue(new DataArray() { IsInPool = true, CreatedFromPool = true });
}
}
///
/// 풀에서 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 % 10 == 0) Debug.Log($"DataArrayPool stats: {GetStats()}");
if (fromPool)
{
array.IsInPool = false;
}
return fromPool ? array : new DataArray() { CreatedFromPool = true };
}
///
/// 사용이 끝난 DataArray 객체를 풀에 반환합니다.
///
/// 반환할 DataArray 객체
public static void Return(DataArray array)
{
if (array == null || array.IsInPool) return;
bool shouldReturnToPool;
lock (_statsLock)
{
_inUseCount--;
shouldReturnToPool = _pool.Count < _maxPoolSize;
}
if (shouldReturnToPool)
{
array.Reset();
array.IsInPool = true;
_pool.Enqueue(array);
}
}
///
/// 풀의 현재 성능 통계를 문자열로 반환합니다.
///
/// 풀 통계 (최대 사용량, 현재 사용량, 풀 비어있을 때 생성 횟수, 현재 풀 크기)
public static string GetStats()
{
lock (_statsLock)
{
return $"최대 사용량: {_peakUsage}, 현재 사용량: {_inUseCount}, 풀 비어있을 때 생성 횟수: {_poolMisses}, 현재 풀 크기: {_pool.Count}, Max Size: {_maxPoolSize}";
}
}
///
/// 풀 통계를 초기화합니다.
///
public static void ResetStats()
{
lock (_statsLock)
{
_peakUsage = 0;
_poolMisses = 0;
}
}
}
}