-
Notifications
You must be signed in to change notification settings - Fork 205
/
stack.go
69 lines (61 loc) · 1.19 KB
/
stack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package chunk
import (
"container/list"
"sync"
)
// Stack is a thread safe list/stack implementation
type Stack struct {
items *list.List
index map[string]*list.Element
len int
lock sync.Mutex
maxSize int
}
// NewStack creates a new stack
func NewStack(maxChunks int) *Stack {
return &Stack{
items: list.New(),
index: make(map[string]*list.Element, maxChunks),
maxSize: maxChunks,
}
}
// Pop pops the first item from the stack
func (s *Stack) Pop() string {
s.lock.Lock()
if s.len < s.maxSize {
s.lock.Unlock()
return ""
}
item := s.items.Front()
if nil == item {
s.lock.Unlock()
return ""
}
s.items.Remove(item)
s.len--
id := item.Value.(string)
delete(s.index, id)
s.lock.Unlock()
return id
}
// Touch moves the specified item to the last position of the stack
func (s *Stack) Touch(id string) {
s.lock.Lock()
item, exists := s.index[id]
if exists {
s.items.MoveToBack(item)
}
s.lock.Unlock()
}
// Push adds a new item to the last position of the stack
func (s *Stack) Push(id string) {
s.lock.Lock()
if _, exists := s.index[id]; exists {
s.lock.Unlock()
return
}
s.items.PushBack(id)
s.index[id] = s.items.Back()
s.len++
s.lock.Unlock()
}