Переглянути джерело

bring back high volumn mode in adaptive reader

Darien Raymond 9 роки тому
батько
коміт
3ba5ab3291
2 змінених файлів з 35 додано та 6 видалено
  1. 27 5
      common/io/reader.go
  2. 8 1
      common/io/reader_test.go

+ 27 - 5
common/io/reader.go

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

+ 8 - 1
common/io/reader_test.go

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