mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 18:17:52 -05:00
avoid copying segment structure
This commit is contained in:
parent
ee0c25b0f3
commit
8cd32a8267
@ -123,6 +123,11 @@ func (seg *Segment) encode(ptr []byte) []byte {
|
|||||||
return ptr
|
return ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Segment) Release() {
|
||||||
|
this.data.Release()
|
||||||
|
this.data = nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewSegment creates a KCP segment
|
// NewSegment creates a KCP segment
|
||||||
func NewSegment() *Segment {
|
func NewSegment() *Segment {
|
||||||
return &Segment{
|
return &Segment{
|
||||||
@ -142,10 +147,10 @@ type KCP struct {
|
|||||||
ts_probe, probe_wait uint32
|
ts_probe, probe_wait uint32
|
||||||
dead_link, incr uint32
|
dead_link, incr uint32
|
||||||
|
|
||||||
snd_queue []Segment
|
snd_queue []*Segment
|
||||||
rcv_queue []Segment
|
rcv_queue []*Segment
|
||||||
snd_buf []Segment
|
snd_buf []*Segment
|
||||||
rcv_buf []Segment
|
rcv_buf []*Segment
|
||||||
|
|
||||||
acklist []uint32
|
acklist []uint32
|
||||||
|
|
||||||
@ -190,13 +195,13 @@ func (kcp *KCP) Recv(buffer []byte) (n int) {
|
|||||||
|
|
||||||
// merge fragment
|
// merge fragment
|
||||||
count := 0
|
count := 0
|
||||||
for k := range kcp.rcv_queue {
|
for _, seg := range kcp.rcv_queue {
|
||||||
seg := &kcp.rcv_queue[k]
|
|
||||||
dataLen := seg.data.Len()
|
dataLen := seg.data.Len()
|
||||||
if dataLen > len(buffer) {
|
if dataLen > len(buffer) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
copy(buffer, seg.data.Value)
|
copy(buffer, seg.data.Value)
|
||||||
|
seg.Release()
|
||||||
buffer = buffer[dataLen:]
|
buffer = buffer[dataLen:]
|
||||||
n += dataLen
|
n += dataLen
|
||||||
count++
|
count++
|
||||||
@ -205,10 +210,9 @@ func (kcp *KCP) Recv(buffer []byte) (n int) {
|
|||||||
|
|
||||||
// move available data from rcv_buf -> rcv_queue
|
// move available data from rcv_buf -> rcv_queue
|
||||||
count = 0
|
count = 0
|
||||||
for k := range kcp.rcv_buf {
|
for _, seg := range kcp.rcv_buf {
|
||||||
seg := &kcp.rcv_buf[k]
|
|
||||||
if seg.sn == kcp.rcv_nxt && len(kcp.rcv_queue) < int(kcp.rcv_wnd) {
|
if seg.sn == kcp.rcv_nxt && len(kcp.rcv_queue) < int(kcp.rcv_wnd) {
|
||||||
kcp.rcv_queue = append(kcp.rcv_queue, *seg)
|
kcp.rcv_queue = append(kcp.rcv_queue, seg)
|
||||||
kcp.rcv_nxt++
|
kcp.rcv_nxt++
|
||||||
count++
|
count++
|
||||||
} else {
|
} else {
|
||||||
@ -257,7 +261,7 @@ func (kcp *KCP) Send(buffer []byte) int {
|
|||||||
seg := NewSegment()
|
seg := NewSegment()
|
||||||
seg.data.Append(buffer[:size])
|
seg.data.Append(buffer[:size])
|
||||||
seg.frg = uint32(count - i - 1)
|
seg.frg = uint32(count - i - 1)
|
||||||
kcp.snd_queue = append(kcp.snd_queue, *seg)
|
kcp.snd_queue = append(kcp.snd_queue, seg)
|
||||||
buffer = buffer[size:]
|
buffer = buffer[size:]
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
@ -292,7 +296,7 @@ func (kcp *KCP) update_ack(rtt int32) {
|
|||||||
|
|
||||||
func (kcp *KCP) shrink_buf() {
|
func (kcp *KCP) shrink_buf() {
|
||||||
if len(kcp.snd_buf) > 0 {
|
if len(kcp.snd_buf) > 0 {
|
||||||
seg := &kcp.snd_buf[0]
|
seg := kcp.snd_buf[0]
|
||||||
kcp.snd_una = seg.sn
|
kcp.snd_una = seg.sn
|
||||||
} else {
|
} else {
|
||||||
kcp.snd_una = kcp.snd_nxt
|
kcp.snd_una = kcp.snd_nxt
|
||||||
@ -304,10 +308,10 @@ func (kcp *KCP) parse_ack(sn uint32) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for k := range kcp.snd_buf {
|
for k, seg := range kcp.snd_buf {
|
||||||
seg := &kcp.snd_buf[k]
|
|
||||||
if sn == seg.sn {
|
if sn == seg.sn {
|
||||||
kcp.snd_buf = append(kcp.snd_buf[:k], kcp.snd_buf[k+1:]...)
|
kcp.snd_buf = append(kcp.snd_buf[:k], kcp.snd_buf[k+1:]...)
|
||||||
|
seg.Release()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if _itimediff(sn, seg.sn) < 0 {
|
if _itimediff(sn, seg.sn) < 0 {
|
||||||
@ -321,8 +325,7 @@ func (kcp *KCP) parse_fastack(sn uint32) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for k := range kcp.snd_buf {
|
for _, seg := range kcp.snd_buf {
|
||||||
seg := &kcp.snd_buf[k]
|
|
||||||
if _itimediff(sn, seg.sn) < 0 {
|
if _itimediff(sn, seg.sn) < 0 {
|
||||||
break
|
break
|
||||||
} else if sn != seg.sn {
|
} else if sn != seg.sn {
|
||||||
@ -333,9 +336,9 @@ func (kcp *KCP) parse_fastack(sn uint32) {
|
|||||||
|
|
||||||
func (kcp *KCP) parse_una(una uint32) {
|
func (kcp *KCP) parse_una(una uint32) {
|
||||||
count := 0
|
count := 0
|
||||||
for k := range kcp.snd_buf {
|
for _, seg := range kcp.snd_buf {
|
||||||
seg := &kcp.snd_buf[k]
|
|
||||||
if _itimediff(una, seg.sn) > 0 {
|
if _itimediff(una, seg.sn) > 0 {
|
||||||
|
seg.Release()
|
||||||
count++
|
count++
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@ -364,7 +367,7 @@ func (kcp *KCP) parse_data(newseg *Segment) {
|
|||||||
insert_idx := 0
|
insert_idx := 0
|
||||||
repeat := false
|
repeat := false
|
||||||
for i := n; i >= 0; i-- {
|
for i := n; i >= 0; i-- {
|
||||||
seg := &kcp.rcv_buf[i]
|
seg := kcp.rcv_buf[i]
|
||||||
if seg.sn == sn {
|
if seg.sn == sn {
|
||||||
repeat = true
|
repeat = true
|
||||||
break
|
break
|
||||||
@ -377,18 +380,17 @@ func (kcp *KCP) parse_data(newseg *Segment) {
|
|||||||
|
|
||||||
if !repeat {
|
if !repeat {
|
||||||
if insert_idx == n+1 {
|
if insert_idx == n+1 {
|
||||||
kcp.rcv_buf = append(kcp.rcv_buf, *newseg)
|
kcp.rcv_buf = append(kcp.rcv_buf, newseg)
|
||||||
} else {
|
} else {
|
||||||
kcp.rcv_buf = append(kcp.rcv_buf, Segment{})
|
kcp.rcv_buf = append(kcp.rcv_buf, &Segment{})
|
||||||
copy(kcp.rcv_buf[insert_idx+1:], kcp.rcv_buf[insert_idx:])
|
copy(kcp.rcv_buf[insert_idx+1:], kcp.rcv_buf[insert_idx:])
|
||||||
kcp.rcv_buf[insert_idx] = *newseg
|
kcp.rcv_buf[insert_idx] = newseg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// move available data from rcv_buf -> rcv_queue
|
// move available data from rcv_buf -> rcv_queue
|
||||||
count := 0
|
count := 0
|
||||||
for k := range kcp.rcv_buf {
|
for k, seg := range kcp.rcv_buf {
|
||||||
seg := &kcp.rcv_buf[k]
|
|
||||||
if seg.sn == kcp.rcv_nxt && len(kcp.rcv_queue) < int(kcp.rcv_wnd) {
|
if seg.sn == kcp.rcv_nxt && len(kcp.rcv_queue) < int(kcp.rcv_wnd) {
|
||||||
kcp.rcv_queue = append(kcp.rcv_queue, kcp.rcv_buf[k])
|
kcp.rcv_queue = append(kcp.rcv_queue, kcp.rcv_buf[k])
|
||||||
kcp.rcv_nxt++
|
kcp.rcv_nxt++
|
||||||
@ -636,8 +638,7 @@ func (kcp *KCP) flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// flush data segments
|
// flush data segments
|
||||||
for k := range kcp.snd_buf {
|
for _, segment := range kcp.snd_buf {
|
||||||
segment := &kcp.snd_buf[k]
|
|
||||||
needsend := false
|
needsend := false
|
||||||
if segment.xmit == 0 {
|
if segment.xmit == 0 {
|
||||||
needsend = true
|
needsend = true
|
||||||
@ -680,8 +681,6 @@ func (kcp *KCP) flush() {
|
|||||||
copy(ptr, segment.data.Value)
|
copy(ptr, segment.data.Value)
|
||||||
ptr = ptr[segment.data.Len():]
|
ptr = ptr[segment.data.Len():]
|
||||||
|
|
||||||
segment.data.Release()
|
|
||||||
|
|
||||||
if segment.xmit >= kcp.dead_link {
|
if segment.xmit >= kcp.dead_link {
|
||||||
kcp.state = 0xFFFFFFFF
|
kcp.state = 0xFFFFFFFF
|
||||||
}
|
}
|
||||||
@ -778,8 +777,7 @@ func (kcp *KCP) Check(current uint32) uint32 {
|
|||||||
|
|
||||||
tm_flush = _itimediff(ts_flush, current)
|
tm_flush = _itimediff(ts_flush, current)
|
||||||
|
|
||||||
for k := range kcp.snd_buf {
|
for _, seg := range kcp.snd_buf {
|
||||||
seg := &kcp.snd_buf[k]
|
|
||||||
diff := _itimediff(seg.resendts, current)
|
diff := _itimediff(seg.resendts, current)
|
||||||
if diff <= 0 {
|
if diff <= 0 {
|
||||||
return current
|
return current
|
||||||
|
Loading…
Reference in New Issue
Block a user