83 lines
2.2 KiB
C#
83 lines
2.2 KiB
C#
using Pcie8586Probe.Models;
|
|
|
|
namespace Pcie8586Probe.Acquisition;
|
|
|
|
public sealed class RingHistoryBuffer
|
|
{
|
|
private readonly object _gate = new();
|
|
private readonly Queue<SampleBlock> _blocks = new();
|
|
private readonly long _maxSamplesPerChannel;
|
|
private long _samplesPerChannel;
|
|
|
|
public RingHistoryBuffer(double sampleRateHz, double seconds, int maxBytes = 500 * 1024 * 1024)
|
|
{
|
|
if (sampleRateHz <= 0) throw new ArgumentOutOfRangeException(nameof(sampleRateHz));
|
|
if (seconds <= 0) throw new ArgumentOutOfRangeException(nameof(seconds));
|
|
|
|
var requested = (long)Math.Ceiling(sampleRateHz * seconds);
|
|
var memoryBound = Math.Max(1, maxBytes / (8L * 8L));
|
|
_maxSamplesPerChannel = Math.Max(1, Math.Min(requested, memoryBound));
|
|
}
|
|
|
|
public long SamplesPerChannel
|
|
{
|
|
get
|
|
{
|
|
lock (_gate)
|
|
{
|
|
return _samplesPerChannel;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Add(SampleBlock block)
|
|
{
|
|
if (block.SamplesPerChannel == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lock (_gate)
|
|
{
|
|
_blocks.Enqueue(block);
|
|
_samplesPerChannel += block.SamplesPerChannel;
|
|
|
|
while (_samplesPerChannel > _maxSamplesPerChannel && _blocks.Count > 0)
|
|
{
|
|
var removed = _blocks.Dequeue();
|
|
_samplesPerChannel -= removed.SamplesPerChannel;
|
|
}
|
|
}
|
|
}
|
|
|
|
public SampleBlock? Snapshot()
|
|
{
|
|
lock (_gate)
|
|
{
|
|
if (_blocks.Count == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return SampleBlockAssembler.Concat(_blocks);
|
|
}
|
|
}
|
|
|
|
public SampleBlock? Slice(long startInclusive, long endExclusive)
|
|
{
|
|
if (startInclusive < 0 || endExclusive <= startInclusive)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var snapshot = Snapshot();
|
|
if (snapshot is null || startInclusive >= snapshot.SamplesPerChannel)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var end = Math.Min(endExclusive, snapshot.SamplesPerChannel);
|
|
return SampleBlockAssembler.Slice(snapshot, (int)startInclusive, (int)(end - startInclusive));
|
|
}
|
|
}
|