86 lines
2.6 KiB
C#
86 lines
2.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
|
|
namespace DTS.Common.Utilities
|
|
{
|
|
/// <summary>
|
|
/// handles averaging over a queue of values (like in realtime mode)
|
|
/// </summary>
|
|
/// <remarks>thread safe</remarks>
|
|
public class AverageQueue
|
|
{
|
|
private Queue<double> Queue { get; set; }
|
|
private readonly object _queueLock;
|
|
private int QueueLength { get; set; }
|
|
private double _queueSum;
|
|
/// <summary>
|
|
/// constructs a queue that will maintain track of the average of the contents
|
|
/// </summary>
|
|
/// <param name="length">the length of the queue, when contents exceed size,
|
|
/// the first item is dequeued
|
|
/// </param>
|
|
public AverageQueue(int length)
|
|
{
|
|
Queue = new Queue<double>(length);
|
|
QueueLength = length;
|
|
_queueLock = new object();
|
|
}
|
|
/// <summary>
|
|
/// pushes a new value into the queue
|
|
/// </summary>
|
|
/// <param name="newValue">value to be pushed onto queue</param>
|
|
/// <returns>current average</returns>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// returns current average
|
|
/// </summary>
|
|
/// <returns>current average</returns>
|
|
public double GetAverage()
|
|
{
|
|
lock (_queueLock)
|
|
{
|
|
return _queueSum / Queue.Count;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// removes all entries in the queue.
|
|
/// </summary>
|
|
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(); }
|
|
}
|
|
}
|
|
}
|