use a sync.Pool for ACK frames

This commit is contained in:
Marten Seemann
2022-09-06 14:38:00 +03:00
parent c3289188d1
commit 63764c429c
6 changed files with 87 additions and 12 deletions

View File

@@ -29,7 +29,7 @@ func parseAckFrame(r *bytes.Reader, ackDelayExponent uint8, _ protocol.VersionNu
}
ecn := typeByte&0x1 > 0
frame := &AckFrame{}
frame := GetAckFrame()
la, err := quicvarint.Read(r)
if err != nil {
@@ -106,7 +106,7 @@ func parseAckFrame(r *bytes.Reader, ackDelayExponent uint8, _ protocol.VersionNu
return frame, nil
}
// Write writes an ACK frame.
// Append appends an ACK frame.
func (f *AckFrame) Append(b []byte, _ protocol.VersionNumber) ([]byte, error) {
hasECN := f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0
if hasECN {

View File

@@ -0,0 +1,24 @@
package wire
import "sync"
var ackFramePool = sync.Pool{New: func() any {
return &AckFrame{}
}}
func GetAckFrame() *AckFrame {
f := ackFramePool.Get().(*AckFrame)
f.AckRanges = f.AckRanges[:0]
f.ECNCE = 0
f.ECT0 = 0
f.ECT1 = 0
f.DelayTime = 0
return f
}
func PutAckFrame(f *AckFrame) {
if cap(f.AckRanges) > 4 {
return
}
ackFramePool.Put(f)
}

View File

@@ -0,0 +1,29 @@
package wire
import (
"math/rand"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("ACK Frame (for IETF QUIC)", func() {
It("gets an ACK frame from the pool", func() {
for i := 0; i < 100; i++ {
ack := GetAckFrame()
Expect(ack.AckRanges).To(BeEmpty())
Expect(ack.ECNCE).To(BeZero())
Expect(ack.ECT0).To(BeZero())
Expect(ack.ECT1).To(BeZero())
Expect(ack.DelayTime).To(BeZero())
ack.AckRanges = make([]AckRange, rand.Intn(10))
ack.ECNCE = 1
ack.ECT0 = 2
ack.ECT1 = 3
ack.DelayTime = time.Hour
PutAckFrame(ack)
}
})
})