using System; using System.Collections; using System.Collections.Generic; using System.Linq; 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(); } } }