Repository navigation
Expand file tree
/
Copy pathasync_list.go
More file actions
107 lines (82 loc) · 1.81 KB
/
Copy pathasync_list.go
File metadata and controls
107 lines (82 loc) · 1.81 KB
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
package co
import (
"sync"
"sync/atomic"
)
type List[R any] struct {
list []R
rwmux sync.RWMutex
}
func NewList[R any]() *List[R] {
return &List[R]{list: make([]R, 0)}
}
func (l *List[R]) len() int {
l.rwmux.RLock()
defer l.rwmux.RUnlock()
return len(l.list)
}
func (l *List[R]) popFirst() R {
l.rwmux.Lock()
defer l.rwmux.Unlock()
var result R
result, l.list = l.list[0], l.list[1:]
return result
}
func (l *List[R]) getAt(i int) R {
l.rwmux.RLock()
defer l.rwmux.RUnlock()
return l.list[i]
}
func (l *List[R]) setAt(i int, val R) {
l.rwmux.Lock()
defer l.rwmux.Unlock()
l.resizeToInternal(i + 1)
l.list[i] = val
}
func (l *List[R]) add(items ...R) {
l.rwmux.Lock()
defer l.rwmux.Unlock()
l.list = append(l.list, items...)
}
func (l *List[R]) resizeTo(size int) {
l.rwmux.Lock()
defer l.rwmux.Unlock()
l.resizeToInternal(size)
}
func (l *List[R]) resizeToInternal(size int) {
if size <= len(l.list) {
return
}
l.list = append(l.list, make([]R, size-len(l.list))...)
}
type iterativeList[R any] struct {
List[R]
}
func NewIterativeList[R any]() *iterativeList[R] {
return &iterativeList[R]{
List: List[R]{list: make([]R, 0)},
}
}
func (l *iterativeList[R]) iterator() *iterativeListIterator[R] {
it := &iterativeListIterator[R]{
iterativeList: l,
currentIndex: 0,
}
it.asyncSequenceIterator = NewAsyncSequenceIterator[R](it)
return it
}
type iterativeListIterator[R any] struct {
*asyncSequenceIterator[R]
*iterativeList[R]
currentIndex int32
}
func (it *iterativeListIterator[R]) preflight() bool {
return atomic.LoadInt32(&it.currentIndex) < int32(it.len())
}
func (it *iterativeListIterator[R]) next() *Optional[R] {
if !it.preflight() {
return NewOptionalEmpty[R]()
}
defer func() { atomic.AddInt32(&it.currentIndex, 1) }()
return OptionalOf(it.list[it.currentIndex])
}