Jelajahi Sumber

pool for data and ack segments

Darien Raymond 7 tahun lalu
induk
melakukan
f8e6927581
2 mengubah file dengan 30 tambahan dan 6 penghapusan
  1. 4 1
      transport/internet/kcp/receiving.go
  2. 26 5
      transport/internet/kcp/segment.go

+ 4 - 1
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
 	}

+ 26 - 5
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 {