github.com/grafana/pyroscope@v1.18.0/pkg/model/stack.go (about)

     1  package model
     2  
     3  import "sync"
     4  
     5  var stackIntPool = sync.Pool{
     6  	New: func() interface{} {
     7  		return NewStack[int64]()
     8  	},
     9  }
    10  
    11  var stackNodePool = sync.Pool{
    12  	New: func() interface{} {
    13  		return NewStack[stackNode]()
    14  	},
    15  }
    16  
    17  type stackNode struct {
    18  	xOffset int
    19  	level   int
    20  	node    *node
    21  }
    22  
    23  // Stack is a stack of values. Pushing and popping values is O(1).
    24  type Stack[T any] struct {
    25  	values []T
    26  }
    27  
    28  func NewStack[T any]() *Stack[T] {
    29  	return &Stack[T]{}
    30  }
    31  
    32  // Push adds a value to the top of the stack.
    33  func (s *Stack[T]) Push(v T) {
    34  	s.values = append(s.values, v)
    35  }
    36  
    37  // Pop removes and returns the top value from the stack.
    38  func (s *Stack[T]) Pop() (result T, ok bool) {
    39  	if len(s.values) == 0 {
    40  		ok = false
    41  		return
    42  	}
    43  	top := s.values[len(s.values)-1]
    44  	s.values = s.values[:len(s.values)-1]
    45  	return top, true
    46  }
    47  
    48  // Slice returns a slice of the values in the stack.
    49  // The top value of the stack is at the beginning of the slice.
    50  func (s *Stack[T]) Slice() []T {
    51  	result := make([]T, 0, len(s.values))
    52  	for i := len(s.values) - 1; i >= 0; i-- {
    53  		result = append(result, s.values[i])
    54  	}
    55  	return result
    56  }
    57  
    58  // Reset releases the stack's resources.
    59  func (s *Stack[T]) Reset() {
    60  	s.values = s.values[:0]
    61  }