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(); }
}
}
}