mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 10:08:15 -05:00
reuse alloc.buffer in kcp
This commit is contained in:
parent
7bf74761df
commit
ee0c25b0f3
@ -7,6 +7,8 @@ package kcp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/alloc"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -105,7 +107,7 @@ type Segment struct {
|
||||
rto uint32
|
||||
fastack uint32
|
||||
xmit uint32
|
||||
data []byte
|
||||
data *alloc.Buffer
|
||||
}
|
||||
|
||||
// encode a segment into buffer
|
||||
@ -117,15 +119,15 @@ func (seg *Segment) encode(ptr []byte) []byte {
|
||||
ptr = ikcp_encode32u(ptr, seg.ts)
|
||||
ptr = ikcp_encode32u(ptr, seg.sn)
|
||||
ptr = ikcp_encode32u(ptr, seg.una)
|
||||
ptr = ikcp_encode32u(ptr, uint32(len(seg.data)))
|
||||
ptr = ikcp_encode32u(ptr, uint32(seg.data.Len()))
|
||||
return ptr
|
||||
}
|
||||
|
||||
// NewSegment creates a KCP segment
|
||||
func NewSegment(size int) *Segment {
|
||||
seg := new(Segment)
|
||||
seg.data = make([]byte, size)
|
||||
return seg
|
||||
func NewSegment() *Segment {
|
||||
return &Segment{
|
||||
data: alloc.NewSmallBuffer().Clear(),
|
||||
}
|
||||
}
|
||||
|
||||
// KCP defines a single KCP connection
|
||||
@ -190,12 +192,13 @@ func (kcp *KCP) Recv(buffer []byte) (n int) {
|
||||
count := 0
|
||||
for k := range kcp.rcv_queue {
|
||||
seg := &kcp.rcv_queue[k]
|
||||
if len(seg.data) > len(buffer) {
|
||||
dataLen := seg.data.Len()
|
||||
if dataLen > len(buffer) {
|
||||
break
|
||||
}
|
||||
copy(buffer, seg.data)
|
||||
buffer = buffer[len(seg.data):]
|
||||
n += len(seg.data)
|
||||
copy(buffer, seg.data.Value)
|
||||
buffer = buffer[dataLen:]
|
||||
n += dataLen
|
||||
count++
|
||||
}
|
||||
kcp.rcv_queue = kcp.rcv_queue[count:]
|
||||
@ -251,8 +254,8 @@ func (kcp *KCP) Send(buffer []byte) int {
|
||||
} else {
|
||||
size = len(buffer)
|
||||
}
|
||||
seg := NewSegment(size)
|
||||
copy(seg.data, buffer[:size])
|
||||
seg := NewSegment()
|
||||
seg.data.Append(buffer[:size])
|
||||
seg.frg = uint32(count - i - 1)
|
||||
kcp.snd_queue = append(kcp.snd_queue, *seg)
|
||||
buffer = buffer[size:]
|
||||
@ -456,7 +459,7 @@ func (kcp *KCP) Input(data []byte) int {
|
||||
if _itimediff(sn, kcp.rcv_nxt+kcp.rcv_wnd) < 0 {
|
||||
kcp.ack_push(sn, ts)
|
||||
if _itimediff(sn, kcp.rcv_nxt) >= 0 {
|
||||
seg := NewSegment(int(length))
|
||||
seg := NewSegment()
|
||||
seg.conv = conv
|
||||
seg.cmd = uint32(cmd)
|
||||
seg.frg = uint32(frg)
|
||||
@ -464,7 +467,7 @@ func (kcp *KCP) Input(data []byte) int {
|
||||
seg.ts = ts
|
||||
seg.sn = sn
|
||||
seg.una = una
|
||||
copy(seg.data, data[:length])
|
||||
seg.data.Append(data[:length])
|
||||
kcp.parse_data(seg)
|
||||
}
|
||||
}
|
||||
@ -666,7 +669,7 @@ func (kcp *KCP) flush() {
|
||||
segment.una = kcp.rcv_nxt
|
||||
|
||||
size := len(buffer) - len(ptr)
|
||||
need := IKCP_OVERHEAD + len(segment.data)
|
||||
need := IKCP_OVERHEAD + segment.data.Len()
|
||||
|
||||
if size+need >= int(kcp.mtu) {
|
||||
kcp.output(buffer[:size])
|
||||
@ -674,8 +677,10 @@ func (kcp *KCP) flush() {
|
||||
}
|
||||
|
||||
ptr = segment.encode(ptr)
|
||||
copy(ptr, segment.data)
|
||||
ptr = ptr[len(segment.data):]
|
||||
copy(ptr, segment.data.Value)
|
||||
ptr = ptr[segment.data.Len():]
|
||||
|
||||
segment.data.Release()
|
||||
|
||||
if segment.xmit >= kcp.dead_link {
|
||||
kcp.state = 0xFFFFFFFF
|
||||
|
Loading…
Reference in New Issue
Block a user