nettools/data_structures/stack.go

82 lines
1.4 KiB
Go
Raw Permalink Normal View History

2024-11-12 12:31:54 +00:00
package dsUtils
2024-11-12 08:10:09 +00:00
2024-11-12 12:31:54 +00:00
import (
"io"
"sync"
)
2024-11-12 08:10:09 +00:00
type IStack[T any] interface {
Push(item T)
Get() T
Len() int
}
2024-11-12 12:31:54 +00:00
// Stack isn't thread safe and suppose to be used only in a single thread
// For multithreaded usage -- use Stack
2024-11-12 08:10:09 +00:00
type Stack[T any] struct {
IStack[T]
Buffer []T
}
2024-11-12 12:31:54 +00:00
// NewStack creates a new Stack instance
2024-11-12 08:10:09 +00:00
func NewStack[T any]() *Stack[T] {
return &Stack[T]{}
}
2024-11-12 12:31:54 +00:00
func (s *Stack[T]) Push(item T) {
s.Buffer = append(s.Buffer, item)
2024-11-12 08:10:09 +00:00
}
2024-11-12 12:31:54 +00:00
func (s *Stack[T]) Get() (T, error) {
if len(s.Buffer) == 0 {
var out T
return out, io.EOF
2024-11-12 08:10:09 +00:00
}
2024-11-12 12:31:54 +00:00
item := s.Buffer[len(s.Buffer)-1]
s.Buffer = s.Buffer[:len(s.Buffer)-1]
return item, nil
2024-11-12 08:10:09 +00:00
}
2024-11-12 12:31:54 +00:00
func (s *Stack[T]) Len() int {
return len(s.Buffer)
2024-11-12 08:10:09 +00:00
}
2024-11-12 12:31:54 +00:00
// StackSync is a Stack but for multi thread usage
2024-11-12 08:10:09 +00:00
type StackSync[T any] struct {
IStack[T]
Buffer []T
Mu *sync.Mutex
NonEmptyCond *sync.Cond
}
func NewStackSync[T any]() *StackSync[T] {
return &StackSync[T]{
Mu: &sync.Mutex{},
NonEmptyCond: sync.NewCond(&sync.RWMutex{}),
}
}
2024-11-12 12:31:54 +00:00
func (s *StackSync[T]) Push(item T) {
s.Mu.Lock()
s.Buffer = append(s.Buffer, item)
s.NonEmptyCond.Signal()
s.Mu.Unlock()
2024-11-12 08:10:09 +00:00
}
2024-11-12 12:31:54 +00:00
func (s *StackSync[T]) Get() T {
s.Mu.Lock()
if len(s.Buffer) < 1 {
s.NonEmptyCond.Wait()
2024-11-12 08:10:09 +00:00
}
2024-11-12 12:31:54 +00:00
item := s.Buffer[len(s.Buffer)-1]
s.Buffer = s.Buffer[:len(s.Buffer)-1]
s.Mu.Unlock()
2024-11-12 08:10:09 +00:00
return item
}
2024-11-12 12:31:54 +00:00
func (s *StackSync[T]) Len() int {
s.Mu.Lock()
defer s.Mu.Lock()
return len(s.Buffer)
2024-11-12 08:10:09 +00:00
}