From 063cd4a7bdfacab3ed6cc039e61a769d35c0d161 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 22 Apr 2016 18:35:19 +0700 Subject: [PATCH] calculate entropy when there are NACK ranges --- ackhandler/incoming_packet_ack_handler.go | 21 +++--- .../incoming_packet_ack_handler_test.go | 67 +++++++++++++------ 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/ackhandler/incoming_packet_ack_handler.go b/ackhandler/incoming_packet_ack_handler.go index 702d7d12..dd4afd8e 100644 --- a/ackhandler/incoming_packet_ack_handler.go +++ b/ackhandler/incoming_packet_ack_handler.go @@ -14,7 +14,7 @@ type incomingPacketAckHandler struct { highestInOrderObserved protocol.PacketNumber highestInOrderObservedEntropy EntropyAccumulator largestObserved protocol.PacketNumber - packetHistory map[protocol.PacketNumber]bool + packetHistory map[protocol.PacketNumber]bool // the bool is the EntropyBit of the packet } // NewIncomingPacketAckHandler creates a new outgoingPacketAckHandler @@ -41,17 +41,18 @@ func (h *incomingPacketAckHandler) ReceivedPacket(packetNumber protocol.PacketNu h.highestInOrderObservedEntropy.Add(packetNumber, entropyBit) } - h.packetHistory[packetNumber] = true + h.packetHistory[packetNumber] = entropyBit return nil } // getNackRanges gets all the NACK ranges -func (h *incomingPacketAckHandler) getNackRanges() []frames.NackRange { - // ToDo: improve performance +func (h *incomingPacketAckHandler) getNackRanges() ([]frames.NackRange, EntropyAccumulator) { + // ToDo: use a better data structure here var ranges []frames.NackRange inRange := false - for i := h.highestInOrderObserved; i < h.largestObserved; i++ { - _, ok := h.packetHistory[i] + entropy := h.highestInOrderObservedEntropy + for i := h.highestInOrderObserved + 1; i <= h.largestObserved; i++ { + entropyBit, ok := h.packetHistory[i] if !ok { if !inRange { r := frames.NackRange{ @@ -65,17 +66,17 @@ func (h *incomingPacketAckHandler) getNackRanges() []frames.NackRange { } } else { inRange = false + entropy.Add(i, entropyBit) } } - return ranges + return ranges, entropy } func (h *incomingPacketAckHandler) DequeueAckFrame() *frames.AckFrame { - nackRanges := h.getNackRanges() - entropy := byte(0) + nackRanges, entropy := h.getNackRanges() return &frames.AckFrame{ LargestObserved: h.largestObserved, - Entropy: entropy, + Entropy: byte(entropy), NackRanges: nackRanges, } } diff --git a/ackhandler/incoming_packet_ack_handler_test.go b/ackhandler/incoming_packet_ack_handler_test.go index a1b7057e..ce852613 100644 --- a/ackhandler/incoming_packet_ack_handler_test.go +++ b/ackhandler/incoming_packet_ack_handler_test.go @@ -8,10 +8,14 @@ import ( ) var _ = Describe("incomingPacketAckHandler", func() { - var handler *incomingPacketAckHandler + var ( + handler *incomingPacketAckHandler + expectedEntropy EntropyAccumulator + ) BeforeEach(func() { handler = NewIncomingPacketAckHandler().(*incomingPacketAckHandler) + expectedEntropy = EntropyAccumulator(0) }) Context("accepting and rejecting packets", func() { @@ -22,7 +26,7 @@ var _ = Describe("incomingPacketAckHandler", func() { Expect(err).ToNot(HaveOccurred()) err = handler.ReceivedPacket(protocol.PacketNumber(2), false) Expect(err).ToNot(HaveOccurred()) - nackRanges := handler.getNackRanges() + nackRanges, _ := handler.getNackRanges() Expect(len(nackRanges)).To(Equal(0)) }) @@ -49,21 +53,19 @@ var _ = Describe("incomingPacketAckHandler", func() { Context("Entropy calculation", func() { It("calculates the entropy for continously received packets", func() { - entropy := EntropyAccumulator(0) for i := 1; i < 100; i++ { entropyBit := false if i%3 == 0 || i%5 == 0 { entropyBit = true } - entropy.Add(protocol.PacketNumber(i), entropyBit) + expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) Expect(err).ToNot(HaveOccurred()) } - Expect(handler.highestInOrderObservedEntropy).To(Equal(entropy)) + Expect(handler.highestInOrderObservedEntropy).To(Equal(expectedEntropy)) }) It("calculates the entropy if there is a NACK range", func() { - entropy := EntropyAccumulator(0) for i := 1; i < 100; i++ { entropyBit := false if i%3 == 0 || i%5 == 0 { @@ -74,92 +76,117 @@ var _ = Describe("incomingPacketAckHandler", func() { continue } if i < 10 { - entropy.Add(protocol.PacketNumber(i), entropyBit) + expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) } err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) Expect(err).ToNot(HaveOccurred()) } - Expect(handler.highestInOrderObservedEntropy).To(Equal(entropy)) + Expect(handler.highestInOrderObservedEntropy).To(Equal(expectedEntropy)) }) }) Context("NACK range calculation", func() { It("Returns no NACK ranges for continously received packets", func() { for i := 1; i < 100; i++ { - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) + entropyBit := false + if i%2 == 0 { + entropyBit = true + } + expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) + err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) Expect(err).ToNot(HaveOccurred()) } Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(99))) Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(99))) - Expect(len(handler.getNackRanges())).To(Equal(0)) + nackRanges, entropy := handler.getNackRanges() + Expect(len(nackRanges)).To(Equal(0)) + Expect(entropy).To(Equal(expectedEntropy)) }) It("handles a single lost package", func() { for i := 1; i < 10; i++ { + entropyBit := true if i == 5 { continue } - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) + expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) + err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) Expect(err).ToNot(HaveOccurred()) } Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(9))) - nackRanges := handler.getNackRanges() + nackRanges, entropy := handler.getNackRanges() Expect(len(nackRanges)).To(Equal(1)) Expect(nackRanges[0].FirstPacketNumber).To(Equal(protocol.PacketNumber(5))) Expect(nackRanges[0].LastPacketNumber).To(Equal(protocol.PacketNumber(5))) Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(4))) + Expect(entropy).To(Equal(expectedEntropy)) }) It("handles two consecutive lost packages", func() { - for i := 1; i < 10; i++ { + for i := 1; i < 12; i++ { + entropyBit := false + if i%2 == 0 || i == 5 { + entropyBit = true + } if i == 5 || i == 6 { continue } - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) + expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) + err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) Expect(err).ToNot(HaveOccurred()) } - Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(9))) - nackRanges := handler.getNackRanges() + Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(11))) + nackRanges, entropy := handler.getNackRanges() Expect(len(nackRanges)).To(Equal(1)) Expect(nackRanges[0].FirstPacketNumber).To(Equal(protocol.PacketNumber(5))) Expect(nackRanges[0].LastPacketNumber).To(Equal(protocol.PacketNumber(6))) Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(4))) + Expect(entropy).To(Equal(expectedEntropy)) }) It("handles two non-consecutively lost packages", func() { for i := 1; i < 10; i++ { + entropyBit := false + if i%2 != 0 { + entropyBit = true + } if i == 3 || i == 7 { continue } - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) + expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) + err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) Expect(err).ToNot(HaveOccurred()) } Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(9))) - nackRanges := handler.getNackRanges() + nackRanges, entropy := handler.getNackRanges() Expect(len(nackRanges)).To(Equal(2)) Expect(nackRanges[0].FirstPacketNumber).To(Equal(protocol.PacketNumber(3))) Expect(nackRanges[0].LastPacketNumber).To(Equal(protocol.PacketNumber(3))) Expect(nackRanges[1].FirstPacketNumber).To(Equal(protocol.PacketNumber(7))) Expect(nackRanges[1].LastPacketNumber).To(Equal(protocol.PacketNumber(7))) Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(2))) + Expect(entropy).To(Equal(expectedEntropy)) }) It("handles two sequences of lost packages", func() { for i := 1; i < 10; i++ { + entropyBit := true if i == 2 || i == 3 || i == 4 || i == 7 || i == 8 { continue } - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) + expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) + err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) Expect(err).ToNot(HaveOccurred()) } Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(9))) - nackRanges := handler.getNackRanges() + nackRanges, entropy := handler.getNackRanges() Expect(len(nackRanges)).To(Equal(2)) Expect(nackRanges[0].FirstPacketNumber).To(Equal(protocol.PacketNumber(2))) Expect(nackRanges[0].LastPacketNumber).To(Equal(protocol.PacketNumber(4))) Expect(nackRanges[1].FirstPacketNumber).To(Equal(protocol.PacketNumber(7))) Expect(nackRanges[1].LastPacketNumber).To(Equal(protocol.PacketNumber(8))) Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(1))) + Expect(entropy).To(Equal(expectedEntropy)) }) }) })