forked from pSpaces/goSpace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
composable_policy.go
166 lines (130 loc) · 3.39 KB
/
composable_policy.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
164
165
166
package policy
import (
"fmt"
"github.com/pspaces/gospace/container"
"strings"
"sync"
)
// Composable is a structure for containing composable policies.
type Composable struct {
ActionMap *sync.Map // [Action]Label
LabelMap *sync.Map // [Label]AggregationPolicy
}
// NewComposable creates a composable policy cp from any amount of aggregation policies aps.
func NewComposable(aps ...Aggregation) (cp *Composable) {
cp = &Composable{ActionMap: new(sync.Map), LabelMap: new(sync.Map)}
for _, ap := range aps {
cp.Add(ap)
}
return cp
}
// Add adds an aggregation policy ap to the composable policy cp.
// Add returns true if the aggregation policy ap has been added to the composable policy cp, and false otherwise.
func (cp *Composable) Add(ap Aggregation) (b bool) {
b = cp != nil
if b {
a := (&ap).Action()
l := (&ap).Label()
as := (&a).Signature()
_, existsLabel := cp.ActionMap.Load(as)
b = !existsLabel
if b {
lid := l.ID()
_, existsPolicy := cp.LabelMap.Load(lid)
b = !existsPolicy
if b {
_, existsPolicy := cp.LabelMap.LoadOrStore(lid, ap)
_, existsLabel := cp.ActionMap.LoadOrStore(as, l)
b = !existsLabel && !existsPolicy
}
}
}
return b
}
// Find returns a reference to a label l given an action a.
func (cp *Composable) Find(a *Action) (l *container.Label) {
b := cp != nil
l = nil
if b {
as := a.Signature()
val, exists := cp.ActionMap.Load(as)
if exists {
lbl := val.(container.Label)
lbl = lbl.DeepCopy()
l = &lbl
}
}
return l
}
// Retrieve returns a reference to the aggregation policy ap with label l from the composable policy cp.
// Retrieve returns a reference if it exists and nil otherwise.
func (cp *Composable) Retrieve(l container.Label) (ap *Aggregation) {
b := cp != nil
ap = nil
if b {
lid := l.ID()
val, exists := cp.LabelMap.Load(lid)
if exists {
pol := val.(Aggregation)
ap = &pol
}
}
return ap
}
// Delete removes an aggregation policy with label l from the composable policy cp.
// Delete returns true if an aggregation policy with label l has been deleted from the composable policy cp, and false otherwise.
func (cp *Composable) Delete(l container.Label) (b bool) {
b = cp != nil
if b {
lid := l.ID()
val, exists := cp.LabelMap.Load(lid)
if exists {
ap := val.(Aggregation)
a := ap.Action()
cp.LabelMap.Delete(l)
cp.ActionMap.Delete(a)
}
b = exists
}
return b
}
// String returns a print friendly representation of a composable policy cp.
func (cp Composable) String() (s string) {
var actionEntries, labelEntries []string
entries := []string{}
entry := make(chan string)
go func() {
cp.ActionMap.Range(func(k, v interface{}) bool {
entry <- fmt.Sprintf("\t%v: %v", k, v)
return true
})
close(entry)
}()
for entry := range entry {
entries = append(entries, entry)
}
actionEntries = entries
entries = []string{}
entry = make(chan string)
go func() {
cp.LabelMap.Range(func(k, v interface{}) bool {
entry <- fmt.Sprintf("\t%v: %v", k, v)
return true
})
close(entry)
}()
for entry := range entry {
entries = append(entries, entry)
}
labelEntries = entries
refs := strings.Join(actionEntries, ",\n")
if refs != "" {
refs = fmt.Sprintf("\n%s\n", refs)
}
names := strings.Join(labelEntries, ",\n")
if names != "" {
names = fmt.Sprintf("\n%s\n", names)
}
s = fmt.Sprintf("%s%s%s%s%s%s", "{", refs, "}", "{", names, "}")
return s
}