mirror of https://github.com/ogoun/Zero.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.6 KiB
108 lines
2.6 KiB
using System;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace MemoryPools.Collections.Specialized
|
|
{
|
|
public abstract class PoolingStackBase<T> : IDisposable
|
|
{
|
|
private IPoolingNode<T> _top;
|
|
private int _topIndex;
|
|
|
|
protected PoolingStackBase()
|
|
{
|
|
Count = 0;
|
|
_topIndex = 0;
|
|
_top = null!;
|
|
}
|
|
|
|
public bool IsEmpty => Count == 0;
|
|
|
|
public int Count { get; private set; }
|
|
|
|
public void Dispose()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
protected abstract IPoolingNode<T> CreateNodeHolder();
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public void Push(T obj)
|
|
{
|
|
if (Count == 0 && _top == null!)
|
|
_top = CreateNodeHolder();
|
|
|
|
_top[_topIndex] = obj;
|
|
_topIndex++;
|
|
Count++;
|
|
|
|
if (_topIndex == PoolsDefaults.DefaultPoolBucketSize)
|
|
{
|
|
var top = _top;
|
|
_top = CreateNodeHolder();
|
|
_top.Next = top;
|
|
_topIndex = 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to return queue element if any available via `val` parameter.
|
|
/// </summary>
|
|
/// <returns>
|
|
/// true if element found or false otherwise
|
|
/// </returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public bool TryPop(out T val)
|
|
{
|
|
if (IsEmpty)
|
|
{
|
|
val = default!;
|
|
return false;
|
|
}
|
|
|
|
val = Pop();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns queue element
|
|
/// </summary>
|
|
/// <returns>
|
|
/// Returns element or throws IndexOutOfRangeException if no element found
|
|
/// </returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public T Pop()
|
|
{
|
|
if (IsEmpty) throw new IndexOutOfRangeException();
|
|
|
|
_topIndex--;
|
|
|
|
if (_topIndex < 0)
|
|
{
|
|
_topIndex = PoolsDefaults.DefaultPoolBucketSize - 1;
|
|
var oldTop = _top;
|
|
_top = _top.Next;
|
|
oldTop.Dispose();
|
|
}
|
|
|
|
var obj = _top[_topIndex];
|
|
_top[_topIndex] = default!;
|
|
|
|
Count--;
|
|
|
|
return obj;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public void Clear()
|
|
{
|
|
while (_top != null!)
|
|
{
|
|
var next = _top.Next;
|
|
_top.Dispose();
|
|
_top = next;
|
|
}
|
|
}
|
|
}
|
|
} |