115 lines
2.8 KiB
C#
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|