-
Notifications
You must be signed in to change notification settings - Fork 312
/
resource_map.go
53 lines (44 loc) · 1.22 KB
/
resource_map.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
package rtconfgen
import "fmt"
// A resource is an object with a unique resource id (rid).
type resource interface {
GetRid() string
}
type resourceKey struct {
typ string
rid string
}
// A resourceSet tracks whether a resource has been seen before based on its id,
// and allows efficient lookup of a resource by id.
type resourceSet struct {
m map[resourceKey]any
}
// rsAdd adds a resource to the set. It reports whether the resource was added.
func rsAdd[R any](rs *resourceSet, rid string, fn func() R) (val R, added bool) {
key := internalRSKeyByID[R](rid)
if existing := rs.m[key]; existing != nil {
return existing.(R), false
}
if rs.m == nil {
rs.m = make(map[resourceKey]any)
}
val = fn()
rs.m[key] = val
return val, true
}
func internalRSKeyByID[R any](rid string) resourceKey {
var zero R
typ := fmt.Sprintf("%T", zero)
return resourceKey{typ, rid}
}
func addResFunc[R any](dst *[]R, rs *resourceSet, rid string, fn func() R) (stored R) {
*dst, stored = appendResFunc(*dst, rs, rid, fn)
return stored
}
func appendResFunc[R any](dst []R, rs *resourceSet, rid string, fn func() R) (result []R, stored R) {
stored, updated := rsAdd(rs, rid, fn)
if updated {
dst = append(dst, stored)
}
return dst, stored
}