2023-05-10 13:50:04 +00:00
|
|
|
# Copyright (c) 2021-2023 Status Research & Development GmbH
|
2021-12-09 09:52:21 +00:00
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2023-05-10 13:50:04 +00:00
|
|
|
{.push raises: [].}
|
2021-12-09 09:52:21 +00:00
|
|
|
|
2021-12-20 12:14:50 +00:00
|
|
|
import
|
2021-12-09 09:52:21 +00:00
|
|
|
chronos,
|
|
|
|
./utp_utils
|
|
|
|
|
|
|
|
const
|
|
|
|
currentDelaySize = 3
|
|
|
|
delayBaseHistory = 13
|
|
|
|
delayBaseUpdateInterval = minutes(1)
|
|
|
|
|
|
|
|
type
|
|
|
|
DelayHistogram* = object
|
|
|
|
delayBase*: uint32
|
|
|
|
currentDelayHistory: array[currentDelaySize, uint32]
|
2022-11-16 16:44:00 +00:00
|
|
|
currentDelayIdx: int
|
2021-12-09 09:52:21 +00:00
|
|
|
delayBaseHistory: array[delayBaseHistory, uint32]
|
|
|
|
delayBaseIdx: int
|
|
|
|
delayBaseTime: Moment
|
|
|
|
|
|
|
|
proc init*(T: type DelayHistogram, currentTime: Moment): T =
|
|
|
|
DelayHistogram(
|
|
|
|
delayBaseTime: currentTime
|
|
|
|
)
|
|
|
|
|
|
|
|
proc shift*(h: var DelayHistogram, offset: uint32) =
|
|
|
|
for sample in h.delayBaseHistory.mitems():
|
|
|
|
sample = sample + offset
|
|
|
|
h.delayBase = h.delayBase + offset
|
|
|
|
|
|
|
|
proc addSample*(h: var DelayHistogram, sample: uint32, currentTime: Moment) =
|
|
|
|
# if delay base is zero it means it is our first sample. Initialize necessary parts
|
|
|
|
if h.delayBase == 0:
|
|
|
|
h.delayBase = sample
|
|
|
|
for i in h.delayBaseHistory.mitems():
|
|
|
|
i = sample
|
|
|
|
|
|
|
|
if wrapCompareLess(sample, h.delayBaseHistory[h.delayBaseIdx]):
|
|
|
|
h.delayBaseHistory[h.delayBaseIdx] = sample
|
|
|
|
|
|
|
|
if wrapCompareLess(sample, h.delayBase):
|
2021-12-20 12:14:50 +00:00
|
|
|
h.delayBase = sample
|
|
|
|
|
2021-12-09 09:52:21 +00:00
|
|
|
let delay = sample - h.delayBase
|
|
|
|
|
2022-11-16 16:44:00 +00:00
|
|
|
h.currentDelayHistory[h.currentDelayIdx] = delay
|
|
|
|
h.currentDelayIdx = (h.currentDelayIdx + 1) mod currentDelaySize
|
2021-12-09 09:52:21 +00:00
|
|
|
|
|
|
|
if (currentTime - h.delayBaseTime > delayBaseUpdateInterval):
|
|
|
|
h.delayBaseTime = currentTime
|
|
|
|
h.delayBaseIdx = (h.delayBaseIdx + 1) mod delayBaseHistory
|
|
|
|
h.delayBaseHistory[h.delayBaseIdx] = sample
|
|
|
|
h.delayBase = h.delayBaseHistory[0]
|
|
|
|
|
|
|
|
for delaySample in h.delayBaseHistory.items():
|
|
|
|
if (wrapCompareLess(delaySample, h.delayBase)):
|
|
|
|
h.delayBase = delaySample
|
|
|
|
|
|
|
|
proc getValue*(h: DelayHistogram): Duration =
|
|
|
|
var value = uint32.high
|
2022-11-16 16:44:00 +00:00
|
|
|
# this will return zero if not all samples are collected
|
2021-12-09 09:52:21 +00:00
|
|
|
for sample in h.currentDelayHistory:
|
|
|
|
value = min(sample, value)
|
|
|
|
|
|
|
|
microseconds(value)
|