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

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