41 lines
1.1 KiB
C#
41 lines
1.1 KiB
C#
|
namespace DispenserCommon.Utils;
|
||
|
|
||
|
/// <summary>
|
||
|
/// 基于滑动时间窗口算法来判断指定时间窗口内是否存在目标值
|
||
|
/// </summary>
|
||
|
public class SlidingWindow(int milliseconds, int thresold = 1)
|
||
|
{
|
||
|
private readonly Queue<(DateTime time, object value)> _window = new();
|
||
|
private readonly TimeSpan _windowSize = TimeSpan.FromMilliseconds(milliseconds);
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// 添加值
|
||
|
/// </summary>
|
||
|
/// <param name="value">待添加值</param>
|
||
|
public bool AllowValue(object value)
|
||
|
{
|
||
|
var currentTime = DateTime.Now;
|
||
|
|
||
|
while (_window.Count > 0 && currentTime - _window.Peek().time > _windowSize) _window.Dequeue();
|
||
|
|
||
|
if (_window.Count < thresold)
|
||
|
{
|
||
|
_window.Enqueue((currentTime, value));
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// 判断是否已经包含了该值
|
||
|
/// </summary>
|
||
|
/// <param name="targetValue">待匹配值</param>
|
||
|
/// <returns></returns>
|
||
|
public bool Contains(object targetValue)
|
||
|
{
|
||
|
return _window.Any(item => item.value.Equals(targetValue));
|
||
|
}
|
||
|
}
|