You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

FixedSizeQueue.cs 2.7 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace LLama.Common
  6. {
  7. /// <summary>
  8. /// A queue with fixed storage size.
  9. /// Currently it's only a naive implementation and needs to be further optimized in the future.
  10. /// </summary>
  11. public class FixedSizeQueue<T>
  12. : IReadOnlyList<T>
  13. {
  14. private readonly List<T> _storage;
  15. /// <inheritdoc />
  16. public T this[int index] => _storage[index];
  17. /// <summary>
  18. /// Number of items in this queue
  19. /// </summary>
  20. public int Count => _storage.Count;
  21. /// <summary>
  22. /// Maximum number of items allowed in this queue
  23. /// </summary>
  24. public int Capacity { get; }
  25. /// <summary>
  26. /// Create a new queue
  27. /// </summary>
  28. /// <param name="size">the maximum number of items to store in this queue</param>
  29. public FixedSizeQueue(int size)
  30. {
  31. Capacity = size;
  32. _storage = new();
  33. }
  34. /// <summary>
  35. /// Fill the quene with the data. Please ensure that data.Count &lt;= size
  36. /// </summary>
  37. /// <param name="size"></param>
  38. /// <param name="data"></param>
  39. public FixedSizeQueue(int size, IEnumerable<T> data)
  40. {
  41. #if NET6_0_OR_GREATER
  42. // Try to check the size without enumerating the entire IEnumerable. This may not be able to get the count,
  43. // in which case we'll have to check later
  44. if (data.TryGetNonEnumeratedCount(out var dataCount) && dataCount > size)
  45. throw new ArgumentException($"The max size set for the quene is {size}, but got {dataCount} initial values.");
  46. #endif
  47. // Size of "data" is unknown, copy it all into a list
  48. Capacity = size;
  49. _storage = new List<T>(data);
  50. // Now check if that list is a valid size.
  51. if (_storage.Count > Capacity)
  52. throw new ArgumentException($"The max size set for the quene is {size}, but got {_storage.Count} initial values.");
  53. }
  54. /// <summary>
  55. /// Enquene an element.
  56. /// </summary>
  57. /// <returns></returns>
  58. public void Enqueue(T item)
  59. {
  60. _storage.Add(item);
  61. if (_storage.Count > Capacity)
  62. _storage.RemoveAt(0);
  63. }
  64. /// <inheritdoc />
  65. public IEnumerator<T> GetEnumerator()
  66. {
  67. return _storage.GetEnumerator();
  68. }
  69. /// <inheritdoc />
  70. IEnumerator IEnumerable.GetEnumerator()
  71. {
  72. return GetEnumerator();
  73. }
  74. }
  75. }