mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-04 12:27:37 +03:00
Improve vectorised writer
This commit is contained in:
parent
c875a4ffab
commit
e16845727f
4 changed files with 44 additions and 17 deletions
|
@ -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) {
|
func ReleaseMulti(buffers []*Buffer) {
|
||||||
for _, buffer := range buffers {
|
for _, buffer := range buffers {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
|
|
|
@ -49,11 +49,29 @@ func (c *ChunkReader) Read(p []byte) (n int, err error) {
|
||||||
c.cache.FullReset()
|
c.cache.FullReset()
|
||||||
err = c.upstream.ReadBuffer(c.cache)
|
err = c.upstream.ReadBuffer(c.cache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
c.cache.Release()
|
||||||
|
c.cache = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return c.cache.Read(p)
|
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 {
|
func (c *ChunkReader) MTU() int {
|
||||||
return c.maxChunkSize
|
return c.maxChunkSize
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package bufio
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
@ -16,7 +15,7 @@ func NewVectorisedWriter(writer io.Writer) N.VectorisedWriter {
|
||||||
if vectorisedWriter, ok := CreateVectorisedWriter(writer); ok {
|
if vectorisedWriter, ok := CreateVectorisedWriter(writer); ok {
|
||||||
return vectorisedWriter
|
return vectorisedWriter
|
||||||
}
|
}
|
||||||
return &SerialVectorisedWriter{upstream: writer}
|
return &BufferedVectorisedWriter{upstream: writer}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateVectorisedWriter(writer any) (N.VectorisedWriter, bool) {
|
func CreateVectorisedWriter(writer any) (N.VectorisedWriter, bool) {
|
||||||
|
@ -57,26 +56,30 @@ func CreateVectorisedPacketWriter(writer any) (N.VectorisedPacketWriter, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ N.VectorisedWriter = (*SerialVectorisedWriter)(nil)
|
var _ N.VectorisedWriter = (*BufferedVectorisedWriter)(nil)
|
||||||
|
|
||||||
type SerialVectorisedWriter struct {
|
type BufferedVectorisedWriter struct {
|
||||||
upstream io.Writer
|
upstream io.Writer
|
||||||
access sync.Mutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SerialVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
|
func (w *BufferedVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
|
||||||
w.access.Lock()
|
defer buf.ReleaseMulti(buffers)
|
||||||
defer w.access.Unlock()
|
bufferLen := buf.LenMulti(buffers)
|
||||||
for _, buffer := range buffers {
|
var bufferBytes []byte
|
||||||
_, err := w.upstream.Write(buffer.Bytes())
|
if bufferLen > 65535 {
|
||||||
if err != nil {
|
bufferBytes = make([]byte, bufferLen)
|
||||||
return err
|
} 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
|
return w.upstream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -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 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue