Commit deedd3bb authored by Steven Allen's avatar Steven Allen

support large slices

They won't use the buffer pool but it doesn't hurt to be nice to the user by
allocating such slices anyways.
parent cb18b794
...@@ -48,15 +48,18 @@ type BufferPool struct { ...@@ -48,15 +48,18 @@ type BufferPool struct {
// values returned by Get. // values returned by Get.
// //
// If no suitable buffer exists in the pool, Get creates one. // If no suitable buffer exists in the pool, Get creates one.
func (p *BufferPool) Get(length uint32) []byte { func (p *BufferPool) Get(length int) []byte {
if length == 0 { if length == 0 {
return nil return nil
} }
idx := nextLogBase2(length) if length > MaxLength {
return make([]byte, length)
}
idx := nextLogBase2(uint32(length))
if buf := p.pools[idx].Get(); buf != nil { if buf := p.pools[idx].Get(); buf != nil {
return buf.([]byte)[:length] return buf.([]byte)[:uint32(length)]
} }
return make([]byte, 1<<idx)[:length] return make([]byte, 1<<idx)[:uint32(length)]
} }
// Put adds x to the pool. // Put adds x to the pool.
...@@ -71,7 +74,7 @@ func (p *BufferPool) Put(buf []byte) { ...@@ -71,7 +74,7 @@ func (p *BufferPool) Put(buf []byte) {
// Get retrieves a buffer of the appropriate length from the global buffer pool // Get retrieves a buffer of the appropriate length from the global buffer pool
// (or allocates a new one). // (or allocates a new one).
func Get(length uint32) []byte { func Get(length int) []byte {
return GlobalPool.Get(length) return GlobalPool.Get(length)
} }
......
...@@ -65,7 +65,7 @@ func TestPoolStressByteSlicePool(t *testing.T) { ...@@ -65,7 +65,7 @@ func TestPoolStressByteSlicePool(t *testing.T) {
const P = 10 const P = 10
chs := 10 chs := 10
maxSize := uint32(1 << 16) maxSize := 1 << 16
N := int(1e4) N := int(1e4)
if testing.Short() { if testing.Short() {
N /= 100 N /= 100
...@@ -77,18 +77,18 @@ func TestPoolStressByteSlicePool(t *testing.T) { ...@@ -77,18 +77,18 @@ func TestPoolStressByteSlicePool(t *testing.T) {
ch := make(chan []byte, chs+1) ch := make(chan []byte, chs+1)
for i := 0; i < chs; i++ { for i := 0; i < chs; i++ {
j := rand.Uint32() % maxSize j := rand.Int() % maxSize
ch <- p.Get(j) ch <- p.Get(j)
} }
for j := 0; j < N; j++ { for j := 0; j < N; j++ {
r := uint32(0) r := 0
for i := 0; i < chs; i++ { for i := 0; i < chs; i++ {
v := <-ch v := <-ch
p.Put(v) p.Put(v)
r = rand.Uint32() % maxSize r = rand.Int() % maxSize
v = p.Get(r) v = p.Get(r)
if uint32(len(v)) < r { if len(v) < r {
errs <- fmt.Errorf("expect len(v) >= %d, got %d", j, len(v)) errs <- fmt.Errorf("expect len(v) >= %d, got %d", j, len(v))
} }
ch <- v ch <- v
...@@ -115,7 +115,7 @@ func TestPoolStressByteSlicePool(t *testing.T) { ...@@ -115,7 +115,7 @@ func TestPoolStressByteSlicePool(t *testing.T) {
func BenchmarkPool(b *testing.B) { func BenchmarkPool(b *testing.B) {
var p BufferPool var p BufferPool
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
i := uint32(7) i := 7
for pb.Next() { for pb.Next() {
if i > 1<<20 { if i > 1<<20 {
i = 7 i = 7
...@@ -135,7 +135,7 @@ func BenchmarkPoolOverlflow(b *testing.B) { ...@@ -135,7 +135,7 @@ func BenchmarkPoolOverlflow(b *testing.B) {
bufs := make([][]byte, 2100) bufs := make([][]byte, 2100)
for pow := uint32(0); pow < 21; pow++ { for pow := uint32(0); pow < 21; pow++ {
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
bufs = append(bufs, p.Get(uint32(1<<pow))) bufs = append(bufs, p.Get(1<<pow))
} }
} }
for _, b := range bufs { for _, b := range bufs {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment