Skip to content

Commit 1ccff82

Browse files
committed
Add helper to filter duplicate acks
1 parent 0555d58 commit 1ccff82

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

pkg/ccfb/duplicate_ack_filter.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package ccfb
2+
3+
type DuplicateAckFilter struct {
4+
highestAckedBySSRC map[uint32]int64
5+
}
6+
7+
func NewDuplicateAckFilter() *DuplicateAckFilter {
8+
return &DuplicateAckFilter{
9+
highestAckedBySSRC: make(map[uint32]int64),
10+
}
11+
}
12+
13+
func (f *DuplicateAckFilter) Filter(reports Report) {
14+
for ssrc, prs := range reports.SSRCToPacketReports {
15+
n := 0
16+
for _, report := range prs {
17+
if highest, ok := f.highestAckedBySSRC[ssrc]; !ok || report.SeqNr > highest {
18+
f.highestAckedBySSRC[ssrc] = report.SeqNr
19+
prs[n] = report
20+
n++
21+
}
22+
}
23+
reports.SSRCToPacketReports[ssrc] = prs[:n]
24+
}
25+
}

pkg/ccfb/duplicate_ack_filter_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package ccfb
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestDuplicateAckFilter(t *testing.T) {
12+
cases := []struct {
13+
in []Report
14+
expect []Report
15+
}{
16+
{
17+
in: []Report{},
18+
expect: []Report{},
19+
},
20+
{
21+
in: []Report{
22+
{
23+
SSRCToPacketReports: map[uint32][]PacketReport{
24+
0: {},
25+
},
26+
},
27+
},
28+
expect: []Report{
29+
{
30+
Arrival: time.Time{},
31+
Departure: time.Time{},
32+
SSRCToPacketReports: map[uint32][]PacketReport{
33+
0: {},
34+
},
35+
},
36+
},
37+
},
38+
{
39+
in: []Report{
40+
{
41+
SSRCToPacketReports: map[uint32][]PacketReport{
42+
0: {
43+
{
44+
SeqNr: 1,
45+
},
46+
{
47+
SeqNr: 2,
48+
},
49+
},
50+
},
51+
},
52+
{
53+
SSRCToPacketReports: map[uint32][]PacketReport{
54+
0: {
55+
{
56+
SeqNr: 1,
57+
},
58+
{
59+
SeqNr: 2,
60+
},
61+
{
62+
SeqNr: 3,
63+
},
64+
},
65+
},
66+
},
67+
},
68+
expect: []Report{
69+
{
70+
Arrival: time.Time{},
71+
Departure: time.Time{},
72+
SSRCToPacketReports: map[uint32][]PacketReport{
73+
0: {
74+
{
75+
SeqNr: 1,
76+
},
77+
{
78+
SeqNr: 2,
79+
},
80+
},
81+
},
82+
},
83+
{
84+
Arrival: time.Time{},
85+
Departure: time.Time{},
86+
SSRCToPacketReports: map[uint32][]PacketReport{
87+
0: {
88+
{
89+
SeqNr: 3,
90+
},
91+
},
92+
},
93+
},
94+
},
95+
},
96+
}
97+
for i, tc := range cases {
98+
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
99+
daf := NewDuplicateAckFilter()
100+
for i, m := range tc.in {
101+
daf.Filter(m)
102+
assert.Equal(t, tc.expect[i], m)
103+
}
104+
})
105+
}
106+
}

0 commit comments

Comments
 (0)