reuse alloc.buffer in kcp

pull/215/head
v2ray 2016-06-18 18:53:29 +02:00
parent 7bf74761df
commit ee0c25b0f3
1 changed files with 22 additions and 17 deletions

View File

@ -7,6 +7,8 @@ package kcp
import ( import (
"encoding/binary" "encoding/binary"
"github.com/v2ray/v2ray-core/common/alloc"
) )
const ( const (
@ -105,7 +107,7 @@ type Segment struct {
rto uint32 rto uint32
fastack uint32 fastack uint32
xmit uint32 xmit uint32
data []byte data *alloc.Buffer
} }
// encode a segment into 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.ts)
ptr = ikcp_encode32u(ptr, seg.sn) ptr = ikcp_encode32u(ptr, seg.sn)
ptr = ikcp_encode32u(ptr, seg.una) ptr = ikcp_encode32u(ptr, seg.una)
ptr = ikcp_encode32u(ptr, uint32(len(seg.data))) ptr = ikcp_encode32u(ptr, uint32(seg.data.Len()))
return ptr return ptr
} }
// NewSegment creates a KCP segment // NewSegment creates a KCP segment
func NewSegment(size int) *Segment { func NewSegment() *Segment {
seg := new(Segment) return &Segment{
seg.data = make([]byte, size) data: alloc.NewSmallBuffer().Clear(),
return seg }
} }
// KCP defines a single KCP connection // KCP defines a single KCP connection
@ -190,12 +192,13 @@ func (kcp *KCP) Recv(buffer []byte) (n int) {
count := 0 count := 0
for k := range kcp.rcv_queue { for k := range kcp.rcv_queue {
seg := &kcp.rcv_queue[k] seg := &kcp.rcv_queue[k]
if len(seg.data) > len(buffer) { dataLen := seg.data.Len()
if dataLen > len(buffer) {
break break
} }
copy(buffer, seg.data) copy(buffer, seg.data.Value)
buffer = buffer[len(seg.data):] buffer = buffer[dataLen:]
n += len(seg.data) n += dataLen
count++ count++
} }
kcp.rcv_queue = kcp.rcv_queue[count:] kcp.rcv_queue = kcp.rcv_queue[count:]
@ -251,8 +254,8 @@ func (kcp *KCP) Send(buffer []byte) int {
} else { } else {
size = len(buffer) size = len(buffer)
} }
seg := NewSegment(size) seg := NewSegment()
copy(seg.data, 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:]
@ -456,7 +459,7 @@ func (kcp *KCP) Input(data []byte) int {
if _itimediff(sn, kcp.rcv_nxt+kcp.rcv_wnd) < 0 { if _itimediff(sn, kcp.rcv_nxt+kcp.rcv_wnd) < 0 {
kcp.ack_push(sn, ts) kcp.ack_push(sn, ts)
if _itimediff(sn, kcp.rcv_nxt) >= 0 { if _itimediff(sn, kcp.rcv_nxt) >= 0 {
seg := NewSegment(int(length)) seg := NewSegment()
seg.conv = conv seg.conv = conv
seg.cmd = uint32(cmd) seg.cmd = uint32(cmd)
seg.frg = uint32(frg) seg.frg = uint32(frg)
@ -464,7 +467,7 @@ func (kcp *KCP) Input(data []byte) int {
seg.ts = ts seg.ts = ts
seg.sn = sn seg.sn = sn
seg.una = una seg.una = una
copy(seg.data, data[:length]) seg.data.Append(data[:length])
kcp.parse_data(seg) kcp.parse_data(seg)
} }
} }
@ -666,7 +669,7 @@ func (kcp *KCP) flush() {
segment.una = kcp.rcv_nxt segment.una = kcp.rcv_nxt
size := len(buffer) - len(ptr) size := len(buffer) - len(ptr)
need := IKCP_OVERHEAD + len(segment.data) need := IKCP_OVERHEAD + segment.data.Len()
if size+need >= int(kcp.mtu) { if size+need >= int(kcp.mtu) {
kcp.output(buffer[:size]) kcp.output(buffer[:size])
@ -674,8 +677,10 @@ func (kcp *KCP) flush() {
} }
ptr = segment.encode(ptr) ptr = segment.encode(ptr)
copy(ptr, segment.data) copy(ptr, segment.data.Value)
ptr = ptr[len(segment.data):] 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