From f8e6927581f9369ea51b608ca9143a57e349b6f5 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Sun, 8 Jul 2018 23:03:00 +0200 Subject: [PATCH] pool for data and ack segments --- transport/internet/kcp/receiving.go | 5 ++++- transport/internet/kcp/segment.go | 31 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/transport/internet/kcp/receiving.go b/transport/internet/kcp/receiving.go index 4be9be5a8..d6a0d0638 100644 --- a/transport/internet/kcp/receiving.go +++ b/transport/internet/kcp/receiving.go @@ -113,6 +113,7 @@ func (l *AckList) Flush(current uint32, rto uint32) { l.dirty = false } } + if l.dirty || !seg.IsEmpty() { for _, number := range l.flushCandidates { if seg.IsFull() { @@ -121,9 +122,10 @@ func (l *AckList) Flush(current uint32, rto uint32) { seg.PutNumber(number) } l.writer.Write(seg) - seg.Release() l.dirty = false } + + seg.Release() } type ReceivingWorker struct { @@ -234,6 +236,7 @@ func (w *ReceivingWorker) Write(seg Segment) error { ackSeg.Conv = w.conn.meta.Conversation ackSeg.ReceivingNext = w.nextNumber ackSeg.ReceivingWindow = w.nextNumber + w.windowSize + ackSeg.Option = 0 if w.conn.State() == StateReadyToClose { ackSeg.Option = SegmentOptionClose } diff --git a/transport/internet/kcp/segment.go b/transport/internet/kcp/segment.go index e4e9e8530..52881e457 100755 --- a/transport/internet/kcp/segment.go +++ b/transport/internet/kcp/segment.go @@ -1,6 +1,8 @@ package kcp import ( + "sync" + "v2ray.com/core/common/buf" "v2ray.com/core/common/serial" ) @@ -38,6 +40,12 @@ const ( DataSegmentOverhead = 18 ) +var dataSegmentPool = sync.Pool{ + New: func() interface{} { + return new(DataSegment) + }, +} + type DataSegment struct { Conv uint16 Option SegmentOption @@ -51,7 +59,11 @@ type DataSegment struct { } func NewDataSegment() *DataSegment { - return new(DataSegment) + seg := dataSegmentPool.Get().(*DataSegment) + seg.Conv = 0 + seg.timeout = 0 + seg.transmit = 0 + return seg } func (s *DataSegment) parse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte) { @@ -123,6 +135,15 @@ func (s *DataSegment) ByteSize() int32 { func (s *DataSegment) Release() { s.payload.Release() s.payload = nil + dataSegmentPool.Put(s) +} + +var ackSegmentPool = sync.Pool{ + New: func() interface{} { + return &AckSegment{ + NumberList: make([]uint32, 0, 16), + } + }, } type AckSegment struct { @@ -137,9 +158,9 @@ type AckSegment struct { const ackNumberLimit = 128 func NewAckSegment() *AckSegment { - return &AckSegment{ - NumberList: make([]uint32, 0, ackNumberLimit), - } + seg := ackSegmentPool.Get().(*AckSegment) + seg.NumberList = seg.NumberList[:0] + return seg } func (s *AckSegment) parse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte) { @@ -219,7 +240,7 @@ func (s *AckSegment) Bytes() buf.Supplier { } func (s *AckSegment) Release() { - s.NumberList = nil + ackSegmentPool.Put(s) } type CmdOnlySegment struct {