This repository has been archived by the owner on Mar 4, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeque.go
173 lines (140 loc) · 3.61 KB
/
deque.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package mesoelevator
// Taken from : https://github.com/oleiade/lane/blob/master/deque.go
// * Modified to add a function for List()
// * Modified to add a String()
// Modified by: Sam Xiao
import (
"fmt"
"container/list"
"sync"
)
// Deque is a head-tail linked list data structure implementation.
// It is based on a doubly linked list container, so that every
// operations time complexity is O(1).
//
// every operations over an instiated Deque are synchronized and
// safe for concurrent usage.
type Deque struct {
sync.RWMutex
container *list.List
capacity int
}
// NewDeque creates a Deque.
func NewDeque() *Deque {
return NewCappedDeque(-1)
}
// NewCappedDeque creates a Deque with the specified capacity limit.
func NewCappedDeque(capacity int) *Deque {
return &Deque{
container: list.New(),
capacity: capacity,
}
}
// Append inserts element at the back of the Deque in a O(1) time complexity,
// returning true if successful or false if the deque is at capacity.
func (s *Deque) Append(item interface{}) bool {
s.Lock()
defer s.Unlock()
if s.capacity < 0 || s.container.Len() < s.capacity {
s.container.PushBack(item)
return true
}
return false
}
// Prepend inserts element at the Deques front in a O(1) time complexity,
// returning true if successful or false if the deque is at capacity.
func (s *Deque) Prepend(item interface{}) bool {
s.Lock()
defer s.Unlock()
if s.capacity < 0 || s.container.Len() < s.capacity {
s.container.PushFront(item)
return true
}
return false
}
// Pop removes the last element of the deque in a O(1) time complexity
func (s *Deque) Pop() interface{} {
s.Lock()
defer s.Unlock()
var item interface{} = nil
var lastContainerItem *list.Element = nil
lastContainerItem = s.container.Back()
if lastContainerItem != nil {
item = s.container.Remove(lastContainerItem)
}
return item
}
// Shift removes the first element of the deque in a O(1) time complexity
func (s *Deque) Shift() interface{} {
s.Lock()
defer s.Unlock()
var item interface{} = nil
var firstContainerItem *list.Element = nil
firstContainerItem = s.container.Front()
if firstContainerItem != nil {
item = s.container.Remove(firstContainerItem)
}
return item
}
// First returns the first value stored in the deque in a O(1) time complexity
func (s *Deque) First() interface{} {
s.RLock()
defer s.RUnlock()
item := s.container.Front()
if item != nil {
return item.Value
} else {
return nil
}
}
// Last returns the last value stored in the deque in a O(1) time complexity
func (s *Deque) Last() interface{} {
s.RLock()
defer s.RUnlock()
item := s.container.Back()
if item != nil {
return item.Value
} else {
return nil
}
}
// Size returns the actual deque size
func (s *Deque) Size() int {
s.RLock()
defer s.RUnlock()
return s.container.Len()
}
// Capacity returns the capacity of the deque, or -1 if unlimited
func (s *Deque) Capacity() int {
s.RLock()
defer s.RUnlock()
return s.capacity
}
// Empty checks if the deque is empty
func (s *Deque) Empty() bool {
s.RLock()
defer s.RUnlock()
return s.container.Len() == 0
}
// Full checks if the deque is full
func (s *Deque) Full() bool {
s.RLock()
defer s.RUnlock()
return s.capacity >= 0 && s.container.Len() >= s.capacity
}
// Convert it to a List()
func (s *Deque) List() ([]interface{}) {
s.RLock()
defer s.RUnlock()
list := make([]interface{}, 0, s.container.Len())
// Iterate through list and print its contents.
for e := s.container.Front(); e != nil; e = e.Next() {
list = append(list, e.Value)
}
return list
}
func (s *Deque) String() string {
s.RLock()
defer s.RUnlock()
return fmt.Sprintf("%v", s.List())
}