// Provides leaky buffer, based on the example in Effective Go. package leakybuf type LeakyBuf struct { bufSize int // size of each buffer freeList chan []byte } // NewLeakyBuf creates a leaky buffer which can hold at most n buffer, each // with bufSize bytes. func NewLeakyBuf(n, bufSize int) *LeakyBuf { return &LeakyBuf{ bufSize: bufSize, freeList: make(chan []byte, n), } } // Get returns a buffer from the leaky buffer or create a new buffer. func (lb *LeakyBuf) Get() (b []byte) { select { case b = <-lb.freeList: default: b = make([]byte, lb.bufSize) } return } // Put add the buffer into the free buffer pool for reuse. Panic if the buffer // size is not the same with the leaky buffer's. This is intended to expose // error usage of leaky buffer. func (lb *LeakyBuf) Put(b []byte) { if len(b) != lb.bufSize { panic("invalid buffer size that's put into leaky buffer") } select { case lb.freeList <- b: default: } return } const ( GlobalLeakyBufSize = 32 * 1024 // data.len(2) + hmacsha1(10) + data(4096) maxNBuf = 8192 ) var GlobalLeakyBuf = NewLeakyBuf(maxNBuf, GlobalLeakyBufSize)