Files
YouTube-Manager/Manager.App/Services/CircularBuffer.cs
2025-09-10 02:55:06 +02:00

64 lines
1.5 KiB
C#

using System.Threading.Channels;
namespace Manager.App.Services;
public class CircularBuffer <T>
{
private readonly T[] _buffer;
private readonly Channel<T> _channel;
private readonly object _lock = new();
public int Capacity { get; }
public int Head { get; private set; }
public int Count { get; private set; }
public CircularBuffer(int capacity)
{
if (capacity <= 0)
{
throw new ArgumentOutOfRangeException(nameof(capacity));
}
Capacity = capacity;
_buffer = new T[Capacity];
_channel = Channel.CreateBounded<T>(new BoundedChannelOptions(Capacity)
{
SingleReader = false,
SingleWriter = false,
FullMode = BoundedChannelFullMode.DropOldest
});
}
public void Add(T item)
{
lock (_lock)
{
_buffer[Head] = item;
Head = (Head + 1) % _buffer.Length;
if (Count < _buffer.Length)
{
Count++;
}
}
_channel.Writer.TryWrite(item);
}
public IEnumerable<T> Items
{
get
{
for (var i = 0; i < Count; i++)
{
lock (_lock)
{
yield return _buffer[(Head - Count + i + _buffer.Length) % _buffer.Length];
}
}
}
}
public IAsyncEnumerable<T> GetStreamAsync() => _channel.Reader.ReadAllAsync();
}