Commit 61e1fa01 authored by AlexStocks's avatar AlexStocks

Rft: object pool

parent d38547d0
...@@ -23,12 +23,18 @@ import ( ...@@ -23,12 +23,18 @@ import (
) )
var ( var (
defaultPool BytesBufferPool defaultPool *ObjectPool
) )
func init() {
defaultPool = NewObjectPool(func() PoolObject {
return new(bytes.Buffer)
})
}
// GetBytesBuffer returns bytes.Buffer from pool // GetBytesBuffer returns bytes.Buffer from pool
func GetBytesBuffer() *bytes.Buffer { func GetBytesBuffer() *bytes.Buffer {
return defaultPool.Get() return defaultPool.Get().(*bytes.Buffer)
} }
// PutIoBuffer returns IoBuffer to pool // PutIoBuffer returns IoBuffer to pool
...@@ -36,23 +42,35 @@ func PutBytesBuffer(buf *bytes.Buffer) { ...@@ -36,23 +42,35 @@ func PutBytesBuffer(buf *bytes.Buffer) {
defaultPool.Put(buf) defaultPool.Put(buf)
} }
// BytesBufferPool is bytes.Buffer Pool // Pool object
type BytesBufferPool struct { type PoolObject interface {
Reset()
}
type New func() PoolObject
// Pool is bytes.Buffer Pool
type ObjectPool struct {
New New
pool sync.Pool pool sync.Pool
} }
func NewObjectPool(n New) *ObjectPool {
return &ObjectPool{New: n}
}
// take returns *bytes.Buffer from Pool // take returns *bytes.Buffer from Pool
func (p *BytesBufferPool) Get() *bytes.Buffer { func (p *ObjectPool) Get() PoolObject {
v := p.pool.Get() v := p.pool.Get()
if v == nil { if v == nil {
return new(bytes.Buffer) return p.New()
} }
return v.(*bytes.Buffer) return v.(PoolObject)
} }
// give returns *byes.Buffer to Pool // give returns *byes.Buffer to Pool
func (p *BytesBufferPool) Put(buf *bytes.Buffer) { func (p *ObjectPool) Put(o PoolObject) {
buf.Reset() o.Reset()
p.pool.Put(buf) p.pool.Put(o)
} }
...@@ -12,4 +12,11 @@ func TestBytesBufferPool(t *testing.T) { ...@@ -12,4 +12,11 @@ func TestBytesBufferPool(t *testing.T) {
t.Error("iobuffer len not match write bytes' size") t.Error("iobuffer len not match write bytes' size")
} }
PutBytesBuffer(buf) PutBytesBuffer(buf)
buf2 := GetBytesBuffer()
// https://go-review.googlesource.com/c/go/+/162919/
// before go 1.13, sync.Pool just reserves some objs before every gc and will be cleanup by gc.
// after Go 1.13, maybe there are many reserved objs after gc.
if buf != buf2 {
t.Errorf("buf pointer %p != buf2 pointer %p", buf, buf2)
}
} }
...@@ -18,6 +18,15 @@ func intN(n int) int { ...@@ -18,6 +18,15 @@ func intN(n int) int {
return rand.Intn(n) + 1 return rand.Intn(n) + 1
} }
func ExampleGetBytes() {
// Obtain a buffer from the pool.
bufPtr := GetBytes(16)
defer PutBytes(bufPtr)
buf := *bufPtr
copy(buf, []byte("hello, world"))
println(string(buf))
}
func TestSlicePoolSmallBytes(t *testing.T) { func TestSlicePoolSmallBytes(t *testing.T) {
pool := NewSlicePool() pool := NewSlicePool()
......
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