2010-04-10

Size Limited Queues

There are lots of times in a project when you want to have a list of the last N somethings. DotNet's System.Collections.Generic.Queue provides a FIFO mechanism. We just need to add a limiting mechanism so that the oldest entries are automatically dropped as new ones are queued. I also added the ability to add an array of objects or values to the queue.
using System;
using System.Collections.Generic;

namespace GrokkingCode.Generic {
    public class SizedQueue<T> : Queue<T> {
        private int queueLimit = 1;

        /// <summary>
        /// Gets curent queue size limit or alters limit, dumping
        /// excess entries if reduced below current size.
        /// </summary>
        public int QueueLimit {
            get {
                return queueLimit;
            }
            set {
                queueLimit = value;
                Limiter();
            }
        }

        /// <summary>
        /// Instantiate a SizedQueue (default limit is 1)
        /// </summary>
        public SizedQueue() { }

        /// <summary>
        /// Instantiate a SizedQueue (default limit is 1)
        /// </summary>
        /// <param name="QueueLimit">Queue maximum size</param>
        public SizedQueue(int QueueLimit) {
            queueLimit = QueueLimit;
        }

        /// <summary>
        /// Add item to queue
        /// </summary>
        /// <param name="item">Item to add</param>
        public new void Enqueue(T item) {
            base.Enqueue(item);
            Limiter();
        }

        /// <summary>
        /// Add item to queue
        /// </summary>
        /// <param name="items">Array of items to add</param>
        public void Enqueue(T[] items) {
            foreach (T item in items) {
                base.Enqueue(item);
            }
            Limiter();
        }

        /// <summary>
        /// Remove excess entries from queue
        /// </summary>
        private void Limiter() {
            if (this.Count > queueLimit) {
                string LockObject = "";
                lock (LockObject) {
                    while (this.Count > queueLimit) {
                        base.Dequeue();
                    }
                }
            }
        }
    }
}