bring back high volumn mode in adaptive reader

pull/314/head
Darien Raymond 2016-12-02 15:06:04 +01:00
parent b575de2a55
commit 3ba5ab3291
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
2 changed files with 35 additions and 6 deletions

View File

@ -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
} }

View File

@ -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)
} }