Commit bc215a0 1 parent 0e63a05 commit bc215a0 Copy full SHA for bc215a0
File tree 4 files changed +35
-14
lines changed
4 files changed +35
-14
lines changed Original file line number Diff line number Diff line change 1
1
package list
2
2
3
3
import (
4
+ "errors"
4
5
"runtime"
5
6
"sync/atomic"
6
7
"unsafe"
7
8
)
8
9
9
- //thread safe
10
+ // thread safe
10
11
type List [T any ] struct {
11
12
head * node [T ]
12
13
tail * node [T ]
@@ -43,19 +44,25 @@ func (l *List[T]) Push(data T) {
43
44
atomic .StorePointer ((* unsafe .Pointer )(unsafe .Pointer (& l .tail )), unsafe .Pointer (n ))
44
45
}
45
46
46
- //check func is used to check whether the next element can be popped,set nil if don't need it
47
- //return false - when the buf is empty,or the check failed
48
- func (l * List [T ]) Pop (check func (d T ) bool ) (data T , ok bool ) {
47
+ var ErrPopEmpty = errors .New ("pop empty list" )
48
+ var ErrPopCheckFailed = errors .New ("pop list check failed" )
49
+
50
+ // check func is used to check whether the next element can be popped,set nil if don't need it
51
+ // if e == ErrPopCheckFailed the data will return but it will not be poped from the list
52
+ func (l * List [T ]) Pop (check func (d T ) bool ) (data T , e error ) {
49
53
for {
50
54
oldhead := l .head
51
55
if oldhead .next == nil {
56
+ e = ErrPopEmpty
52
57
return
53
58
}
54
59
if check != nil && ! check (oldhead .next .value ) {
60
+ data = oldhead .next .value
61
+ e = ErrPopCheckFailed
55
62
return
56
63
}
57
64
if atomic .CompareAndSwapPointer ((* unsafe .Pointer )(unsafe .Pointer (& l .head )), unsafe .Pointer (oldhead ), unsafe .Pointer (oldhead .next )) {
58
- return oldhead .next .value , true
65
+ return oldhead .next .value , nil
59
66
}
60
67
runtime .Gosched ()
61
68
}
Original file line number Diff line number Diff line change 1
1
package ring
2
2
3
3
import (
4
+ "errors"
4
5
"runtime"
5
6
"sync/atomic"
6
7
)
@@ -37,16 +38,22 @@ func (b *Ring[T]) Push(d T) bool {
37
38
}
38
39
}
39
40
41
+ var ErrPopEmpty = errors .New ("pop empty ring" )
42
+ var ErrPopCheckFailed = errors .New ("pop ring check failed" )
43
+
40
44
// check func is used to check whether the next element can be popped,set nil if don't need it
41
- // return false - when the buf is empty,or the check failed
42
- func (b * Ring [T ]) Pop (check func (d T ) bool ) (data T , ok bool ) {
45
+ // if e == ErrPopCheckFailed the data will return but it will not be poped from the ring
46
+ func (b * Ring [T ]) Pop (check func (d T ) bool ) (data T , e error ) {
43
47
for {
44
48
oldPopTry := atomic .LoadUint64 (& b .popTry )
45
49
if oldPopTry == atomic .LoadUint64 (& b .pushConfirm ) {
50
+ e = ErrPopEmpty
46
51
return
47
52
}
48
53
d := b .data [oldPopTry % atomic .LoadUint64 (& b .length )]
49
54
if check != nil && ! check (d ) {
55
+ data = d
56
+ e = ErrPopCheckFailed
50
57
return
51
58
}
52
59
if ! atomic .CompareAndSwapUint64 (& b .popTry , oldPopTry , oldPopTry + 1 ) {
@@ -55,6 +62,6 @@ func (b *Ring[T]) Pop(check func(d T) bool) (data T, ok bool) {
55
62
for ! atomic .CompareAndSwapUint64 (& b .popConfirm , oldPopTry , oldPopTry + 1 ) {
56
63
runtime .Gosched ()
57
64
}
58
- return d , true
65
+ return d , nil
59
66
}
60
67
}
Original file line number Diff line number Diff line change 1
1
package stack
2
2
3
3
import (
4
+ "errors"
4
5
"runtime"
5
6
"sync/atomic"
6
7
"unsafe"
7
8
)
8
9
9
- //thread safe
10
+ // thread safe
10
11
type Stack [T any ] struct {
11
12
top * node [T ]
12
13
}
@@ -31,19 +32,25 @@ func (s *Stack[T]) Push(data T) {
31
32
}
32
33
}
33
34
34
- //check func is used to check whether the next element can be popped,set nil if don't need it
35
- //return false - when the buf is empty,or the check failed
36
- func (s * Stack [T ]) Pop (check func (d T ) bool ) (data T , ok bool ) {
35
+ var ErrPopEmpty = errors .New ("pop empty stack" )
36
+ var ErrPopCheckFailed = errors .New ("pop stack check failed" )
37
+
38
+ // check func is used to check whether the next element can be popped,set nil if don't need it
39
+ // if e == ErrPopCheckFailed the data will return but it will not be poped from the stack
40
+ func (s * Stack [T ]) Pop (check func (d T ) bool ) (data T , e error ) {
37
41
for {
38
42
oldtop := s .top
39
43
if oldtop .pre == nil {
44
+ e = ErrPopEmpty
40
45
return
41
46
}
42
47
if check != nil && ! check (oldtop .value ) {
48
+ data = oldtop .value
49
+ e = ErrPopCheckFailed
43
50
return
44
51
}
45
52
if atomic .CompareAndSwapPointer ((* unsafe .Pointer )(unsafe .Pointer (& s .top )), unsafe .Pointer (oldtop ), unsafe .Pointer (oldtop .pre )) {
46
- return oldtop .value , true
53
+ return oldtop .value , nil
47
54
}
48
55
runtime .Gosched ()
49
56
}
Original file line number Diff line number Diff line change @@ -92,7 +92,7 @@ func (f *RotateFile) run() {
92
92
}
93
93
}
94
94
write := func () bool {
95
- if tmp , ok := f .caslist .Pop (nil ); ok {
95
+ if tmp , e := f .caslist .Pop (nil ); e == nil {
96
96
buf := tmp
97
97
if n , e := f .buffile .Write (buf ); e != nil {
98
98
fmt .Println ("[rotatefile.run] write error: " + e .Error ())
You can’t perform that action at this time.
0 commit comments