diff options
Diffstat (limited to 'vendor/github.com/vmihailenco/bufpool/buf_pool.go')
| -rw-r--r-- | vendor/github.com/vmihailenco/bufpool/buf_pool.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/vendor/github.com/vmihailenco/bufpool/buf_pool.go b/vendor/github.com/vmihailenco/bufpool/buf_pool.go new file mode 100644 index 000000000..2daa69888 --- /dev/null +++ b/vendor/github.com/vmihailenco/bufpool/buf_pool.go @@ -0,0 +1,67 @@ +package bufpool + +import ( + "log" + "sync" +) + +var thePool bufPool + +// Get retrieves a buffer of the appropriate length from the buffer pool or +// allocates a new one. Get may choose to ignore the pool and treat it as empty. +// Callers should not assume any relation between values passed to Put and the +// values returned by Get. +// +// If no suitable buffer exists in the pool, Get creates one. +func Get(length int) *Buffer { + return thePool.Get(length) +} + +// Put returns a buffer to the buffer pool. +func Put(buf *Buffer) { + thePool.Put(buf) +} + +type bufPool struct { + pools [steps]sync.Pool +} + +func (p *bufPool) Get(length int) *Buffer { + if length > maxPoolSize { + return NewBuffer(make([]byte, length)) + } + + idx := index(length) + if bufIface := p.pools[idx].Get(); bufIface != nil { + buf := bufIface.(*Buffer) + unlock(buf) + if length > buf.Cap() { + log.Println(idx, buf.Len(), buf.Cap(), buf.String()) + } + buf.buf = buf.buf[:length] + return buf + } + + b := make([]byte, length, indexSize(idx)) + return NewBuffer(b) +} + +func (p *bufPool) Put(buf *Buffer) { + length := buf.Cap() + if length > maxPoolSize || length < minSize { + return // drop it + } + + idx := prevIndex(length) + lock(buf) + p.pools[idx].Put(buf) +} + +func lock(buf *Buffer) { + buf.buf = buf.buf[:cap(buf.buf)] + buf.off = cap(buf.buf) + 1 +} + +func unlock(buf *Buffer) { + buf.off = 0 +} |
