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 3.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. : IEnumerable<T>
  13. {
  14. private readonly int _maxSize;
  15. private readonly List<T> _storage;
  16. /// <summary>
  17. /// Number of items in this queue
  18. /// </summary>
  19. public int Count => _storage.Count;
  20. /// <summary>
  21. /// Maximum number of items allowed in this queue
  22. /// </summary>
  23. public int Capacity => _maxSize;
  24. /// <summary>
  25. /// Create a new queue
  26. /// </summary>
  27. /// <param name="size">the maximum number of items to store in this queue</param>
  28. public FixedSizeQueue(int size)
  29. {
  30. _maxSize = size;
  31. _storage = new();
  32. }
  33. /// <summary>
  34. /// Fill the quene with the data. Please ensure that data.Count &lt;= size
  35. /// </summary>
  36. /// <param name="size"></param>
  37. /// <param name="data"></param>
  38. public FixedSizeQueue(int size, IEnumerable<T> data)
  39. {
  40. #if !NETSTANDARD2_0
  41. // Try to check the size without enumerating the entire IEnumerable. This may not be able to get the count,
  42. // in which case we'll have to check later
  43. if (data.TryGetNonEnumeratedCount(out var dataCount) && dataCount > size)
  44. throw new ArgumentException($"The max size set for the quene is {size}, but got {dataCount} initial values.");
  45. #endif
  46. // Size of "data" is unknown, copy it all into a list
  47. _maxSize = size;
  48. _storage = new List<T>(data);
  49. // Now check if that list is a valid size.
  50. if (_storage.Count > _maxSize)
  51. throw new ArgumentException($"The max size set for the quene is {size}, but got {_storage.Count} initial values.");
  52. }
  53. /// <summary>
  54. /// Replace every item in the queue with the given value
  55. /// </summary>
  56. /// <param name="value">The value to replace all items with</param>
  57. /// <returns>returns this</returns>
  58. public FixedSizeQueue<T> FillWith(T value)
  59. {
  60. for(var i = 0; i < Count; i++)
  61. {
  62. _storage[i] = value;
  63. }
  64. return this;
  65. }
  66. /// <summary>
  67. /// Enquene an element.
  68. /// </summary>
  69. /// <returns></returns>
  70. public void Enqueue(T item)
  71. {
  72. _storage.Add(item);
  73. if(_storage.Count >= _maxSize)
  74. {
  75. _storage.RemoveAt(0);
  76. }
  77. }
  78. /// <inheritdoc />
  79. public IEnumerator<T> GetEnumerator()
  80. {
  81. return _storage.GetEnumerator();
  82. }
  83. /// <inheritdoc />
  84. IEnumerator IEnumerable.GetEnumerator()
  85. {
  86. return GetEnumerator();
  87. }
  88. }
  89. }