github.com/Nigel2392/go-datastructures@v1.1.5/stack/stack.go (about) 1 package stack 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/Nigel2392/go-datastructures/linkedlist" 8 ) 9 10 // Stack is a stack data structure 11 // 12 // # It is implemeneted using a singly linked list 13 // 14 // # This is to save space, as the stack only needs to know about the top element 15 // 16 // This does mean that the data gets prepended at the start, and then shifted off, 17 // as opposed to appended and then popped off. 18 type Stack[T any] linkedlist.Singly[T] 19 20 // Push adds a value to the top of the stack 21 // 22 // This is the same as Prepend in a linked list 23 func (s *Stack[T]) Push(value T) { 24 (*linkedlist.Singly[T])(s).Prepend(value) 25 } 26 27 // Pop removes a value from the top of the stack 28 // 29 // This is the same as Shift in a linked list 30 func (s *Stack[T]) Pop() T { 31 return (*linkedlist.Singly[T])(s).Shift() 32 } 33 34 // PopOK removes a value from the top of the stack 35 // 36 // # This is the same as Shift in a linked list 37 // 38 // It returns the value and a boolean indicating whether the value was removed 39 func (s *Stack[T]) PopOK() (value T, ok bool) { 40 if s.Len() == 0 { 41 return 42 } 43 return (*linkedlist.Singly[T])(s).Shift(), true 44 } 45 46 // PopWaiter allows you to wait on a value through a channel. 47 func (s *Stack[T]) PopWaiter(sleep time.Duration) <-chan T { 48 var c = make(chan T, 1) 49 var mu = new(sync.Mutex) 50 go s.wait(mu, c, sleep) 51 return c 52 } 53 54 func (s *Stack[T]) wait(mu *sync.Mutex, c chan<- T, sleep time.Duration) { 55 for { 56 if s.Len() > 0 { 57 mu.Lock() 58 // Check again to make sure it wasn't removed 59 if s.Len() <= 0 { 60 mu.Unlock() 61 continue 62 } 63 c <- (*linkedlist.Singly[T])(s).Shift() 64 close(c) 65 mu.Unlock() 66 return 67 } 68 if sleep > 0 { 69 time.Sleep(sleep) 70 } 71 } 72 } 73 74 // PopOKDeadline returns a channel where the value will be sent when it is available 75 func (s *Stack[T]) PopOKDeadline(deadline time.Duration) (ret <-chan T, ok <-chan time.Time) { 76 var deadlineWaiter = time.After(deadline) 77 var c = make(chan T, 1) 78 var mu = new(sync.Mutex) 79 go func(mut *sync.Mutex) { 80 for { 81 select { 82 case <-deadlineWaiter: 83 close(c) 84 return 85 default: 86 if s.Len() > 0 { 87 mut.Lock() 88 defer mut.Unlock() 89 if s.Len() > 0 { 90 c <- (*linkedlist.Singly[T])(s).Shift() 91 close(c) 92 return 93 } 94 } 95 } 96 } 97 }(mu) 98 99 return c, deadlineWaiter 100 101 } 102 103 // Peek returns the value at the top of the stack 104 // 105 // This is the same as Head in a linked list 106 func (s *Stack[T]) Peek() (value T) { 107 var head = (*linkedlist.Singly[T])(s).Head() 108 if head == nil { 109 return // value is zero value 110 } 111 return head.Value() 112 } 113 114 func (s *Stack[T]) Len() int { 115 return (*linkedlist.Singly[T])(s).Len() 116 }