master
go 93 lines 1.59 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package confgroup
4
5 func NewCache() *Cache {
6 return &Cache{
7 hashes: make(map[uint64]uint),
8 sources: make(map[string]map[uint64]Config),
9 }
10 }
11
12 type Cache struct {
13 hashes map[uint64]uint // map[cfgHash]cfgCount
14 sources map[string]map[uint64]Config // map[cfgSource]map[cfgHash]cfg
15 }
16
17 func (c *Cache) Add(group *Group) (added, removed []Config) {
18 if group == nil {
19 return nil, nil
20 }
21
22 if len(group.Configs) == 0 {
23 return c.addEmpty(group)
24 }
25
26 return c.addNotEmpty(group)
27 }
28
29 func (c *Cache) addEmpty(group *Group) (added, removed []Config) {
30 set, ok := c.sources[group.Source]
31 if !ok {
32 return nil, nil
33 }
34
35 for hash, cfg := range set {
36 c.hashes[hash]--
37 if c.hashes[hash] == 0 {
38 removed = append(removed, cfg)
39 }
40 delete(set, hash)
41 }
42
43 delete(c.sources, group.Source)
44
45 return nil, removed
46 }
47
48 func (c *Cache) addNotEmpty(group *Group) (added, removed []Config) {
49 set, ok := c.sources[group.Source]
50 if !ok {
51 set = make(map[uint64]Config)
52 c.sources[group.Source] = set
53 }
54
55 seen := make(map[uint64]struct{})
56
57 for _, cfg := range group.Configs {
58 hash := cfg.Hash()
59 seen[hash] = struct{}{}
60
61 if _, ok := set[hash]; ok {
62 continue
63 }
64
65 set[hash] = cfg
66 if c.hashes[hash] == 0 {
67 added = append(added, cfg)
68 }
69 c.hashes[hash]++
70 }
71
72 if !ok {
73 return added, nil
74 }
75
76 for hash, cfg := range set {
77 if _, ok := seen[hash]; ok {
78 continue
79 }
80
81 delete(set, hash)
82 c.hashes[hash]--
83 if c.hashes[hash] == 0 {
84 removed = append(removed, cfg)
85 }
86 }
87
88 if len(set) == 0 {
89 delete(c.sources, group.Source)
90 }
91
92 return added, removed
93 }