package twcc
const (
minCapacity = 128
maxNumberOfPackets = 1 << 15
)
type packetArrivalTimeMap struct {
arrivalTimes []int64
beginSequenceNumber, endSequenceNumber int64
}
func (m *packetArrivalTimeMap ) AddPacket (sequenceNumber int64 , arrivalTime int64 ) {
if m .arrivalTimes == nil {
m .reallocate (minCapacity )
m .beginSequenceNumber = sequenceNumber
m .endSequenceNumber = sequenceNumber + 1
m .arrivalTimes [m .index (sequenceNumber )] = arrivalTime
return
}
if sequenceNumber >= m .beginSequenceNumber && sequenceNumber < m .endSequenceNumber {
m .arrivalTimes [m .index (sequenceNumber )] = arrivalTime
return
}
if sequenceNumber < m .beginSequenceNumber {
newSize := int (m .endSequenceNumber - sequenceNumber )
if newSize > maxNumberOfPackets {
return
}
m .adjustToSize (newSize )
m .arrivalTimes [m .index (sequenceNumber )] = arrivalTime
m .setNotReceived (sequenceNumber +1 , m .beginSequenceNumber )
m .beginSequenceNumber = sequenceNumber
return
}
newEndSequenceNumber := sequenceNumber + 1
if newEndSequenceNumber >= m .endSequenceNumber +maxNumberOfPackets {
m .beginSequenceNumber = sequenceNumber
m .endSequenceNumber = newEndSequenceNumber
m .arrivalTimes [m .index (sequenceNumber )] = arrivalTime
return
}
if m .beginSequenceNumber < newEndSequenceNumber -maxNumberOfPackets {
m .beginSequenceNumber = newEndSequenceNumber - maxNumberOfPackets
}
m .adjustToSize (int (newEndSequenceNumber - m .beginSequenceNumber ))
m .setNotReceived (m .endSequenceNumber , sequenceNumber )
m .endSequenceNumber = newEndSequenceNumber
m .arrivalTimes [m .index (sequenceNumber )] = arrivalTime
}
func (m *packetArrivalTimeMap ) setNotReceived (startInclusive , endExclusive int64 ) {
for sn := startInclusive ; sn < endExclusive ; sn ++ {
m .arrivalTimes [m .index (sn )] = -1
}
}
func (m *packetArrivalTimeMap ) BeginSequenceNumber () int64 {
return m .beginSequenceNumber
}
func (m *packetArrivalTimeMap ) EndSequenceNumber () int64 {
return m .endSequenceNumber
}
func (m *packetArrivalTimeMap ) FindNextAtOrAfter (sequenceNumber int64 ) (
foundSequenceNumber int64 , arrivalTime int64 , ok bool ,
) {
for sequenceNumber = m .Clamp (sequenceNumber ); sequenceNumber < m .endSequenceNumber ; sequenceNumber ++ {
if t := m .get (sequenceNumber ); t >= 0 {
return sequenceNumber , t , true
}
}
return -1 , -1 , false
}
func (m *packetArrivalTimeMap ) EraseTo (sequenceNumber int64 ) {
if sequenceNumber < m .beginSequenceNumber {
return
}
if sequenceNumber >= m .endSequenceNumber {
m .beginSequenceNumber = m .endSequenceNumber
return
}
m .beginSequenceNumber = sequenceNumber
m .adjustToSize (int (m .endSequenceNumber - m .beginSequenceNumber ))
}
func (m *packetArrivalTimeMap ) RemoveOldPackets (sequenceNumber int64 , arrivalTimeLimit int64 ) {
checkTo := min64 (sequenceNumber , m .endSequenceNumber )
for m .beginSequenceNumber < checkTo && m .get (m .beginSequenceNumber ) <= arrivalTimeLimit {
m .beginSequenceNumber ++
}
m .adjustToSize (int (m .endSequenceNumber - m .beginSequenceNumber ))
}
func (m *packetArrivalTimeMap ) HasReceived (sequenceNumber int64 ) bool {
return m .get (sequenceNumber ) >= 0
}
func (m *packetArrivalTimeMap ) Clamp (sequenceNumber int64 ) int64 {
if sequenceNumber < m .beginSequenceNumber {
return m .beginSequenceNumber
}
if m .endSequenceNumber < sequenceNumber {
return m .endSequenceNumber
}
return sequenceNumber
}
func (m *packetArrivalTimeMap ) get (sequenceNumber int64 ) int64 {
if sequenceNumber < m .beginSequenceNumber || sequenceNumber >= m .endSequenceNumber {
return -1
}
return m .arrivalTimes [m .index (sequenceNumber )]
}
func (m *packetArrivalTimeMap ) index (sequenceNumber int64 ) int {
return int (sequenceNumber & int64 (m .capacity ()-1 ))
}
func (m *packetArrivalTimeMap ) adjustToSize (newSize int ) {
if newSize > m .capacity () {
newCapacity := m .capacity ()
for newCapacity < newSize {
newCapacity *= 2
}
m .reallocate (newCapacity )
}
if m .capacity () > maxInt (minCapacity , newSize *4 ) {
newCapacity := m .capacity ()
for newCapacity >= 2 *maxInt (newSize , minCapacity ) {
newCapacity /= 2
}
m .reallocate (newCapacity )
}
}
func (m *packetArrivalTimeMap ) capacity () int {
return len (m .arrivalTimes )
}
func (m *packetArrivalTimeMap ) reallocate (newCapacity int ) {
newBuffer := make ([]int64 , newCapacity )
for sn := m .beginSequenceNumber ; sn < m .endSequenceNumber ; sn ++ {
newBuffer [int (sn &(int64 (newCapacity -1 )))] = m .get (sn )
}
m .arrivalTimes = newBuffer
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .