Restructure stats into delta, mask, and aggregate layers
This commit is contained in:
+35
-41
@@ -5,11 +5,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// The panel's recent-history ring: 18 slots of 5 seconds, sampled every drawn
|
||||
// frame from the same figures the panel paints, so a slot has data within one
|
||||
// frame of being born. Slots are wall-time and survive a reset — recently is
|
||||
// recently, whatever the counters were re-based to — while the since-reset
|
||||
// aggregates and fault ages clear.
|
||||
// The panel's recent-history ring: 18 slots of 5 seconds. Fault and corrected
|
||||
// deltas arrive straight from the layers below the moment they clear the mask,
|
||||
// and the per-frame judgments — measure state, rate, SNR — from the draw loop,
|
||||
// so a slot has data within one tick of being born. Slots are wall-time and
|
||||
// survive a reset — recently is recently, whatever the aggregates were
|
||||
// re-based to — while the fault ages and since-reset extremes clear.
|
||||
const (
|
||||
histSlots = 18
|
||||
histSlotSpan = 5 * time.Second
|
||||
@@ -47,10 +48,6 @@ type history struct {
|
||||
start time.Time
|
||||
slots [histSlots]histSlot
|
||||
|
||||
prevValid bool
|
||||
prevSince errs
|
||||
prevCorrected uint64
|
||||
|
||||
lastFault [4]time.Time
|
||||
sinceRateLow bool
|
||||
sinceHaveSNR bool
|
||||
@@ -69,15 +66,27 @@ func (h *history) slot(seq int64) *histSlot {
|
||||
return s
|
||||
}
|
||||
|
||||
// Counters only move forward between samples except across a reset, where
|
||||
// they re-base to zero; a backward step is that re-base, not negative faults.
|
||||
func delta(now, prev uint64) uint64 {
|
||||
if now < prev {
|
||||
return 0
|
||||
// Bucketing sits above the mask: only fault deltas that survived it arrive
|
||||
// here, already flattened, so a slot is a plain sum.
|
||||
func (h *history) addFaults(now time.Time, e errs) {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
s := h.slot(int64(now.Sub(h.start) / histSlotSpan))
|
||||
for i, c := range faultClasses {
|
||||
if d := c.get(e); d > 0 {
|
||||
s.faults[i] += d
|
||||
h.lastFault[i] = now
|
||||
}
|
||||
}
|
||||
return now - prev
|
||||
}
|
||||
|
||||
func (h *history) addCorrected(now time.Time, d uint64) {
|
||||
h.mu.Lock()
|
||||
h.slot(int64(now.Sub(h.start)/histSlotSpan)).corrected += d
|
||||
h.mu.Unlock()
|
||||
}
|
||||
|
||||
// The per-frame judgments, from the same figures the panel paints.
|
||||
func (h *history) sample(now time.Time, v view, phy phyDisplay,
|
||||
measuring bool, target float64) {
|
||||
h.mu.Lock()
|
||||
@@ -85,34 +94,20 @@ func (h *history) sample(now time.Time, v view, phy phyDisplay,
|
||||
|
||||
s := h.slot(int64(now.Sub(h.start) / histSlotSpan))
|
||||
|
||||
if h.prevValid {
|
||||
for i, c := range faultClasses {
|
||||
d := delta(c.get(v.since), c.get(h.prevSince))
|
||||
s.faults[i] += d
|
||||
if d > 0 {
|
||||
h.lastFault[i] = now
|
||||
}
|
||||
}
|
||||
s.corrected += delta(phy.corrected, h.prevCorrected)
|
||||
}
|
||||
h.prevValid = true
|
||||
h.prevSince = v.since
|
||||
h.prevCorrected = phy.corrected
|
||||
|
||||
if measuring {
|
||||
s.measuring = true
|
||||
} else {
|
||||
if v.rxGbps < rateOKFrac*target {
|
||||
s.rateLow = true
|
||||
h.sinceRateLow = true
|
||||
return
|
||||
}
|
||||
if v.rxGbps < rateOKFrac*target {
|
||||
s.rateLow = true
|
||||
h.sinceRateLow = true
|
||||
}
|
||||
if phy.haveSNR {
|
||||
if !s.haveSNR || phy.worstMargin < s.snrMin {
|
||||
s.haveSNR, s.snrMin = true, phy.worstMargin
|
||||
}
|
||||
if phy.haveSNR {
|
||||
if !s.haveSNR || phy.worstMargin < s.snrMin {
|
||||
s.haveSNR, s.snrMin = true, phy.worstMargin
|
||||
}
|
||||
if !h.sinceHaveSNR || phy.worstMargin < h.sinceSNRMin {
|
||||
h.sinceHaveSNR, h.sinceSNRMin = true, phy.worstMargin
|
||||
}
|
||||
if !h.sinceHaveSNR || phy.worstMargin < h.sinceSNRMin {
|
||||
h.sinceHaveSNR, h.sinceSNRMin = true, phy.worstMargin
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +116,6 @@ func (h *history) sample(now time.Time, v view, phy phyDisplay,
|
||||
// the reset origin clears.
|
||||
func (h *history) reset() {
|
||||
h.mu.Lock()
|
||||
h.prevValid = false
|
||||
h.lastFault = [4]time.Time{}
|
||||
h.sinceRateLow = false
|
||||
h.sinceHaveSNR = false
|
||||
|
||||
Reference in New Issue
Block a user