zoukankan      html  css  js  c++  java
  • C# LIFOPool 对象池

    代码
    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
    }
  • 相关阅读:
    (十一)Updating Documents
    (十)Modifying Your Data
    (九)Delete an Index
    (八)Index and Query a Document
    (七)Create an Index
    (六)List All Indices
    (五)Cluster Health
    (四)Exploring Your Cluster
    (三)Installation
    (二)Basic Concepts 基本概念
  • 原文地址:https://www.cnblogs.com/Googler/p/1752314.html
Copyright © 2011-2022 走看看