Files
Main/Assets/Plugins/References/FuncellBase/ObjectPool/BlockAllocator.cs
2025-01-25 04:38:09 +08:00

115 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
namespace Thousandto.Core.Base
{
public class BlockAllocator {
const int DefaultMaxBlockNum = 100;
public delegate void SweepAction();
public SweepAction Sweeper {
get;
set;
}
public bool ExtendAble {
get {
return _extendAble;
}
set {
_extendAble = value;
}
}
public void TrimExcess() {
if ( _freeBlocks.Count > _initMaxBlockNum ) {
_freeBlocks.RemoveRange( _initMaxBlockNum, _freeBlocks.Count - _initMaxBlockNum );
_freeBlocks.TrimExcess();
}
}
public void Sweep() {
if ( Sweeper == null ) {
TrimExcess();
} else {
Sweeper();
}
}
public BlockAllocator( int theBlockSize, int maxBlock, bool theExtendAble ) {
_blockSize = theBlockSize;
if ( maxBlock <= 0 ) {
maxBlock = DefaultMaxBlockNum;
}
_freeBlocks = new List<byte[]>( maxBlock );
_maxBlockNum = _freeBlocks.Capacity;
_initMaxBlockNum = _maxBlockNum;
_extendAble = theExtendAble;
for ( int i = 0; i < _maxBlockNum; ++i ) {
_freeBlocks.Add( new byte[_blockSize] );
}
}
public void Clear() {
_freeBlocks.Clear();
}
public void DeepClear() {
_freeBlocks.Clear();
_freeBlocks.TrimExcess();
}
public int AllocatedCount {
get {
return _maxBlockNum - _freeBlocks.Count;
}
}
public int FreeCount {
get {
return _freeBlocks.Count;
}
}
public byte[] Allocate() {
if ( _freeBlocks.Count == 0 ) {
if ( _extendAble ) {
_freeBlocks.Add( new byte[_blockSize] );
_maxBlockNum = _freeBlocks.Capacity;
} else {
return null;
}
}
var last = _freeBlocks.Count - 1;
var ret = _freeBlocks[last];
_freeBlocks.RemoveAt( last );
return ret;
}
public void Free( byte[] p ) {
if ( p.Length == _blockSize ) {
_freeBlocks.Add( p );
}
}
public int GetTotalSize() {
return _freeBlocks.Capacity * _blockSize;
}
int _blockSize = 0;
int _maxBlockNum = 0;
bool _extendAble = false;
int _initMaxBlockNum = 0;
List<byte[]> _freeBlocks = null;
}
}