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.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. namespace LLama.Common
  7. {
  8. /// <summary>
  9. /// A queue with fixed storage size.
  10. /// Currently it's only a naive implementation and needs to be further optimized in the future.
  11. /// </summary>
  12. public class FixedSizeQueue<T>: IEnumerable<T>
  13. {
  14. int _maxSize;
  15. List<T> _storage;
  16. public int Count => _storage.Count;
  17. public int Capacity => _maxSize;
  18. public FixedSizeQueue(int size)
  19. {
  20. _maxSize = size;
  21. _storage = new();
  22. }
  23. /// <summary>
  24. /// Fill the quene with the data. Please ensure that data.Count &lt;= size
  25. /// </summary>
  26. /// <param name="size"></param>
  27. /// <param name="data"></param>
  28. public FixedSizeQueue(int size, IEnumerable<T> data)
  29. {
  30. #if NETCOREAPP3_0_OR_GREATER
  31. // Try an early check on the amount of data supplied (if possible)
  32. #if NETSTANDARD2_0
  33. var dataCount = data.Count();
  34. if (data.Count() > size)
  35. throw new ArgumentException($"The max size set for the quene is {size}, but got {dataCount} initial values.");
  36. #else
  37. if (data.TryGetNonEnumeratedCount(out var count) && count > size)
  38. throw new ArgumentException($"The max size set for the quene is {size}, but got {count} initial values.");
  39. #endif
  40. // Size of "data" is unknown, copy it all into a list
  41. _maxSize = size;
  42. _storage = new List<T>(data);
  43. // Now check if that list is a valid size
  44. if (_storage.Count > _maxSize)
  45. #if NETSTANDARD2_0
  46. throw new ArgumentException($"The max size set for the quene is {size}, but got {dataCount} initial values.");
  47. #else
  48. throw new ArgumentException($"The max size set for the quene is {size}, but got {count} initial values.");
  49. #endif
  50. }
  51. /
  52. /// <summary>
  53. /// Replace every item in the queue with the given value
  54. /// </summary>
  55. /// <param name="value">The value to replace all items with</param>
  56. /// <returns>returns this</returns>
  57. public FixedSizeQueue<T> FillWith(T value)
  58. {
  59. for(int i = 0; i < Count; i++)
  60. {
  61. _storage[i] = value;
  62. }
  63. return this;
  64. }
  65. /// <summary>
  66. /// Enquene an element.
  67. /// </summary>
  68. /// <returns></returns>
  69. public void Enqueue(T item)
  70. {
  71. _storage.Add(item);
  72. if(_storage.Count >= _maxSize)
  73. {
  74. _storage.RemoveAt(0);
  75. }
  76. }
  77. public T[] ToArray()
  78. {
  79. return _storage.ToArray();
  80. }
  81. public IEnumerator<T> GetEnumerator()
  82. {
  83. return _storage.GetEnumerator();
  84. }
  85. IEnumerator IEnumerable.GetEnumerator()
  86. {
  87. return GetEnumerator();
  88. }
  89. }
  90. }