Improve vectorised writer

This commit is contained in:
世界 2023-03-05 13:35:34 +08:00
parent c875a4ffab
commit e16845727f
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 44 additions and 17 deletions

View file

@ -16,6 +16,14 @@ func ToSliceMulti(buffers []*Buffer) [][]byte {
})
}
func CopyMulti(toBuffer []byte, buffers []*Buffer) int {
var n int
for _, buffer := range buffers {
n += copy(toBuffer[n:], buffer.Bytes())
}
return n
}
func ReleaseMulti(buffers []*Buffer) {
for _, buffer := range buffers {
buffer.Release()

View file

@ -49,11 +49,29 @@ func (c *ChunkReader) Read(p []byte) (n int, err error) {
c.cache.FullReset()
err = c.upstream.ReadBuffer(c.cache)
if err != nil {
c.cache.Release()
c.cache = nil
return
}
return c.cache.Read(p)
}
func (c *ChunkReader) ReadChunk() (*buf.Buffer, error) {
if c.cache == nil {
c.cache = buf.NewSize(c.maxChunkSize)
} else if !c.cache.IsEmpty() {
return c.cache, nil
}
c.cache.FullReset()
err := c.upstream.ReadBuffer(c.cache)
if err != nil {
c.cache.Release()
c.cache = nil
return nil, err
}
return c.cache, nil
}
func (c *ChunkReader) MTU() int {
return c.maxChunkSize
}

View file

@ -3,7 +3,6 @@ package bufio
import (
"io"
"net"
"sync"
"syscall"
"github.com/sagernet/sing/common"
@ -16,7 +15,7 @@ func NewVectorisedWriter(writer io.Writer) N.VectorisedWriter {
if vectorisedWriter, ok := CreateVectorisedWriter(writer); ok {
return vectorisedWriter
}
return &SerialVectorisedWriter{upstream: writer}
return &BufferedVectorisedWriter{upstream: writer}
}
func CreateVectorisedWriter(writer any) (N.VectorisedWriter, bool) {
@ -57,26 +56,30 @@ func CreateVectorisedPacketWriter(writer any) (N.VectorisedPacketWriter, bool) {
return nil, false
}
var _ N.VectorisedWriter = (*SerialVectorisedWriter)(nil)
var _ N.VectorisedWriter = (*BufferedVectorisedWriter)(nil)
type SerialVectorisedWriter struct {
type BufferedVectorisedWriter struct {
upstream io.Writer
access sync.Mutex
}
func (w *SerialVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
w.access.Lock()
defer w.access.Unlock()
for _, buffer := range buffers {
_, err := w.upstream.Write(buffer.Bytes())
if err != nil {
return err
}
func (w *BufferedVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
defer buf.ReleaseMulti(buffers)
bufferLen := buf.LenMulti(buffers)
var bufferBytes []byte
if bufferLen > 65535 {
bufferBytes = make([]byte, bufferLen)
} else {
_buffer := buf.StackNewSize(bufferLen)
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
bufferBytes = buffer.FreeBytes()
}
return nil
buf.CopyMulti(bufferBytes, buffers)
return common.Error(w.upstream.Write(bufferBytes))
}
func (w *SerialVectorisedWriter) Upstream() any {
func (w *BufferedVectorisedWriter) Upstream() any {
return w.upstream
}

2
go.sum
View file

@ -1,4 +1,2 @@
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=