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 }