forked from quic-go/quic-go
Merge pull request #2898 from lucas-clemente/dont-allocate-for-lost-packets
avoid allocating when detecting lost packets
This commit is contained in:
@@ -307,13 +307,9 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lostPackets, err := h.detectLostPackets(rcvTime, encLevel)
|
if err := h.detectLostPackets(rcvTime, encLevel); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, p := range lostPackets {
|
|
||||||
h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight)
|
|
||||||
}
|
|
||||||
for _, p := range ackedPackets {
|
for _, p := range ackedPackets {
|
||||||
if p.skippedPacket {
|
if p.skippedPacket {
|
||||||
return fmt.Errorf("received an ACK for skipped packet number: %d (%s)", p.PacketNumber, encLevel)
|
return fmt.Errorf("received an ACK for skipped packet number: %d (%s)", p.PacketNumber, encLevel)
|
||||||
@@ -508,7 +504,7 @@ func (h *sentPacketHandler) setLossDetectionTimer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) ([]*Packet, error) {
|
func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) error {
|
||||||
pnSpace := h.getPacketNumberSpace(encLevel)
|
pnSpace := h.getPacketNumberSpace(encLevel)
|
||||||
pnSpace.lossTime = time.Time{}
|
pnSpace.lossTime = time.Time{}
|
||||||
|
|
||||||
@@ -521,47 +517,42 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
|
|||||||
// Packets sent before this time are deemed lost.
|
// Packets sent before this time are deemed lost.
|
||||||
lostSendTime := now.Add(-lossDelay)
|
lostSendTime := now.Add(-lossDelay)
|
||||||
|
|
||||||
var lostPackets []*Packet
|
priorInFlight := h.bytesInFlight
|
||||||
if err := pnSpace.history.Iterate(func(packet *Packet) (bool, error) {
|
return pnSpace.history.Iterate(func(p *Packet) (bool, error) {
|
||||||
if packet.PacketNumber > pnSpace.largestAcked {
|
if p.PacketNumber > pnSpace.largestAcked {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if packet.declaredLost || packet.skippedPacket {
|
if p.declaredLost || p.skippedPacket {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if packet.SendTime.Before(lostSendTime) {
|
var packetLost bool
|
||||||
lostPackets = append(lostPackets, packet)
|
if p.SendTime.Before(lostSendTime) {
|
||||||
if h.tracer != nil {
|
packetLost = true
|
||||||
h.tracer.LostPacket(packet.EncryptionLevel, packet.PacketNumber, logging.PacketLossTimeThreshold)
|
if h.logger.Debug() {
|
||||||
|
h.logger.Debugf("\tlost packet %d (time threshold)", p.PacketNumber)
|
||||||
}
|
}
|
||||||
} else if pnSpace.largestAcked >= packet.PacketNumber+packetThreshold {
|
|
||||||
lostPackets = append(lostPackets, packet)
|
|
||||||
if h.tracer != nil {
|
if h.tracer != nil {
|
||||||
h.tracer.LostPacket(packet.EncryptionLevel, packet.PacketNumber, logging.PacketLossReorderingThreshold)
|
h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossTimeThreshold)
|
||||||
|
}
|
||||||
|
} else if pnSpace.largestAcked >= p.PacketNumber+packetThreshold {
|
||||||
|
packetLost = true
|
||||||
|
if h.logger.Debug() {
|
||||||
|
h.logger.Debugf("\tlost packet %d (reordering threshold)", p.PacketNumber)
|
||||||
|
}
|
||||||
|
if h.tracer != nil {
|
||||||
|
h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossReorderingThreshold)
|
||||||
}
|
}
|
||||||
} else if pnSpace.lossTime.IsZero() {
|
} else if pnSpace.lossTime.IsZero() {
|
||||||
// Note: This conditional is only entered once per call
|
// Note: This conditional is only entered once per call
|
||||||
lossTime := packet.SendTime.Add(lossDelay)
|
lossTime := p.SendTime.Add(lossDelay)
|
||||||
if h.logger.Debug() {
|
if h.logger.Debug() {
|
||||||
h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", packet.PacketNumber, encLevel, lossDelay, lossTime)
|
h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", p.PacketNumber, encLevel, lossDelay, lossTime)
|
||||||
}
|
}
|
||||||
pnSpace.lossTime = lossTime
|
pnSpace.lossTime = lossTime
|
||||||
}
|
}
|
||||||
return true, nil
|
if packetLost {
|
||||||
}); err != nil {
|
h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if h.logger.Debug() && len(lostPackets) > 0 {
|
|
||||||
pns := make([]protocol.PacketNumber, len(lostPackets))
|
|
||||||
for i, p := range lostPackets {
|
|
||||||
pns[i] = p.PacketNumber
|
|
||||||
}
|
|
||||||
h.logger.Debugf("\tlost packets (%d): %d", len(pns), pns)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range lostPackets {
|
|
||||||
p.declaredLost = true
|
p.declaredLost = true
|
||||||
h.queueFramesForRetransmission(p)
|
h.queueFramesForRetransmission(p)
|
||||||
// the bytes in flight need to be reduced no matter if this packet will be retransmitted
|
// the bytes in flight need to be reduced no matter if this packet will be retransmitted
|
||||||
@@ -582,7 +573,8 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lostPackets, nil
|
return true, nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) OnLossDetectionTimeout() error {
|
func (h *sentPacketHandler) OnLossDetectionTimeout() error {
|
||||||
@@ -609,15 +601,7 @@ func (h *sentPacketHandler) onVerifiedLossDetectionTimeout() error {
|
|||||||
h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel)
|
h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel)
|
||||||
}
|
}
|
||||||
// Early retransmit or time loss detection
|
// Early retransmit or time loss detection
|
||||||
priorInFlight := h.bytesInFlight
|
return h.detectLostPackets(time.Now(), encLevel)
|
||||||
lostPackets, err := h.detectLostPackets(time.Now(), encLevel)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, p := range lostPackets {
|
|
||||||
h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PTO
|
// PTO
|
||||||
|
|||||||
Reference in New Issue
Block a user