Limit <T> Queue Size in .NET?
I have a Queue <T> object that I initialized to 2, but obviously this is just capacity, and it continues to expand as elements are added. Is there an object that automatically deletes an element when it reaches the limit, or is the best solution for creating your own inherited class?
I hit the basic version of what I'm looking for, this is not perfect, but it will do the job until something better appears.
public class LimitedQueue<T> : Queue<T> { public int Limit { get; set; } public LimitedQueue(int limit) : base(limit) { Limit = limit; } public new void Enqueue(T item) { while (Count >= Limit) { Dequeue(); } base.Enqueue(item); } } I would recommend you pick up the C5 Library . Unlike SCG (System.Collections.Generic), C5 is programmed for the interface and is intended for subclassing. Most public methods are virtual, and none of the classes are private. This way, you won’t need to use this ridiculous “new” keyword, which will not work if your LimitedQueue<T> been added to SCG.Queue<T> . With C5 and using the same codes as before, you should get from CircularQueue<T> . CircularQueue<T> actually implements both the stack and the queue, so you can get both options with a restriction almost for free. I rewrote it below with 3.5 constructs:
using C5; public class LimitedQueue<T> : CircularQueue<T> { public int Limit { get; set; } public LimitedQueue(int limit) : base(limit) { this.Limit = limit; } public override void Push(T item) { CheckLimit(false); base.Push(item); } public override void Enqueue(T item) { CheckLimit(true); base.Enqueue(item); } protected virtual void CheckLimit(bool enqueue) { while (this.Count >= this.Limit) { if (enqueue) { this.Dequeue(); } else { this.Pop(); } } } } I think this code should do exactly what you were looking for.
You should create your own class, a ringbuffer would probably fit your needs.
.NET data structures that allow you to specify capacity, with the exception of the array, use this to build the internal data structure used to store internal data.
For example, for a list, capacity is used to measure the internal array. When you start adding items to the list, it will begin to fill this array from index 0 and above, and when it reaches your capacity, it will increase the capacity to a new higher capacity and continue to fill it.
Why don't you just use an array of size 2? It is assumed that the queue should dynamically grow and shrink.
Or create a wrapper class around an instance of Queue<T> , and each time it circles the <T> object, check the size of the queue. If greater than 2, delete the first item.
Ok, hope this class helps you:
Inside the circular FIFO buffer, the Queue <T> queue with the specified size is used. Once the buffer size is reached, it will replace the old elements with new ones.
NOTE. You cannot delete items randomly. I set the Remove (T item) method to return false. if you want to. You can change the random deletion of items.
public class CircularFIFO<T> : ICollection<T> , IDisposable { public Queue<T> CircularBuffer; /// <summary> /// The default initial capacity. /// </summary> private int capacity = 32; /// <summary> /// Gets the actual capacity of the FIFO. /// </summary> public int Capacity { get { return capacity; } } /// <summary> /// Initialize a new instance of FIFO class that is empty and has the default initial capacity. /// </summary> public CircularFIFO() { CircularBuffer = new Queue<T>(); } /// <summary> /// Initialize a new instance of FIFO class that is empty and has the specified initial capacity. /// </summary> /// <param name="size"> Initial capacity of the FIFO. </param> public CircularFIFO(int size) { capacity = size; CircularBuffer = new Queue<T>(capacity); } /// <summary> /// Adds an item to the end of the FIFO. /// </summary> /// <param name="item"> The item to add to the end of the FIFO. </param> public void Add(T item) { if (this.Count >= this.Capacity) Remove(); CircularBuffer.Enqueue(item); } /// <summary> /// Adds array of items to the end of the FIFO. /// </summary> /// <param name="item"> The array of items to add to the end of the FIFO. </param> public void Add(T[] item) { int enqueuedSize = 0; int remainEnqueueSize = this.Capacity - this.Count; for (; (enqueuedSize < item.Length && enqueuedSize < remainEnqueueSize); enqueuedSize++) CircularBuffer.Enqueue(item[enqueuedSize]); if ((item.Length - enqueuedSize) != 0) { Remove((item.Length - enqueuedSize));//remaining item size for (; enqueuedSize < item.Length; enqueuedSize++) CircularBuffer.Enqueue(item[enqueuedSize]); } } /// <summary> /// Removes and Returns an item from the FIFO. /// </summary> /// <returns> Item removed. </returns> public T Remove() { T removedItem = CircularBuffer.Peek(); CircularBuffer.Dequeue(); return removedItem; } /// <summary> /// Removes and Returns the array of items form the FIFO. /// </summary> /// <param name="size"> The size of item to be removed from the FIFO. </param> /// <returns> Removed array of items </returns> public T[] Remove(int size) { if (size > CircularBuffer.Count) size = CircularBuffer.Count; T[] removedItems = new T[size]; for (int i = 0; i < size; i++) { removedItems[i] = CircularBuffer.Peek(); CircularBuffer.Dequeue(); } return removedItems; } /// <summary> /// Returns the item at the beginning of the FIFO with out removing it. /// </summary> /// <returns> Item Peeked. </returns> public T Peek() { return CircularBuffer.Peek(); } /// <summary> /// Returns the array of item at the beginning of the FIFO with out removing it. /// </summary> /// <param name="size"> The size of the array items. </param> /// <returns> Array of peeked items. </returns> public T[] Peek(int size) { T[] arrayItems = new T[CircularBuffer.Count]; CircularBuffer.CopyTo(arrayItems, 0); if (size > CircularBuffer.Count) size = CircularBuffer.Count; T[] peekedItems = new T[size]; Array.Copy(arrayItems, 0, peekedItems, 0, size); return peekedItems; } /// <summary> /// Gets the actual number of items presented in the FIFO. /// </summary> public int Count { get { return CircularBuffer.Count; } } /// <summary> /// Removes all the contents of the FIFO. /// </summary> public void Clear() { CircularBuffer.Clear(); } /// <summary> /// Resets and Initialize the instance of FIFO class that is empty and has the default initial capacity. /// </summary> public void Reset() { Dispose(); CircularBuffer = new Queue<T>(capacity); } #region ICollection<T> Members /// <summary> /// Determines whether an element is in the FIFO. /// </summary> /// <param name="item"> The item to locate in the FIFO. </param> /// <returns></returns> public bool Contains(T item) { return CircularBuffer.Contains(item); } /// <summary> /// Copies the FIFO elements to an existing one-dimensional array. /// </summary> /// <param name="array"> The one-dimensional array that have at list a size of the FIFO </param> /// <param name="arrayIndex"></param> public void CopyTo(T[] array, int arrayIndex) { if (array.Length >= CircularBuffer.Count) CircularBuffer.CopyTo(array, 0); } public bool IsReadOnly { get { return false; } } public bool Remove(T item) { return false; } #endregion #region IEnumerable<T> Members public IEnumerator<T> GetEnumerator() { return CircularBuffer.GetEnumerator(); } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return CircularBuffer.GetEnumerator(); } #endregion #region IDisposable Members /// <summary> /// Releases all the resource used by the FIFO. /// </summary> public void Dispose() { CircularBuffer.Clear(); CircularBuffer = null; GC.Collect(); } #endregion } If it is to anyone, I made LimitedStack<T> .
public class LimitedStack<T> { public readonly int Limit; private readonly List<T> _stack; public LimitedStack(int limit = 32) { Limit = limit; _stack = new List<T>(limit); } public void Push(T item) { if (_stack.Count == Limit) _stack.RemoveAt(0); _stack.Add(item); } public T Peek() { return _stack[_stack.Count - 1]; } public void Pop() { _stack.RemoveAt(_stack.Count - 1); } public int Count { get { return _stack.Count; } } } It removes the oldest element (bottom of the stack) when it gets too big.
(This question was Google's best result for "C # stack size")