/// <summary> /// Tries to get one item from the pool. /// </summary> /// <param name="item">The item.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> public bool TryGet(out T item) { if (m_globalStack.TryPop(out item)) { return(true); } var currentSourceCount = m_currentSourceCount; if (currentSourceCount >= m_itemsSource.Length) { return(false); } if (Interlocked.CompareExchange(ref m_currentSourceCount, currentSourceCount + 1, currentSourceCount) != currentSourceCount) { var spinWait = new SpinWait(); while (true) { spinWait.SpinOnce(); if (m_globalStack.TryPop(out item)) { return(true); } if (spinWait.Count >= 100) { return(false); } } } int totalItemsCount = 0; for (var i = 0; i < currentSourceCount; i++) { totalItemsCount += m_itemsSource[i].Count; } totalItemsCount = Math.Min(totalItemsCount, m_maxPoolSize - totalItemsCount); T[] items; m_itemsSource[currentSourceCount] = m_sourceCreator.Create(totalItemsCount, out items); foreach (T t in items) { m_globalStack.Push(t); } return(m_globalStack.TryPop(out item)); }
private void IncreaseCapacity() { var newItemsCount = Math.Min(m_TotalItemsCount, m_MaxPoolSize - m_TotalItemsCount); m_ItemsSource[m_CurrentSourceCount++] = m_SourceCreator.Create(newItemsCount, out T[] items); m_TotalItemsCount += newItemsCount; for (var i = 0; i < items.Length; i++) { m_GlobalStack.Push(items[i]); } }
/// <summary> /// Initializes the specified min and max pool size. /// </summary> /// <param name="minPoolSize">The min size of the pool.</param> /// <param name="maxPoolSize">The max size of the pool.</param> /// <param name="sourceCreator">The source creator.</param> public void Initialize(int minPoolSize, int maxPoolSize, ISmartPoolSourceCreator <T> sourceCreator) { m_MinPoolSize = minPoolSize; m_MaxPoolSize = maxPoolSize; m_SourceCreator = sourceCreator; m_GlobalStack = new ConcurrentStack <T>(); var n = 0; if (minPoolSize != maxPoolSize) { var currentValue = minPoolSize; while (true) { n++; var thisValue = currentValue * 2; if (thisValue >= maxPoolSize) { break; } currentValue = thisValue; } } m_ItemsSource = new ISmartPoolSource[n + 1]; T[] items; m_ItemsSource[0] = sourceCreator.Create(minPoolSize, out items); m_CurrentSourceCount = 1; for (var i = 0; i < items.Length; i++) { m_GlobalStack.Push(items[i]); } m_TotalItemsCount = m_MinPoolSize; }
/// <summary> /// Initializes the specified min and max pool size. /// </summary> /// <param name="minPoolSize">The min size of the pool.</param> /// <param name="maxPoolSize">The max size of the pool.</param> /// <param name="sourceCreator">The source creator.</param> public void Initialize(int minPoolSize, int maxPoolSize, ISmartPoolSourceCreator <T> sourceCreator) { m_minPoolSize = minPoolSize; m_maxPoolSize = maxPoolSize; m_sourceCreator = sourceCreator; m_globalStack = new ConcurrentStack <T>(); var n = 0; if (minPoolSize != maxPoolSize) { var currentValue = minPoolSize; while (true) { n++; var thisValue = currentValue * 2; if (thisValue >= maxPoolSize) { break; } currentValue = thisValue; } } m_itemsSource = new ISmartPoolSource[n + 1]; T[] items; m_itemsSource[0] = sourceCreator.Create(minPoolSize, out items); m_currentSourceCount = 1; foreach (T t in items) { m_globalStack.Push(t); } }