mirror of https://github.com/v2ray/v2ray-core
bring back high volumn mode in adaptive reader
parent
b575de2a55
commit
3ba5ab3291
|
@ -16,28 +16,50 @@ type Reader interface {
|
||||||
|
|
||||||
// AdaptiveReader is a Reader that adjusts its reading speed automatically.
|
// AdaptiveReader is a Reader that adjusts its reading speed automatically.
|
||||||
type AdaptiveReader struct {
|
type AdaptiveReader struct {
|
||||||
reader io.Reader
|
reader io.Reader
|
||||||
allocate func() *alloc.Buffer
|
largeBuffer *alloc.Buffer
|
||||||
|
highVolumn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAdaptiveReader creates a new AdaptiveReader.
|
// NewAdaptiveReader creates a new AdaptiveReader.
|
||||||
// The AdaptiveReader instance doesn't take the ownership of reader.
|
// The AdaptiveReader instance doesn't take the ownership of reader.
|
||||||
func NewAdaptiveReader(reader io.Reader) *AdaptiveReader {
|
func NewAdaptiveReader(reader io.Reader) *AdaptiveReader {
|
||||||
return &AdaptiveReader{
|
return &AdaptiveReader{
|
||||||
reader: reader,
|
reader: reader,
|
||||||
allocate: alloc.NewBuffer,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read implements Reader.Read().
|
// Read implements Reader.Read().
|
||||||
func (v *AdaptiveReader) Read() (*alloc.Buffer, error) {
|
func (v *AdaptiveReader) Read() (*alloc.Buffer, error) {
|
||||||
buffer := v.allocate().Clear()
|
if v.highVolumn && v.largeBuffer.IsEmpty() {
|
||||||
|
if v.largeBuffer == nil {
|
||||||
|
v.largeBuffer = alloc.NewLocalBuffer(256 * 1024).Clear()
|
||||||
|
}
|
||||||
|
nBytes, err := v.largeBuffer.FillFrom(v.reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if nBytes < alloc.BufferSize {
|
||||||
|
v.highVolumn = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer := alloc.NewBuffer().Clear()
|
||||||
|
if !v.largeBuffer.IsEmpty() {
|
||||||
|
buffer.FillFrom(v.largeBuffer)
|
||||||
|
return buffer, nil
|
||||||
|
}
|
||||||
|
|
||||||
_, err := buffer.FillFrom(v.reader)
|
_, err := buffer.FillFrom(v.reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if buffer.IsFull() {
|
||||||
|
v.highVolumn = true
|
||||||
|
}
|
||||||
|
|
||||||
return buffer, nil
|
return buffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,17 @@ func TestAdaptiveReader(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
|
|
||||||
rawContent := make([]byte, 1024*1024)
|
rawContent := make([]byte, 1024*1024)
|
||||||
|
buffer := bytes.NewBuffer(rawContent)
|
||||||
|
|
||||||
reader := NewAdaptiveReader(bytes.NewBuffer(rawContent))
|
reader := NewAdaptiveReader(buffer)
|
||||||
b1, err := reader.Read()
|
b1, err := reader.Read()
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
assert.Bool(b1.IsFull()).IsTrue()
|
assert.Bool(b1.IsFull()).IsTrue()
|
||||||
assert.Int(b1.Len()).Equals(alloc.BufferSize)
|
assert.Int(b1.Len()).Equals(alloc.BufferSize)
|
||||||
|
assert.Int(buffer.Len()).Equals(cap(rawContent) - alloc.BufferSize)
|
||||||
|
|
||||||
|
b2, err := reader.Read()
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
assert.Bool(b2.IsFull()).IsTrue()
|
||||||
|
assert.Int(buffer.Len()).Equals(778272)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue