|  | @@ -1,12 +1,26 @@
 | 
	
		
			
				|  |  |  package kcp
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import (
 | 
	
		
			
				|  |  | +	"sync"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	"github.com/v2ray/v2ray-core/common"
 | 
	
		
			
				|  |  |  	"github.com/v2ray/v2ray-core/common/alloc"
 | 
	
		
			
				|  |  |  	_ "github.com/v2ray/v2ray-core/common/log"
 | 
	
		
			
				|  |  |  	"github.com/v2ray/v2ray-core/common/serial"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +var (
 | 
	
		
			
				|  |  | +	dataSegmentPool = &sync.Pool{
 | 
	
		
			
				|  |  | +		New: func() interface{} { return new(DataSegment) },
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	ackSegmentPool = &sync.Pool{
 | 
	
		
			
				|  |  | +		New: func() interface{} { return new(AckSegment) },
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	cmdSegmentPool = &sync.Pool{
 | 
	
		
			
				|  |  | +		New: func() interface{} { return new(CmdOnlySegment) },
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  type SegmentCommand byte
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const (
 | 
	
	
		
			
				|  | @@ -45,6 +59,10 @@ type DataSegment struct {
 | 
	
		
			
				|  |  |  	transmit   uint32
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +func NewDataSegment() *DataSegment {
 | 
	
		
			
				|  |  | +	return dataSegmentPool.Get().(*DataSegment)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  func (this *DataSegment) Bytes(b []byte) []byte {
 | 
	
		
			
				|  |  |  	b = serial.Uint16ToBytes(this.Conv, b)
 | 
	
		
			
				|  |  |  	b = append(b, byte(SegmentCommandData), byte(this.Opt))
 | 
	
	
		
			
				|  | @@ -62,6 +80,12 @@ func (this *DataSegment) ByteSize() int {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *DataSegment) Release() {
 | 
	
		
			
				|  |  |  	this.Data.Release()
 | 
	
		
			
				|  |  | +	this.Data = nil
 | 
	
		
			
				|  |  | +	this.Opt = 0
 | 
	
		
			
				|  |  | +	this.timeout = 0
 | 
	
		
			
				|  |  | +	this.ackSkipped = 0
 | 
	
		
			
				|  |  | +	this.transmit = 0
 | 
	
		
			
				|  |  | +	dataSegmentPool.Put(this)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  type AckSegment struct {
 | 
	
	
		
			
				|  | @@ -74,6 +98,17 @@ type AckSegment struct {
 | 
	
		
			
				|  |  |  	TimestampList   []uint32
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +func NewAckSegment() *AckSegment {
 | 
	
		
			
				|  |  | +	seg := ackSegmentPool.Get().(*AckSegment)
 | 
	
		
			
				|  |  | +	if seg.NumberList == nil {
 | 
	
		
			
				|  |  | +		seg.NumberList = make([]uint32, 0, 128)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	if seg.TimestampList == nil {
 | 
	
		
			
				|  |  | +		seg.TimestampList = make([]uint32, 0, 128)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return seg
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  func (this *AckSegment) ByteSize() int {
 | 
	
		
			
				|  |  |  	return 2 + 1 + 1 + 4 + 4 + 1 + int(this.Count)*4 + int(this.Count)*4
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -91,7 +126,13 @@ func (this *AckSegment) Bytes(b []byte) []byte {
 | 
	
		
			
				|  |  |  	return b
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (this *AckSegment) Release() {}
 | 
	
		
			
				|  |  | +func (this *AckSegment) Release() {
 | 
	
		
			
				|  |  | +	this.Opt = 0
 | 
	
		
			
				|  |  | +	this.Count = 0
 | 
	
		
			
				|  |  | +	this.NumberList = this.NumberList[:0]
 | 
	
		
			
				|  |  | +	this.TimestampList = this.TimestampList[:0]
 | 
	
		
			
				|  |  | +	ackSegmentPool.Put(this)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  type CmdOnlySegment struct {
 | 
	
		
			
				|  |  |  	Conv         uint16
 | 
	
	
		
			
				|  | @@ -101,6 +142,10 @@ type CmdOnlySegment struct {
 | 
	
		
			
				|  |  |  	ReceivinNext uint32
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +func NewCmdOnlySegment() *CmdOnlySegment {
 | 
	
		
			
				|  |  | +	return cmdSegmentPool.Get().(*CmdOnlySegment)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  func (this *CmdOnlySegment) ByteSize() int {
 | 
	
		
			
				|  |  |  	return 2 + 1 + 1 + 4 + 4
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -113,7 +158,10 @@ func (this *CmdOnlySegment) Bytes(b []byte) []byte {
 | 
	
		
			
				|  |  |  	return b
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (this *CmdOnlySegment) Release() {}
 | 
	
		
			
				|  |  | +func (this *CmdOnlySegment) Release() {
 | 
	
		
			
				|  |  | +	this.Opt = 0
 | 
	
		
			
				|  |  | +	cmdSegmentPool.Put(this)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func ReadSegment(buf []byte) (Segment, []byte) {
 | 
	
		
			
				|  |  |  	if len(buf) <= 4 {
 |