add a timeout policy for fec buffer

This commit is contained in:
xtaci
2019-10-27 13:18:53 +00:00
parent 5e3955f967
commit 31e8785c63
+28 -6
View File
@@ -12,6 +12,7 @@ const (
fecHeaderSizePlus2 = fecHeaderSize + 2 // plus 2B data size
typeData = 0xf1
typeParity = 0xf2
fecExpire = 60000
)
// fecPacket is a decoded FEC packet
@@ -21,13 +22,19 @@ func (bts fecPacket) seqid() uint32 { return binary.LittleEndian.Uint32(bts) }
func (bts fecPacket) flag() uint16 { return binary.LittleEndian.Uint16(bts[4:]) }
func (bts fecPacket) data() []byte { return bts[6:] }
// fecElement has auxcilliary time field
type fecElement struct {
fecPacket
ts uint32
}
// fecDecoder for decoding incoming packets
type fecDecoder struct {
rxlimit int // queue size limit
dataShards int
parityShards int
shardSize int
rx []fecPacket // ordered receive queue
rx []fecElement // ordered receive queue
// caches
decodeCache [][]byte
@@ -81,14 +88,15 @@ func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
// make a copy
pkt := fecPacket(xmitBuf.Get().([]byte)[:len(in)])
copy(pkt, in)
elem := fecElement{pkt, currentMs()}
// insert into ordered rx queue
if insertIdx == n+1 {
dec.rx = append(dec.rx, pkt)
dec.rx = append(dec.rx, elem)
} else {
dec.rx = append(dec.rx, fecPacket{})
dec.rx = append(dec.rx, fecElement{})
copy(dec.rx[insertIdx+1:], dec.rx[insertIdx:]) // shift right
dec.rx[insertIdx] = pkt
dec.rx[insertIdx] = elem
}
// shard range for current packet
@@ -171,13 +179,27 @@ func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
}
dec.rx = dec.freeRange(0, 1, dec.rx)
}
// timeout policy
current := currentMs()
expiredIdx := -1
for k := range dec.rx {
if _itimediff(current, dec.rx[k].ts) > 10 { //fecExpire {
expiredIdx = k
continue
}
break
}
if expiredIdx >= 0 {
dec.rx = dec.freeRange(0, expiredIdx, dec.rx)
}
return
}
// free a range of fecPacket
func (dec *fecDecoder) freeRange(first, n int, q []fecPacket) []fecPacket {
func (dec *fecDecoder) freeRange(first, n int, q []fecElement) []fecElement {
for i := first; i < first+n; i++ { // recycle buffer
xmitBuf.Put([]byte(q[i]))
xmitBuf.Put([]byte(q[i].fecPacket))
}
if first == 0 && n < cap(q)/2 {