Files
Nerfed/Nerfed.Runtime/Util/BoundedQueue.cs

145 lines
2.7 KiB
C#

using System.Collections;
namespace Nerfed.Runtime;
public class BoundedQueue<T> : IEnumerable<T>, ICollection, IReadOnlyCollection<T>
{
private readonly Queue<T> queue = null;
private readonly object syncLock = new object();
private readonly int maxSize = 10;
private T lastAddedElement;
public BoundedQueue(int maxSize)
{
this.maxSize = maxSize;
queue = new Queue<T>(maxSize);
}
public void Enqueue(T item)
{
Enqueue(item, out _);
}
public bool Enqueue(T item, out T evictedItem)
{
lock (syncLock)
{
queue.Enqueue(item);
if (queue.Count > maxSize)
{
evictedItem = queue.Dequeue();
lastAddedElement = item;
return true;
}
evictedItem = default;
lastAddedElement = item;
return false;
}
}
public T Dequeue()
{
lock (syncLock)
{
return queue.Dequeue();
}
}
public T Peek()
{
lock (syncLock)
{
return queue.Peek();
}
}
public T LastAddedElement()
{
lock (syncLock)
{
return lastAddedElement;
}
}
public void Clear()
{
lock (syncLock)
{
queue.Clear();
}
}
public bool Contains(T item)
{
lock (syncLock)
{
return queue.Contains(item);
}
}
// Iterates the internal Queue<T> directly (struct enumerator, no allocation) under the lock.
public int CopyTo(List<T> destination)
{
lock (syncLock)
{
destination.Clear();
foreach (T item in queue)
{
destination.Add(item);
}
return destination.Count;
}
}
public IEnumerator<T> GetEnumerator()
{
T[] snapshot;
lock (syncLock)
{
snapshot = queue.ToArray();
}
return ((IEnumerable<T>)snapshot).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void CopyTo(Array array, int index)
{
lock (syncLock)
{
((ICollection)queue).CopyTo(array, index);
}
}
public int Count
{
get
{
lock (syncLock)
{
return queue.Count;
}
}
}
public int Capacity => maxSize;
public bool IsSynchronized => true;
public object SyncRoot => syncLock;
int IReadOnlyCollection<T>.Count
{
get
{
lock (syncLock)
{
return queue.Count;
}
}
}
}