github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/nosync/pool.go (about)

     1  package nosync
     2  
     3  // A Pool is a set of temporary objects that may be individually saved and
     4  // retrieved.
     5  //
     6  // Any item stored in the Pool may be removed automatically at any time without
     7  // notification. If the Pool holds the only reference when this happens, the
     8  // item might be deallocated.
     9  //
    10  // A Pool is safe for use by multiple goroutines simultaneously.
    11  //
    12  // Pool's purpose is to cache allocated but unused items for later reuse,
    13  // relieving pressure on the garbage collector. That is, it makes it easy to
    14  // build efficient, thread-safe free lists. However, it is not suitable for all
    15  // free lists.
    16  //
    17  // An appropriate use of a Pool is to manage a group of temporary items
    18  // silently shared among and potentially reused by concurrent independent
    19  // clients of a package. Pool provides a way to amortize allocation overhead
    20  // across many clients.
    21  //
    22  // An example of good use of a Pool is in the fmt package, which maintains a
    23  // dynamically-sized store of temporary output buffers. The store scales under
    24  // load (when many goroutines are actively printing) and shrinks when
    25  // quiescent.
    26  //
    27  // On the other hand, a free list maintained as part of a short-lived object is
    28  // not a suitable use for a Pool, since the overhead does not amortize well in
    29  // that scenario. It is more efficient to have such objects implement their own
    30  // free list.
    31  //
    32  type Pool struct {
    33  	store []interface{}
    34  	New   func() interface{}
    35  }
    36  
    37  // Get selects an arbitrary item from the Pool, removes it from the
    38  // Pool, and returns it to the caller.
    39  // Get may choose to ignore the pool and treat it as empty.
    40  // Callers should not assume any relation between values passed to Put and
    41  // the values returned by Get.
    42  //
    43  // If Get would otherwise return nil and p.New is non-nil, Get returns
    44  // the result of calling p.New.
    45  func (p *Pool) Get() interface{} {
    46  	if len(p.store) == 0 {
    47  		if p.New != nil {
    48  			return p.New()
    49  		}
    50  		return nil
    51  	}
    52  	x := p.store[len(p.store)-1]
    53  	p.store = p.store[:len(p.store)-1]
    54  	return x
    55  }
    56  
    57  // Put adds x to the pool.
    58  func (p *Pool) Put(x interface{}) {
    59  	if x == nil {
    60  		return
    61  	}
    62  	p.store = append(p.store, x)
    63  }