76 lines
1.4 KiB
Go
76 lines
1.4 KiB
Go
package chunk
|
|
|
|
import (
|
|
"container/list"
|
|
"sync"
|
|
)
|
|
|
|
// Stack is a thread safe list/stack implementation
|
|
type Stack struct {
|
|
items *list.List
|
|
lock sync.Mutex
|
|
maxSize int
|
|
}
|
|
|
|
// NewStack creates a new stack
|
|
func NewStack(maxChunks int) *Stack {
|
|
return &Stack{
|
|
items: list.New(),
|
|
maxSize: maxChunks,
|
|
}
|
|
}
|
|
|
|
// Len gets the number of items on the stack
|
|
func (s *Stack) Len() int {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
return s.items.Len()
|
|
}
|
|
|
|
// Pop pops the first item from the stack
|
|
func (s *Stack) Pop() int {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
if s.items.Len() < s.maxSize {
|
|
return -1
|
|
}
|
|
item := s.items.Front()
|
|
if nil == item {
|
|
return -1
|
|
}
|
|
s.items.Remove(item)
|
|
return item.Value.(int)
|
|
}
|
|
|
|
// Touch moves the specified item to the last position of the stack
|
|
func (s *Stack) Touch(item *list.Element) {
|
|
s.lock.Lock()
|
|
if item != s.items.Back() {
|
|
s.items.MoveToBack(item)
|
|
}
|
|
s.lock.Unlock()
|
|
}
|
|
|
|
// Push adds a new item to the last position of the stack
|
|
func (s *Stack) Push(id int) *list.Element {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
return s.items.PushBack(id)
|
|
}
|
|
|
|
// Prepend adds a list to the front of the stack
|
|
func (s *Stack) Prepend(items *list.List) {
|
|
s.lock.Lock()
|
|
s.items.PushFrontList(items)
|
|
s.lock.Unlock()
|
|
}
|
|
|
|
// Purge an item from the stack
|
|
func (s *Stack) Purge(item *list.Element) {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
if item != s.items.Front() {
|
|
s.items.MoveToFront(item)
|
|
}
|
|
}
|