| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 | package kcpimport (	"sync")const (	defaultRTT = 100	queueSize  = 10)type Queue struct {	value  [queueSize]uint32	start  uint32	length uint32}func (v *Queue) Push(value uint32) {	if v.length < queueSize {		v.value[v.length] = value		v.length++		return	}	v.value[v.start] = value	v.start++	if v.start == queueSize {		v.start = 0	}}func (v *Queue) Max() uint32 {	max := v.value[0]	for i := 1; i < queueSize; i++ {		if v.value[i] > max {			max = v.value[i]		}	}	return max}func (v *Queue) Min() uint32 {	max := v.value[0]	for i := 1; i < queueSize; i++ {		if v.value[i] < max {			max = v.value[i]		}	}	return max}type CongestionState byteconst (	CongestionStateRTTProbe CongestionState = iota	CongestionStateBandwidthProbe	CongestionStateTransfer)type Congestion struct {	sync.RWMutex	state      CongestionState	stateSince uint32	limit      uint32 // bytes per 1000 seconds	rtt           uint32 // millisec	rttHistory    Queue	rttUpdateTime uint32	initialThroughput uint32 // bytes per 1000 seconds	cycleStartTime      uint32	cycleBytesConfirmed uint32	cycleBytesSent      uint32	cycleBytesLimit     uint32	cycle                   uint32	bestCycleBytesConfirmed uint32	bestCycleBytesSent      uint32}func (v *Congestion) SetState(current uint32, state CongestionState) {	v.state = state	v.stateSince = current}func (v *Congestion) Update(current uint32) {	switch v.state {	case CongestionStateRTTProbe:		if v.rtt > 0 {			v.SetState(current, CongestionStateBandwidthProbe)			v.cycleStartTime = current			v.cycleBytesConfirmed = 0			v.cycleBytesSent = 0			v.cycleBytesLimit = v.initialThroughput * v.rtt / 1000 / 1000		}	case CongestionStateBandwidthProbe:		if current-v.cycleStartTime >= v.rtt {		}	}}func (v *Congestion) AddBytesConfirmed(current uint32, bytesConfirmed uint32) {	v.Lock()	defer v.Unlock()	v.cycleBytesConfirmed += bytesConfirmed	v.Update(current)}func (v *Congestion) UpdateRTT(current uint32, rtt uint32) {	v.Lock()	defer v.Unlock()	if v.state == CongestionStateRTTProbe || rtt < v.rtt {		v.rtt = rtt		v.rttUpdateTime = current	}	v.Update(current)}func (v *Congestion) GetBytesLimit() uint32 {	v.RLock()	defer v.RUnlock()	if v.state == CongestionStateRTTProbe {		return v.initialThroughput/1000/(1000/defaultRTT) - v.cycleBytesSent	}	return v.cycleBytesLimit}func (v *Congestion) RoundTripTime() uint32 {	v.RLock()	defer v.RUnlock()	if v.state == CongestionStateRTTProbe {		return defaultRTT	}	return v.rtt}func (v *Congestion) Timeout() uint32 {	v.RLock()	defer v.RUnlock()	if v.state == CongestionStateRTTProbe {		return defaultRTT * 3 / 2	}	return v.rtt * 3 / 2}
 |