From ee0c25b0f37f330d788e3a60842bcaa4d338cb74 Mon Sep 17 00:00:00 2001 From: v2ray Date: Sat, 18 Jun 2016 18:53:29 +0200 Subject: [PATCH] reuse alloc.buffer in kcp --- transport/internet/kcp/kcp.go | 39 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/transport/internet/kcp/kcp.go b/transport/internet/kcp/kcp.go index 0331571f2..88118a0e8 100644 --- a/transport/internet/kcp/kcp.go +++ b/transport/internet/kcp/kcp.go @@ -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