using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace DTS.Common.Utilities { /// /// handles averaging over a queue of values (like in realtime mode) /// /// thread safe public class AverageQueue { private Queue Queue { get; set; } private readonly object _queueLock; private int QueueLength { get; set; } private double _queueSum; /// /// constructs a queue that will maintain track of the average of the contents /// /// the length of the queue, when contents exceed size, /// the first item is dequeued /// public AverageQueue(int length) { Queue = new Queue(length); QueueLength = length; _queueLock = new object(); } /// /// pushes a new value into the queue /// /// value to be pushed onto queue /// current average public double Push(double newValue) { lock (_queueLock) { // enqueue the new value Queue.Enqueue(newValue); // add it to the sum _queueSum += newValue; if (Queue.Count > QueueLength) { // we have a full queue, remove the oldest var discard = Queue.Dequeue(); // subtract it from sum _queueSum -= discard; } // return the average of the queue return _queueSum / Queue.Count; } } /// /// returns current average /// /// current average public double GetAverage() { lock (_queueLock) { return _queueSum / Queue.Count; } } /// /// removes all entries in the queue. /// public void Reset() { lock (_queueLock) { Queue.Clear(); _queueSum = 0; } } public double GetMin() { lock (_queueLock) { return Queue.Min(); } } public double GetMax() { lock (_queueLock) { return Queue.Max(); } } } }