| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- package kcp
- type SendingWindow struct {
- start uint32
- cap uint32
- len uint32
- last uint32
- data []*DataSegment
- prev []uint32
- next []uint32
- kcp *KCP
- }
- func NewSendingWindow(kcp *KCP, size uint32) *SendingWindow {
- window := &SendingWindow{
- start: 0,
- cap: size,
- len: 0,
- last: 0,
- data: make([]*DataSegment, size),
- prev: make([]uint32, size),
- next: make([]uint32, size),
- }
- return window
- }
- func (this *SendingWindow) Len() int {
- return int(this.len)
- }
- func (this *SendingWindow) Push(seg *DataSegment) {
- pos := (this.start + this.len) % this.cap
- this.data[pos] = seg
- if this.len > 0 {
- this.next[this.last] = pos
- this.prev[pos] = this.last
- }
- this.last = pos
- this.len++
- }
- func (this *SendingWindow) First() *DataSegment {
- return this.data[this.start]
- }
- func (this *SendingWindow) Clear(una uint32) {
- for this.Len() > 0 {
- if this.data[this.start].Number < una {
- this.Remove(0)
- }
- }
- }
- func (this *SendingWindow) Remove(idx uint32) {
- pos := (this.start + idx) % this.cap
- seg := this.data[pos]
- seg.Release()
- this.data[pos] = nil
- if pos == this.start {
- if this.len == 1 {
- this.len = 0
- this.start = 0
- this.last = 0
- } else {
- delta := this.next[pos] - this.start
- this.start = this.next[pos]
- this.len -= delta
- }
- } else if pos == this.last {
- this.last = this.prev[pos]
- } else {
- this.next[this.prev[pos]] = this.next[pos]
- this.prev[this.next[pos]] = this.prev[pos]
- }
- }
- func (this *SendingWindow) HandleFastAck(number uint32) {
- for i := this.start; ; i = this.next[i] {
- seg := this.data[i]
- if _itimediff(number, seg.Number) < 0 {
- break
- }
- if number != seg.Number {
- seg.ackSkipped++
- }
- if i == this.last {
- break
- }
- }
- }
- func (this *SendingWindow) Flush() bool {
- current := this.kcp.current
- resent := uint32(this.kcp.fastresend)
- if this.kcp.fastresend <= 0 {
- resent = 0xffffffff
- }
- lost := false
- segSent := false
- for i := this.start; ; i = this.next[i] {
- segment := this.data[i]
- needsend := false
- if segment.transmit == 0 {
- needsend = true
- segment.transmit++
- segment.timeout = current + this.kcp.rx_rto
- } else if _itimediff(current, segment.timeout) >= 0 {
- needsend = true
- segment.transmit++
- segment.timeout = current + this.kcp.rx_rto
- lost = true
- } else if segment.ackSkipped >= resent {
- needsend = true
- segment.transmit++
- segment.ackSkipped = 0
- segment.timeout = current + this.kcp.rx_rto
- lost = true
- }
- if needsend {
- segment.Timestamp = current
- segment.SendingNext = this.kcp.snd_una
- segment.Opt = 0
- if this.kcp.state == StateReadyToClose {
- segment.Opt = SegmentOptionClose
- }
- this.kcp.output.Write(segment)
- segSent = true
- }
- if i == this.last {
- break
- }
- }
- this.kcp.HandleLost(lost)
- return segSent
- }
- type SendingQueue struct {
- start uint32
- cap uint32
- len uint32
- list []*DataSegment
- }
- func NewSendingQueue(size uint32) *SendingQueue {
- return &SendingQueue{
- start: 0,
- cap: size,
- list: make([]*DataSegment, size),
- len: 0,
- }
- }
- func (this *SendingQueue) IsFull() bool {
- return this.len == this.cap
- }
- func (this *SendingQueue) IsEmpty() bool {
- return this.len == 0
- }
- func (this *SendingQueue) Pop() *DataSegment {
- if this.IsEmpty() {
- return nil
- }
- seg := this.list[this.start]
- this.list[this.start] = nil
- this.len--
- this.start++
- if this.start == this.cap {
- this.start = 0
- }
- return seg
- }
- func (this *SendingQueue) Push(seg *DataSegment) {
- if this.IsFull() {
- return
- }
- this.list[(this.start+this.len)%this.cap] = seg
- this.len++
- }
- func (this *SendingQueue) Clear() {
- for i := uint32(0); i < this.len; i++ {
- this.list[(i+this.start)%this.cap].Release()
- this.list[(i+this.start)%this.cap] = nil
- }
- this.start = 0
- this.len = 0
- }
- func (this *SendingQueue) Len() uint32 {
- return this.len
- }
|