-
Notifications
You must be signed in to change notification settings - Fork 0
/
fastlist.go
163 lines (135 loc) · 3.15 KB
/
fastlist.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
package fastlist
import "sync"
type FastList struct {
sync.RWMutex
elementData []interface{}
size int
safe bool
}
// Creates a new fastlist. Pass true as a parameter to create a concurrency-safe
// list, or false otherwise.
// Returns a FastList
func NewFastList(isSafe bool) FastList {
return FastList{
elementData: make([]interface{}, 0),
size: 0,
safe: isSafe,
}
}
// Adds any element to the list and returns true if added succesfuly
func (fl *FastList) Add(element interface{}) bool {
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
fl.elementData = append(fl.elementData, element)
fl.size++
return true
}
// Returns the element at the specified index or nil if not found
func (fl *FastList) Get(index int) interface{} {
if fl.size <= 0 || index > fl.size-1 || index < 0 {
return nil
}
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
return fl.elementData[index]
}
// Returns the last element from the list and removes it.
// Returns nil if the list is empty
func (fl *FastList) RemoveLast() interface{} {
if fl.size == 0 {
return nil
}
// should it be before the size == 0 check?
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
fl.size--
elem := fl.elementData[fl.size]
fl.elementData = fl.elementData[:fl.size]
return elem
}
// Returns all the elements
func (fl *FastList) GetAll() []interface{} {
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
return fl.elementData
}
// Removes the element at index i
// Most efficient at removing from the end of the list
// Returns true if successfully removed and false if not
func (fl *FastList) RemoveElement(element interface{}) bool {
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
for index := fl.size - 1; index >= 0; index-- {
if element == fl.elementData[index] {
remElement(fl, index)
return true
}
}
return false
}
func remElement(fl *FastList, index int) {
if index == fl.size-1 {
fl.elementData = fl.elementData[:index]
} else {
copy(fl.elementData[index:], fl.elementData[index+1:])
fl.elementData = fl.elementData[:fl.size-1]
}
fl.size--
}
// Clears the list (removes all elements)
func (fl *FastList) Clear() {
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
fl.elementData = fl.elementData[:0]
fl.size = 0
}
// Returns the size of the list
func (fl *FastList) Size() int {
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
return fl.size
}
// Sets an element at the index specified and returns the element
// that was located at the specified location.
// Returns nil if the specified location was empty or did not exist
func (fl *FastList) Set(index int, element interface{}) interface{} {
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
for fl.size <= index {
fl.elementData = append(fl.elementData, nil)
fl.size++
}
old := fl.elementData[index]
fl.elementData[index] = element
return old
}
// Removes an element at the specified index and returns it.
// Returns nil if element does not exist
func (fl *FastList) RemoveIndex(index int) interface{} {
if fl.size <= 0 || index > fl.size-1 || index < 0 {
return nil
}
if fl.safe {
fl.Lock()
defer fl.Unlock()
}
old := fl.elementData[index]
remElement(fl, index)
return old
}