calculate entropy when there are NACK ranges

This commit is contained in:
Marten Seemann
2016-04-22 18:35:19 +07:00
parent 3e5f43f45a
commit 063cd4a7bd
2 changed files with 58 additions and 30 deletions

View File

@@ -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,
}
}

View File

@@ -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))
})
})
})