-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathawaitable-slice-string.go
114 lines (101 loc) · 2.7 KB
/
awaitable-slice-string.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
/*
© 2024–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
import (
"fmt"
"strings"
"github.com/haraldrudell/parl/pslices"
)
func AwaitableSliceString[T any](a *AwaitableSlice[T]) (s string) {
defer a.outputLock.Unlock()
defer a.queueLock.Unlock()
a.outputLock.Lock()
a.queueLock.Lock()
var sL []string
// behind queueLock
sL = append(sL, Sprintf(
"hasData: %t q %s slices %s loc %t cached %d",
// “hasData: false”
a.hasData.Load(),
// queue: “q 0(10)”
printSlice(a.queue),
// slices, slices0, isLocalSlice, cachedInput
// “slices 0(cap0/0 tot0 offs-1) loc false cached 10”
printSlice2Away(a.slices, a.slices0), a.isLocalSlice, cap(a.cachedInput),
))
// behind outputLock
sL = append(sL, Sprintf(
" out %s outs %s cached %d",
// output output0: “out 0(cap 9/10 offs 1)”
printSliceAway(a.output, a.output0),
// outputs outputs0 cachedOutput
// “outs 0(cap0/0 tot0 offs-1) cached 10”
printSlice2Away(a.outputs, a.outputs0), cap(a.cachedOutput),
))
// data Wait
var isEmptyWait = a.isEmptyWait.IsClosed()
var isEmpty bool
if isEmptyWait {
isEmpty = a.isEmpty.IsClosed()
}
sL = append(sL, Sprintf(
" data %s end act-cls:%t-%t",
// dataWait: “data act-cls-chc:false-false-false”
printCyclic(&a.dataWait),
// end: “end act-cls:false-false”
isEmptyWait, isEmpty,
))
s = strings.Join(sL, "\n")
return
}
// printCyclic returns cyclic state “act-cls-chc:false-false-false”
func printCyclic(c *LazyCyclic) (s2 string) {
var isActive, isClosed, isChannelClosed bool
if isActive = c.IsActive.Load(); isActive {
isClosed = c.Cyclic.IsClosed()
select {
case <-c.Cyclic.Ch():
isChannelClosed = true
default:
}
}
return fmt.Sprintf(
"act-cls-chc:%t-%t-%t",
// whether active
isActive,
// is-closed flag
isClosed,
// channel actually closed
isChannelClosed,
)
}
// printSlice returns slice state “1(10)”
func printSlice[T any](s []T) (s2 string) { return fmt.Sprintf("%d(%d)", len(s), cap(s)) }
// printSliceAway returns slice-away state “0(cap 9/10 offs 1)”
func printSliceAway[T any](s, s0 []T) (s2 string) {
var offset, hasValue = pslices.Offset(s0, s)
if !hasValue {
offset = -1
}
return fmt.Sprintf(
"%d(cap%d/%d offs%d)",
len(s), cap(s), cap(s0), offset,
)
}
// printSlice2Away returns slice-of-slices slice-away state “0(cap0/0 tot0 offs-1)”
func printSlice2Away[T any](s, s0 [][]T) (s2 string) {
var offset, hasValue = pslices.Offset(s0, s)
if !hasValue {
offset = -1
}
var total int
for _, sx := range s {
total += len(sx)
}
return fmt.Sprintf(
"%d(cap%d/%d tot%d offs%d)",
len(s), cap(s), cap(s0), total, offset,
)
}