您的位置:首页 > 移动开发 > Objective-C

自己写的ObjectPool类谨供参考学习。。。

2011-03-11 14:55 218 查看
#region Delegate
public delegate T LookupItem<T>();
public delegate void ReleaseItem<T>(T item);
#endregion

#region ObjectPool
public class ObjectPool<T> : IPool<T>, IFreeness where T : class
{
#region NestedTypes
internal struct LIFOEntry
{
public bool Idle;
public DateTime CreateTime;
public T Value;
}
#endregion

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

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

#region Fields
private WeakEvent<EventHandler> eventFull;
private LookupItem<T> lookupItem;
private ReleaseItem<T> releaseItem;
private TimeSpan 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(ref eventFull, new WeakEvent<EventHandler>(), null);
}
eventFull.Add(value);
}
remove
{
if (eventFull != null)
{
eventFull.Remove(value);
}
}
}
public TimeSpan LifeTime
{
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 ObjectPool(LookupItem<T> createDelegate, ReleaseItem<T> releaseDelegate, TimeSpan timeout)
: this(createDelegate, releaseDelegate, Freer.LifeTime, DefaultMinSize, DefaultMaxSize)
{

}
public ObjectPool(LookupItem<T> lookupDelegate, ReleaseItem<T> releaseDelegate, TimeSpan timeout, int min, int max)
{
AppDiag.GuardArgument(lookupDelegate, "lookupDelegate");
T t1 = lookupDelegate(), t2 = lookupDelegate();
AppDiag.GuardArgument(object.ReferenceEquals(t1, t2), "Lookup delegate can't return the same reference object.");
lookupItem = lookupDelegate;
releaseItem = releaseDelegate;
lifeTime = timeout;
AppDiag.GuardArgument(min < 0, "The min size must > -1.");
AppDiag.GuardArgument(max < 2, "The max size must > 1.");
minSize = min;
maxSize = max;
freeTimeout = 2000;
weakHandle = new GCHandle[max / 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].CreateTime = container[1].CreateTime = DateTime.UtcNow;
container[0].Value = t1;
container[1].Value = t2;
offset++;
locker = new ReaderWriterLockSlim();
Freer.Instance.Add(this);
}
#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].CreateTime = DateTime.UtcNow;
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)
{
item = (T)weakHandle[i].Target;
weakHandle[i].Target = null;
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;
}
finally
{
locker.ExitWriteLock();
}
item = container[i].Value;
break;
}
}
if (item == null)
{
locker.EnterWriteLock();
try
{
container[offset].Idle = false;
container[offset].CreateTime = DateTime.UtcNow;
item = container[offset++].Value = lookupItem();
}
finally
{
locker.ExitWriteLock();
}
}
}
finally
{
locker.ExitUpgradeableReadLock();
}
}
return item;
}

public int Free()
{
int freed = 0;
if (lifeTime != TimeSpan.Zero && offset > minSize - 1)
{
if (locker.TryEnterWriteLock(freeTimeout))
{
try
{
LIFOEntry entry;
if (IsSubOfIDisposable)
{
List<T> list = new List<T>();
for (int i = 0; i <= offset; i++)
{
entry = container[i];
if (DateTime.UtcNow - entry.CreateTime >= lifeTime)
{
if (entry.Idle)
{
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;
}
}
}
list.ForEach(item => ((IDisposable)item).Dispose());
}
else
{
for (int i = 0; i <= offset; i++)
{
entry = container[i];
if (DateTime.UtcNow - entry.CreateTime >= lifeTime)
{
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();
}
}
}
return freed;
}
#endregion
}
#endregion

#region PoolFullException
public class PoolFullException : Exception
{
public PoolFullException()
: base("Object Pool is Full.")
{

}
public PoolFullException(string msg)
: base(msg)
{

}
}
#endregion
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐