| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- // Copyright (C) 2016 The Protocol Authors.
- package protocol
- import "sync"
- type bufferPool struct {
- minSize int
- pool sync.Pool
- }
- // get returns a new buffer of the requested size
- func (p *bufferPool) get(size int) []byte {
- intf := p.pool.Get()
- if intf == nil {
- // Pool is empty, must allocate.
- return p.new(size)
- }
- bs := intf.([]byte)
- if cap(bs) < size {
- // Buffer was too small, leave it for someone else and allocate.
- p.put(bs)
- return p.new(size)
- }
- return bs[:size]
- }
- // upgrade grows the buffer to the requested size, while attempting to reuse
- // it if possible.
- func (p *bufferPool) upgrade(bs []byte, size int) []byte {
- if cap(bs) >= size {
- // Reslicing is enough, lets go!
- return bs[:size]
- }
- // It was too small. But it pack into the pool and try to get another
- // buffer.
- p.put(bs)
- return p.get(size)
- }
- // put returns the buffer to the pool
- func (p *bufferPool) put(bs []byte) {
- p.pool.Put(bs)
- }
- // new creates a new buffer of the requested size, taking the minimum
- // allocation count into account. For internal use only.
- func (p *bufferPool) new(size int) []byte {
- allocSize := size
- if allocSize < p.minSize {
- // Avoid allocating tiny buffers that we won't be able to reuse for
- // anything useful.
- allocSize = p.minSize
- }
- return make([]byte, allocSize)[:size]
- }
|