func (l *leafFreelist) Get() LeafBuffer {
	if l == nil {
		lb := allocatorFunc(MaxLeafSize)()
		lb.Reset()
		return lb
	}
	var lb LeafBuffer
	l.mu.Lock()
	ll := len(l.list)
	if ll != 0 {
		lb = l.list[ll-1]
		lb.Reset()
		l.list = l.list[:ll-1]
	} else {
		l.buffers++
	}
	l.mu.Unlock()
	if lb == nil {
		lb = l.allocate()
	}
	return lb
}
Get allocates a new buffer from memory, or yields are recycled one.

NOTE: it is the caller's responsibility, when pinning a buffer as busy, to idle the buffer
so the free list can recycle it.
package cafs
import (
	"math"
	"sync"
	"unsafe"
	"github.com/docker/go-units"
)
const (
	leaf1MB uint32 = 1 * units.MiB
	leaf2MB uint32 = 2 * units.MiB
	leaf3MB uint32 = 3 * units.MiB
	leaf4MB uint32 = 4 * units.MiB
)
func BytesToBuffers(target int, leafSize uint32) int {
	return int(math.Ceil(float64(target) / float64(leafSize)))
}
type FreeList interface {
	Get() LeafBuffer
	Release(LeafBuffer)
	Buffers() int
	FreeBuffers() int
	Size() uint32
}
type LeafBuffer interface {
	Bytes() []byte
	Copy([]byte)
	Slice(low, high int) []byte
	Reset()
	Pin()
	Unpin()
}
type baseBuffer struct {
	slice []byte
	busy  sync.Mutex
}
func (m *baseBuffer) Bytes() []byte {
	return m.slice
}
func (m *baseBuffer) Copy(val []byte) {
	n := copy(m.slice[:cap(m.slice)], val)
	m.slice = m.slice[:n]
}
func (m *baseBuffer) Slice(low, high int) []byte {
	m.slice = m.slice[low:high]
	return m.slice
}
func (m *baseBuffer) Pin() {
	if m == nil {
		return
	}
	m.busy.Lock()
}
func (m *baseBuffer) Unpin() {
	if m == nil {
		return
	}
	m.busy.Unlock()
}
type leafBuffer1MB struct {
	baseBuffer
	buf [leaf1MB]byte
}
func (lb1 *leafBuffer1MB) Size() uint32 {
	return uint32(unsafe.Sizeof(leafBuffer1MB{}))
}
func (lb1 *leafBuffer1MB) Reset() {
	lb1.slice = lb1.buf[:0]
}
type leafBuffer2MB struct {
	baseBuffer
	buf [leaf2MB]byte
}
func (lb2 *leafBuffer2MB) Size() uint32 {
	return uint32(unsafe.Sizeof(leafBuffer2MB{}))
}
func (lb2 *leafBuffer2MB) Reset() {
	lb2.slice = lb2.buf[:0]
}
type leafBuffer3MB struct {
	baseBuffer
	buf [leaf3MB]byte
}
func (lb3 *leafBuffer3MB) Size() uint32 {
	return uint32(unsafe.Sizeof(leafBuffer3MB{}))
}
func (lb3 *leafBuffer3MB) Reset() {
	lb3.slice = lb3.buf[:0]
}
type leafBuffer4MB struct {
	baseBuffer
	buf [leaf4MB]byte
}
func (lb4 *leafBuffer4MB) Size() uint32 {
	return uint32(unsafe.Sizeof(leafBuffer4MB{}))
}
func (lb4 *leafBuffer4MB) Reset() {
	lb4.slice = lb4.buf[:0]
}
type leafBufferMax struct {
	baseBuffer
	buf [MaxLeafSize]byte
}
func (lbm *leafBufferMax) Size() uint32 {
	return uint32(unsafe.Sizeof(leafBufferMax{}))
}
func (lbm *leafBufferMax) Reset() {
	lbm.slice = lbm.buf[:0]
}
func allocatorFunc(leafSize uint32) func() LeafBuffer {
	switch {
	case leafSize <= 1*units.MiB:
		return func() LeafBuffer {
			x := new(leafBuffer1MB)
			x.Reset()
			return x
		}
	case leafSize <= 2*units.MiB:
		return func() LeafBuffer {
			x := new(leafBuffer2MB)
			x.Reset()
			return x
		}
	case leafSize <= 3*units.MiB:
		return func() LeafBuffer {
			x := new(leafBuffer3MB)
			x.Reset()
			return x
		}
	case leafSize <= 4*units.MiB:
		return func() LeafBuffer {
			x := new(leafBuffer4MB)
			x.Reset()
			return x
		}
	default:
		return func() LeafBuffer {
			x := new(leafBufferMax)
			x.Reset()
			return x
		}
	}
}
func sizeFunc(leafSize uint32) func() uint32 {
	switch {
	case leafSize <= 1*units.MiB:
		t := &leafBuffer1MB{}
		x := t.Size()
		return func() uint32 {
			return x
		}
	case leafSize <= 2*units.MiB:
		t := &leafBuffer2MB{}
		x := t.Size()
		return func() uint32 {
			return x
		}
	case leafSize <= 3*units.MiB:
		t := &leafBuffer3MB{}
		x := t.Size()
		return func() uint32 {
			return x
		}
	case leafSize <= 4*units.MiB:
		t := &leafBuffer4MB{}
		x := t.Size()
		return func() uint32 {
			return x
		}
	default:
		t := &leafBufferMax{}
		x := t.Size()
		return func() uint32 {
			return x
		}
	}
}
type leafFreelist struct {
	list      []LeafBuffer
	allocate  func() LeafBuffer
	size      func() uint32
	mu        sync.Mutex
	buffers   int
	watermark int
	wg sync.WaitGroup
}
var _ FreeList = &leafFreelist{}
func newLeafFreelist(leafSize uint32, watermark int) FreeList {
	return &leafFreelist{
		list:      make([]LeafBuffer, 0, watermark),
		allocate:  allocatorFunc(leafSize),
		size:      sizeFunc(leafSize),
		watermark: watermark,
	}
}
func (l *leafFreelist) Buffers() int {
	if l == nil {
		return 0
	}
	l.mu.Lock()
	s := l.buffers
	l.mu.Unlock()
	return s
}
func (l *leafFreelist) FreeBuffers() int {
	if l == nil {
		return 0
	}
	l.mu.Lock()
	s := len(l.list)
	l.mu.Unlock()
	return s
}
func (l *leafFreelist) Size() uint32 {
	if l == nil {
		return 0
	}
	return l.size()
}