From 1ec873f917cbbfd27b9dfc633f26d93dc02d70c9 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 19 Apr 2018 17:36:12 +0900 Subject: [PATCH] use binary search to check if an ACK acks a packet --- internal/wire/ack_frame.go | 15 +++++++-------- internal/wire/ack_frame_test.go | 2 ++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/internal/wire/ack_frame.go b/internal/wire/ack_frame.go index d1ee229b..61fdfb70 100644 --- a/internal/wire/ack_frame.go +++ b/internal/wire/ack_frame.go @@ -3,6 +3,7 @@ package wire import ( "bytes" "errors" + "sort" "time" "github.com/lucas-clemente/quic-go/internal/protocol" @@ -202,17 +203,15 @@ func (f *AckFrame) LowestAcked() protocol.PacketNumber { // AcksPacket determines if this ACK frame acks a certain packet number func (f *AckFrame) AcksPacket(p protocol.PacketNumber) bool { - if p < f.LowestAcked() || p > f.LargestAcked() { // this is just a performance optimization + if p < f.LowestAcked() || p > f.LargestAcked() { return false } - // TODO: this could be implemented as a binary search - for _, ackRange := range f.AckRanges { - if p >= ackRange.Smallest && p <= ackRange.Largest { - return true - } - } - return false + i := sort.Search(len(f.AckRanges), func(i int) bool { + return p >= f.AckRanges[i].Smallest + }) + // i will always be < len(f.AckRanges), since we checked above that p is not bigger than the largest acked + return p <= f.AckRanges[i].Largest } func encodeAckDelay(delay time.Duration) uint64 { diff --git a/internal/wire/ack_frame_test.go b/internal/wire/ack_frame_test.go index f8a052d4..9e29c8db 100644 --- a/internal/wire/ack_frame_test.go +++ b/internal/wire/ack_frame_test.go @@ -314,12 +314,14 @@ var _ = Describe("ACK Frame (for IETF QUIC)", func() { } Expect(f.AcksPacket(4)).To(BeFalse()) Expect(f.AcksPacket(5)).To(BeTrue()) + Expect(f.AcksPacket(6)).To(BeTrue()) Expect(f.AcksPacket(7)).To(BeTrue()) Expect(f.AcksPacket(8)).To(BeTrue()) Expect(f.AcksPacket(9)).To(BeFalse()) Expect(f.AcksPacket(14)).To(BeFalse()) Expect(f.AcksPacket(15)).To(BeTrue()) Expect(f.AcksPacket(18)).To(BeTrue()) + Expect(f.AcksPacket(19)).To(BeTrue()) Expect(f.AcksPacket(20)).To(BeTrue()) Expect(f.AcksPacket(21)).To(BeFalse()) })