using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using LLama.Extensions;
namespace LLama.Common
{
///
/// A queue with fixed storage size.
/// Currently it's only a naive implementation and needs to be further optimized in the future.
///
public class FixedSizeQueue
: IReadOnlyList
{
private readonly List _storage;
///
public T this[int index] => _storage[index];
///
/// Number of items in this queue
///
public int Count => _storage.Count;
///
/// Maximum number of items allowed in this queue
///
public int Capacity { get; }
///
/// Create a new queue
///
/// the maximum number of items to store in this queue
public FixedSizeQueue(int size)
{
Capacity = size;
_storage = new();
}
///
/// Fill the quene with the data. Please ensure that data.Count <= size
///
///
///
public FixedSizeQueue(int size, IEnumerable data)
{
#if NET6_0_OR_GREATER
// Try to check the size without enumerating the entire IEnumerable. This may not be able to get the count,
// in which case we'll have to check later
if (data.TryGetNonEnumeratedCount(out var dataCount) && dataCount > size)
throw new ArgumentException($"The max size set for the quene is {size}, but got {dataCount} initial values.");
#endif
// Size of "data" is unknown, copy it all into a list
Capacity = size;
_storage = new List(data);
// Now check if that list is a valid size.
if (_storage.Count > Capacity)
throw new ArgumentException($"The max size set for the quene is {size}, but got {_storage.Count} initial values.");
}
///
/// Enquene an element.
///
///
public void Enqueue(T item)
{
_storage.Add(item);
if (_storage.Count > Capacity)
_storage.RemoveAt(0);
}
///
public IEnumerator GetEnumerator()
{
return _storage.GetEnumerator();
}
///
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}