github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/core/lib/buf/leakybuf.go (about)

     1  // Provides leaky buffer, based on the example in Effective Go.
     2  package buf
     3  
     4  type LeakyBuf struct {
     5  	bufSize  int // size of each buffer
     6  	freeList chan []byte
     7  }
     8  
     9  const LeakyBufSize = 2048 // data.len(2) + hmacsha1(10) + data(4096)
    10  const maxNBuf = 2048
    11  
    12  var LeakyBuffer = NewLeakyBuf(maxNBuf, LeakyBufSize)
    13  
    14  func Get() (b []byte) {
    15  	return LeakyBuffer.Get()
    16  }
    17  func Put(b []byte) {
    18  	LeakyBuffer.Put(b)
    19  }
    20  
    21  // NewLeakyBuf creates a leaky buffer which can hold at most n buffer, each
    22  // with bufSize bytes.
    23  func NewLeakyBuf(n, bufSize int) *LeakyBuf {
    24  	return &LeakyBuf{
    25  		bufSize:  bufSize,
    26  		freeList: make(chan []byte, n),
    27  	}
    28  }
    29  
    30  // Get returns a buffer from the leaky buffer or create a new buffer.
    31  func (lb *LeakyBuf) Get() (b []byte) {
    32  	select {
    33  	case b = <-lb.freeList:
    34  	default:
    35  		b = make([]byte, lb.bufSize)
    36  	}
    37  	return
    38  }
    39  
    40  // Put add the buffer into the free buffer pool for reuse. Panic if the buffer
    41  // size is not the same with the leaky buffer's. This is intended to expose
    42  // error usage of leaky buffer.
    43  func (lb *LeakyBuf) Put(b []byte) {
    44  	if len(b) != lb.bufSize {
    45  		panic("invalid buffer size that's put into leaky buffer")
    46  	}
    47  	select {
    48  	case lb.freeList <- b:
    49  	default:
    50  	}
    51  	return
    52  }