github.com/pkg/sftp@v1.13.6/pool.go (about)

     1  package sftp
     2  
     3  // bufPool provides a pool of byte-slices to be reused in various parts of the package.
     4  // It is safe to use concurrently through a pointer.
     5  type bufPool struct {
     6  	ch   chan []byte
     7  	blen int
     8  }
     9  
    10  func newBufPool(depth, bufLen int) *bufPool {
    11  	return &bufPool{
    12  		ch:   make(chan []byte, depth),
    13  		blen: bufLen,
    14  	}
    15  }
    16  
    17  func (p *bufPool) Get() []byte {
    18  	if p.blen <= 0 {
    19  		panic("bufPool: new buffer creation length must be greater than zero")
    20  	}
    21  
    22  	for {
    23  		select {
    24  		case b := <-p.ch:
    25  			if cap(b) < p.blen {
    26  				// just in case: throw away any buffer with insufficient capacity.
    27  				continue
    28  			}
    29  
    30  			return b[:p.blen]
    31  
    32  		default:
    33  			return make([]byte, p.blen)
    34  		}
    35  	}
    36  }
    37  
    38  func (p *bufPool) Put(b []byte) {
    39  	if p == nil {
    40  		// functional default: no reuse.
    41  		return
    42  	}
    43  
    44  	if cap(b) < p.blen || cap(b) > p.blen*2 {
    45  		// DO NOT reuse buffers with insufficient capacity.
    46  		// This could cause panics when resizing to p.blen.
    47  
    48  		// DO NOT reuse buffers with excessive capacity.
    49  		// This could cause memory leaks.
    50  		return
    51  	}
    52  
    53  	select {
    54  	case p.ch <- b:
    55  	default:
    56  	}
    57  }
    58  
    59  type resChanPool chan chan result
    60  
    61  func newResChanPool(depth int) resChanPool {
    62  	return make(chan chan result, depth)
    63  }
    64  
    65  func (p resChanPool) Get() chan result {
    66  	select {
    67  	case ch := <-p:
    68  		return ch
    69  	default:
    70  		return make(chan result, 1)
    71  	}
    72  }
    73  
    74  func (p resChanPool) Put(ch chan result) {
    75  	select {
    76  	case p <- ch:
    77  	default:
    78  	}
    79  }