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 : IEnumerable { private readonly int _maxSize; private readonly List _storage; public int Count => _storage.Count; public int Capacity => _maxSize; public FixedSizeQueue(int size) { _maxSize = size; _storage = new(); } /// /// Fill the quene with the data. Please ensure that data.Count <= size /// /// /// public FixedSizeQueue(int size, IEnumerable data) { #if !NETSTANDARD2_0 // 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 _maxSize = size; _storage = new List(data); // Now check if that list is a valid size. if (_storage.Count > _maxSize) throw new ArgumentException($"The max size set for the quene is {size}, but got {_storage.Count} initial values."); } /// /// Replace every item in the queue with the given value /// /// The value to replace all items with /// returns this public FixedSizeQueue FillWith(T value) { for(var i = 0; i < Count; i++) { _storage[i] = value; } return this; } /// /// Enquene an element. /// /// public void Enqueue(T item) { _storage.Add(item); if(_storage.Count >= _maxSize) { _storage.RemoveAt(0); } } /// public IEnumerator GetEnumerator() { return _storage.GetEnumerator(); } /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }