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.
|
||||
type AdaptiveReader struct {
|
||||
reader io.Reader
|
||||
allocate func() *alloc.Buffer
|
||||
reader io.Reader
|
||||
largeBuffer *alloc.Buffer
|
||||
highVolumn bool
|
||||
}
|
||||
|
||||
// NewAdaptiveReader creates a new AdaptiveReader.
|
||||
// The AdaptiveReader instance doesn't take the ownership of reader.
|
||||
func NewAdaptiveReader(reader io.Reader) *AdaptiveReader {
|
||||
return &AdaptiveReader{
|
||||
reader: reader,
|
||||
allocate: alloc.NewBuffer,
|
||||
reader: reader,
|
||||
}
|
||||
}
|
||||
|
||||
// Read implements Reader.Read().
|
||||
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)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if buffer.IsFull() {
|
||||
v.highVolumn = true
|
||||
}
|
||||
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,17 @@ func TestAdaptiveReader(t *testing.T) {
|
|||
assert := assert.On(t)
|
||||
|
||||
rawContent := make([]byte, 1024*1024)
|
||||
buffer := bytes.NewBuffer(rawContent)
|
||||
|
||||
reader := NewAdaptiveReader(bytes.NewBuffer(rawContent))
|
||||
reader := NewAdaptiveReader(buffer)
|
||||
b1, err := reader.Read()
|
||||
assert.Error(err).IsNil()
|
||||
assert.Bool(b1.IsFull()).IsTrue()
|
||||
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