Files
Main/Assets/Plugins/References/FuncellBase/ObjectPool/BlockPool.cs

176 lines
4.7 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
using System;
using System.Collections.Generic;
using System.Text;
namespace Thousandto.Core.Base
{
public class BlockPool : IObjectPool
{
public class Settings
{
public int BlockSize;
public int MaxBlockNum;
public bool ExtendAble;
public Settings(int s, int n, bool e)
{
BlockSize = s;
MaxBlockNum = n;
ExtendAble = e;
}
}
static BlockPool _sharedInstance = null;
static Dictionary<int, Settings> _defaultSettings = new Dictionary<int, Settings>();
static BlockPool()
{
_defaultSettings.Add(1 << 2, new Settings(1 << 2, 16, true)); // 4
_defaultSettings.Add(1 << 3, new Settings(1 << 3, 64, true)); // 8
_defaultSettings.Add(1 << 4, new Settings(1 << 4, 64, true)); // 16
_defaultSettings.Add(1 << 5, new Settings(1 << 5, 64, true)); // 32
_defaultSettings.Add(1 << 6, new Settings(1 << 6, 64, true)); // 64
_defaultSettings.Add(1 << 7, new Settings(1 << 7, 32, true)); // 128
_defaultSettings.Add(1 << 8, new Settings(1 << 8, 16, true)); // 256
_sharedInstance = new BlockPool();
}
public static BlockPool SharedInstance
{
get
{
return _sharedInstance;
}
}
BlockAllocator CreateAllocator(int size)
{
size = AlignToBlock(size);
Settings s = null;
if (_defaultSettings.TryGetValue(size, out s))
{
return new BlockAllocator(s.BlockSize, s.MaxBlockNum, s.ExtendAble);
}
else
{
return new BlockAllocator(size, 8, true);
}
}
public static int AlignToBlock(int size)
{
size = ((size + 3) & ~3); // 4 bytes aligned
if ((size & (size - 1)) != 0)
{
size = NextPowerOf2(size);
}
return size;
}
public static int NextPowerOf2(int value)
{
int rval = 1;
while (rval < value)
{
rval <<= 1;
}
return rval;
}
public static void MemSet(byte[] array, byte value)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
int block = 32, index = 0;
int length = Math.Min(block, array.Length);
//Fill the initial array
while (index < length)
{
array[index++] = value;
}
length = array.Length;
while (index < length)
{
Buffer.BlockCopy(array, 0, array, index, Math.Min(block, length - index));
index += block;
block *= 2;
}
}
Dictionary<int, BlockAllocator> _bPool = new Dictionary<int, BlockAllocator>();
public byte[] Allocate(int size)
{
size = AlignToBlock(size);
BlockAllocator allocator = null;
if (!_bPool.TryGetValue(size, out allocator))
{
allocator = CreateAllocator(size);
_bPool.Add(size, allocator);
}
return allocator.Allocate();
}
public void Free(ref byte[] p)
{
if (p != null)
{
BlockAllocator allocator = null;
if (_bPool.TryGetValue(p.Length, out allocator))
{
allocator.Free(p);
}
p = null;
}
}
public BlockAllocator TryGet(int size)
{
size = AlignToBlock(size);
BlockAllocator ba = null;
_bPool.TryGetValue(size, out ba);
return ba;
}
public BlockAllocator AddPool(int size, int maxnum, bool extendAble = true)
{
size = AlignToBlock(size);
BlockAllocator ba = null;
if (!_bPool.TryGetValue(size, out ba))
{
ba = new BlockAllocator(size, maxnum, extendAble);
_bPool.Add(size, ba);
}
return ba;
}
public int GetTotalSize()
{
int size = 0;
foreach (var t in _bPool)
{
size += t.Value.GetTotalSize();
}
return size;
}
public BlockPool()
{
}
public void Sweep()
{
foreach (var t in _bPool)
{
t.Value.Sweep();
}
}
}
}