101 lines
2.9 KiB
C#
101 lines
2.9 KiB
C#
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Concurrent;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
namespace squirrowse.web.Common
|
|||
|
{
|
|||
|
public class ConcurrentFixedSizeQueue<T> : IProducerConsumerCollection<T>, IReadOnlyCollection<T>, ICollection
|
|||
|
{
|
|||
|
private readonly ConcurrentQueue<T> m_concurrentQueue;
|
|||
|
private readonly int m_maxSize;
|
|||
|
|
|||
|
public ConcurrentFixedSizeQueue(int maxSize) : this(Array.Empty<T>(), maxSize)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public ConcurrentFixedSizeQueue(IEnumerable<T> initialCollection, int maxSize)
|
|||
|
{
|
|||
|
if (initialCollection == null) throw new ArgumentNullException(nameof(initialCollection));
|
|||
|
|
|||
|
m_concurrentQueue = new ConcurrentQueue<T>(initialCollection);
|
|||
|
m_maxSize = maxSize;
|
|||
|
}
|
|||
|
|
|||
|
public bool IsEmpty => m_concurrentQueue.IsEmpty;
|
|||
|
|
|||
|
public int Count => m_concurrentQueue.Count;
|
|||
|
|
|||
|
public void CopyTo(T[] array, int index)
|
|||
|
{
|
|||
|
m_concurrentQueue.CopyTo(array, index);
|
|||
|
}
|
|||
|
|
|||
|
public T[] ToArray()
|
|||
|
{
|
|||
|
return m_concurrentQueue.ToArray();
|
|||
|
}
|
|||
|
|
|||
|
public IEnumerator<T> GetEnumerator()
|
|||
|
{
|
|||
|
return m_concurrentQueue.GetEnumerator();
|
|||
|
}
|
|||
|
|
|||
|
IEnumerator IEnumerable.GetEnumerator()
|
|||
|
{
|
|||
|
return GetEnumerator();
|
|||
|
}
|
|||
|
|
|||
|
// Explicit ICollection implementations.
|
|||
|
void ICollection.CopyTo(Array array, int index)
|
|||
|
{
|
|||
|
((ICollection) m_concurrentQueue).CopyTo(array, index);
|
|||
|
}
|
|||
|
|
|||
|
object ICollection.SyncRoot => ((ICollection) m_concurrentQueue).SyncRoot;
|
|||
|
bool ICollection.IsSynchronized => ((ICollection) m_concurrentQueue).IsSynchronized;
|
|||
|
|
|||
|
// Explicit IProducerConsumerCollection<T> implementations.
|
|||
|
bool IProducerConsumerCollection<T>.TryAdd(T item)
|
|||
|
{
|
|||
|
return ((IProducerConsumerCollection<T>) m_concurrentQueue).TryAdd(item);
|
|||
|
}
|
|||
|
|
|||
|
bool IProducerConsumerCollection<T>.TryTake(out T item)
|
|||
|
{
|
|||
|
return ((IProducerConsumerCollection<T>) m_concurrentQueue).TryTake(out item);
|
|||
|
}
|
|||
|
|
|||
|
public void Enqueue(T item)
|
|||
|
{
|
|||
|
m_concurrentQueue.Enqueue(item);
|
|||
|
|
|||
|
if (m_concurrentQueue.Count > m_maxSize) m_concurrentQueue.TryDequeue(out var result);
|
|||
|
}
|
|||
|
|
|||
|
public void TryPeek(out T result)
|
|||
|
{
|
|||
|
m_concurrentQueue.TryPeek(out result);
|
|||
|
}
|
|||
|
|
|||
|
public bool TryDequeue(out T result)
|
|||
|
{
|
|||
|
return m_concurrentQueue.TryDequeue(out result);
|
|||
|
}
|
|||
|
|
|||
|
public override int GetHashCode()
|
|||
|
{
|
|||
|
return m_concurrentQueue.GetHashCode();
|
|||
|
}
|
|||
|
|
|||
|
public override bool Equals(object obj)
|
|||
|
{
|
|||
|
return m_concurrentQueue.Equals(obj);
|
|||
|
}
|
|||
|
|
|||
|
public override string ToString()
|
|||
|
{
|
|||
|
return m_concurrentQueue.ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|