-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathoutput.go
134 lines (99 loc) · 2.03 KB
/
output.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
package flow
import (
"encoding/json"
"sync"
"github.com/gogap/context"
)
type outputKey struct{}
type NameValue struct {
Name string `json:"name"`
Value json.RawMessage `json:"value"`
Tags []string `json:"tags,omitempty"`
}
type Output struct {
item NameValue
next *Output
locker sync.Mutex
}
func (p *Output) List() []NameValue {
if p == nil {
return nil
}
var nv []NameValue
output := p
for output != nil {
nv = append(nv, NameValue{output.item.Name, output.item.Value, output.item.Tags})
if output.next != nil {
output = output.next
continue
}
return nv
}
return nil
}
func (p *Output) Append(items ...NameValue) {
p.locker.Lock()
defer p.locker.Unlock()
output := p
for output != nil {
if output.next != nil {
output = output.next
continue
}
for _, item := range items {
output.next = &Output{item: item}
output = output.next
}
return
}
}
func AppendOutput(ctx context.Context, items ...NameValue) {
if ctx == nil {
return
}
output, ok := ctx.Value(outputKey{}).(*Output)
if !ok || output == nil {
output = &Output{}
output.Append(items...)
ctx.WithValue(outputKey{}, output.next)
return
}
output.Append(items...)
}
func ListOutput(ctx context.Context) []NameValue {
if ctx == nil {
return nil
}
output, ok := ctx.Value(outputKey{}).(*Output)
if !ok {
return nil
}
return output.List()
}
func FindOutput(ctx context.Context, name string, tags ...string) []NameValue {
outputList := ListOutput(ctx)
var matched []NameValue
for i := 0; i < len(outputList); i++ {
if name != outputList[i].Name {
continue
}
if !isTagsMatched(tags, outputList[i].Tags) {
continue
}
matched = append(matched, outputList[i])
}
return matched
}
func isTagsMatched(tagsA []string, tagsB []string) bool {
mapTagsB := map[string]bool{}
for i := 0; i < len(tagsB); i++ {
mapTagsB[tagsB[i]] = true
}
matched := 0
for i := 0; i < len(tagsA); i++ {
if mapTagsB[tagsA[i]] == true {
matched++
}
}
return matched == len(tagsA)
}