C# LIFOPool 对象池

C# LIFOPool 对象池

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
     
public class LIFOPool < T > : IPool < T > , IFreeness where T : class
{
#region NestedTypes
internal struct LIFOEntry
{
public bool Idle;
public DateTime LastUpdate;
public T Value;
}
#endregion

#region StaticMembers
public const int DefaultMaxSize = 100 ;
public const int DefaultMinSize = 2 ;
public static readonly bool IsSubOfIDisposable;

static LIFOPool()
{
IsSubOfIDisposable
= typeof (T).IsSubclassOf( typeof (IDisposable));
}
#endregion

#region Fields
private WeakEvent < EventHandler > eventFull;
private LookupItem < T > lookupItem;
private ReleaseItem < T > releaseItem;
private double lifeTime;
private int minSize, maxSize, offset, freeTimeout;
private GCHandle[] weakHandle;
private LIFOEntry[] container;
private ReaderWriterLockSlim locker;
#endregion

#region Properties
public event EventHandler Full
{
add
{
if (eventFull == null )
{
Interlocked.CompareExchange
< WeakEvent < EventHandler >> ( ref eventFull, new WeakEvent < EventHandler > (), null );
}
eventFull.Add(value);
}
remove
{
if (eventFull != null )
{
eventFull.Remove(value);
}
}
}
public double LifeTime
{
set { Interlocked.Exchange( ref lifeTime, value); }
get { return lifeTime; }
}
int IFreeness.Capacity
{
get { return maxSize; }
}
public int MinSize
{
get { return minSize; }
}
public int MaxSize
{
get { return maxSize; }
}
public int Size
{
get { return offset + 1 ; }
}
public bool IsFull
{
get { return offset + 1 == maxSize; }
}
public int FreeTimeout
{
set { Interlocked.Exchange( ref freeTimeout, value); }
get { return freeTimeout; }
}
#endregion

#region Constructor
public LIFOPool(LookupItem < T > createDelegate, ReleaseItem < T > releaseDelegate)
:
this (DefaultMinSize, DefaultMaxSize, createDelegate, releaseDelegate)
{

}
public LIFOPool( int min, int max, LookupItem < T > lookupDelegate, ReleaseItem < T > releaseDelegate)
{
if (lookupDelegate ="color: #000000;">== null )
{
throw new ArgumentNullException( " Lookup delegate can't be null. " );
}
T t1
= lookupDelegate(), t2 = lookupDelegate();
if ( object .ReferenceEquals(t1, t2))
{
throw new ArgumentException( " Lookup delegate can't return the same reference object. " );
}
lookupItem
= lookupDelegate;
releaseItem
= releaseDelegate;
lifeTime
= Freer.DefaultLifeTime / 2D;
minSize
= min;
maxSize
= max;
freeTimeout
= 2000 ;
weakHandle
= new GCHandle[maxSize / 10 ];
GCHandle emptyHandle
= GCHandle.Alloc( null , GCHandleType.Weak);
for ( int i = 0 ; i < weakHandle.Length; i ++ )
{
weakHandle[i]
= emptyHandle;
}
container
= new LIFOEntry[maxSize];
container[
0 ].Idle = container[ 1 ].Idle = true ;
container[
0 ].LastUpdate = container[ 1 ].LastUpdate = DateTime.Now;
container[
0 ].Value = t1;
container[
1 ].Value = t2;
offset
++ ;
locker
= new ReaderWriterLockSlim();
}
#endregion

#region Methods
public void Store(T item)
{
if (releaseItem != null )
{
releaseItem(item);
}
locker.EnterUpgradeableReadLock();
try
{
int index = - 1 ;
for ( int i = offset; i > 0 ; i -- )
{
if (container[i].Value.Equals(item))
{
locker.EnterWriteLock();
try
{
container[i].Idle
= true ;
}
finally
{
locker.ExitWriteLock();
}
index
= i;
break ;
}
}
if (index == - 1 )
{
locker.EnterWriteLock();
try
{
if (offset + 1 == maxSize && (eventFull == null || ! eventFull.Raise( this , EventArgs.Empty)))
{
throw new PoolFullException();
}
container[offset].Idle
= true ;
container[offset].LastUpdate
= DateTime.Now;
container[offset
++ ].Value = item;
}
finally
{
locker.ExitWriteLock();
}
}
}
finally
{
locker.ExitUpgradeableReadLock();
}
}

public T Retrieve()
{
T item
= null ;
locker.EnterReadLock();
try
{
for ( int i = 0 ; i < weakHandle.Length; i ++ )
{
if (weakHandle[i].Target != null )
{
weakHandle[i].Target
= null ;
item
= (T)weakHandle[i].Target;
break ;
}
}
}
finally
{
locker.ExitReadLock();
}
if (item == null )
{
locker.EnterUpgradeableReadLock();
try
{
if (offset + 1 == maxSize && (eventFull == null || ! eventFull.Raise( this , EventArgs.Empty)))
{
throw new PoolFullException();
}
for ( int i = offset; i > 0 ; i -- )
{
if (container[i].Idle)
{
locker.EnterWriteLock();
try
{
container[i].Idle
= false ;
container[i].LastUpdate
= DateTime.Now;
}
finally
{
locker.ExitWriteLock();
}
item
= container[i].Value;
break ;
}
}
if (item == null )
{
locker.EnterWriteLock();
try
{
container[offset].Idle
= false ;
container[offset].LastUpdate
= DateTime.Now;
item
= container[offset ++ ].Value = lookupItem();
}
finally
{
locker.ExitWriteLock();
}
}
}
finally
{
locker.ExitUpgradeableReadLock();
}
}
return item;
}

public int Free()
{
int freed = 0 ;
if (lifeTime != Timeout.Infinite && offset > minSize - 1 )
{
List
< T > list = null ;
if (locker.TryEnterWriteLock(freeTimeout))
{
try
{
LIFOEntry entry;
for ( int i = 0 ; i <= offset; i ++ )
{
entry
= container[i];
if (entry.LastUpdate.AddSeconds(lifeTime).CompareTo(DateTime.Now) <= 0 )
{
if (IsSubOfIDisposable && entry.Idle)
{
if (list == null )
{
list
= new List < T > ();
}
list.Add(container[i].Value);
}
int j = i;
while (j < offset)
{
entry
= container[j];
int nextJ = ++ j;
container[j]
= container[nextJ];
container[nextJ]
= entry;
}
for (j = 0 ; j < weakHandle.Length; j ++ )
{
if (weakHandle[i].Target == null )
{
weakHandle[i].Target
= container[offset].Value;
container[offset].Value
= null ;
break ;
}
}
freed
++ ;
if (offset -- <= minSize)
{
break ;
}
}
}
}
finally
{
locker.ExitWriteLock();
}
}
if (list != null )
{
list.ForEach(item
=> ((IDisposable)item).Dispose());
}
}
return freed;
}
#endregion
}

posted on 2010-06-05 16:57 RockyLOMO 阅读(...) 评论(...) 编辑 收藏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值