diff --git a/cmd/sdrd/decision_budget.go b/cmd/sdrd/decision_budget.go index 019b18b..29553c6 100644 --- a/cmd/sdrd/decision_budget.go +++ b/cmd/sdrd/decision_budget.go @@ -1,24 +1,35 @@ package main -import "sdr-wideband-suite/internal/pipeline" +import ( + "sort" + + "sdr-wideband-suite/internal/pipeline" +) func enforceDecisionBudgets(decisions []pipeline.SignalDecision, maxRecord int, maxDecode int) (int, int) { recorded := 0 decoded := 0 + order := make([]int, len(decisions)) for i := range decisions { - if decisions[i].ShouldRecord { + order[i] = i + } + sort.SliceStable(order, func(i, j int) bool { + return decisions[order[i]].Candidate.SNRDb > decisions[order[j]].Candidate.SNRDb + }) + for _, idx := range order { + if decisions[idx].ShouldRecord { if maxRecord > 0 && recorded >= maxRecord { - decisions[i].ShouldRecord = false - decisions[i].Reason = "recording budget exceeded" + decisions[idx].ShouldRecord = false + decisions[idx].Reason = "recording budget exceeded" } else { recorded++ } } - if decisions[i].ShouldAutoDecode { + if decisions[idx].ShouldAutoDecode { if maxDecode > 0 && decoded >= maxDecode { - decisions[i].ShouldAutoDecode = false - if decisions[i].Reason == "" { - decisions[i].Reason = "decode budget exceeded" + decisions[idx].ShouldAutoDecode = false + if decisions[idx].Reason == "" { + decisions[idx].Reason = "decode budget exceeded" } } else { decoded++ diff --git a/cmd/sdrd/decision_budget_test.go b/cmd/sdrd/decision_budget_test.go index 0827efd..f519ea6 100644 --- a/cmd/sdrd/decision_budget_test.go +++ b/cmd/sdrd/decision_budget_test.go @@ -8,21 +8,21 @@ import ( func TestEnforceDecisionBudgets(t *testing.T) { decisions := []pipeline.SignalDecision{ - {ShouldRecord: true, ShouldAutoDecode: true}, - {ShouldRecord: true, ShouldAutoDecode: true}, - {ShouldRecord: true, ShouldAutoDecode: false}, + {Candidate: pipeline.Candidate{SNRDb: 5}, ShouldRecord: true, ShouldAutoDecode: true}, + {Candidate: pipeline.Candidate{SNRDb: 15}, ShouldRecord: true, ShouldAutoDecode: true}, + {Candidate: pipeline.Candidate{SNRDb: 10}, ShouldRecord: true, ShouldAutoDecode: false}, } recorded, decoded := enforceDecisionBudgets(decisions, 1, 1) if recorded != 1 || decoded != 1 { t.Fatalf("unexpected counts: record=%d decode=%d", recorded, decoded) } - if decisions[0].ShouldRecord != true || decisions[0].ShouldAutoDecode != true { - t.Fatalf("expected first decision to remain allowed") + if !decisions[1].ShouldRecord || !decisions[1].ShouldAutoDecode { + t.Fatalf("expected highest SNR decision to remain allowed") } - if decisions[1].ShouldRecord || decisions[1].ShouldAutoDecode { - t.Fatalf("expected second decision to be budgeted off") + if decisions[0].ShouldRecord || decisions[0].ShouldAutoDecode { + t.Fatalf("expected lowest SNR decision to be budgeted off") } if decisions[2].ShouldRecord { - t.Fatalf("expected third decision to be budgeted off") + t.Fatalf("expected mid SNR decision to be budgeted off by record budget") } }