Skip to content

Commit 5c9b170

Browse files
authored
FEAT: Add ZoneCache primitive (#3365)
1 parent 556926a commit 5c9b170

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

pkg/zoneCache/zoneCache.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package zoneCache
2+
3+
import (
4+
"errors"
5+
"sync"
6+
)
7+
8+
func New[Zone any](fetchAll func() (map[string]Zone, error)) ZoneCache[Zone] {
9+
return ZoneCache[Zone]{fetchAll: fetchAll}
10+
}
11+
12+
var ErrZoneNotFound = errors.New("zone not found")
13+
14+
type ZoneCache[Zone any] struct {
15+
mu sync.Mutex
16+
cached bool
17+
cache map[string]Zone
18+
fetchAll func() (map[string]Zone, error)
19+
}
20+
21+
func (c *ZoneCache[Zone]) ensureCached() error {
22+
if c.cached {
23+
return nil
24+
}
25+
zones, err := c.fetchAll()
26+
if err != nil {
27+
return err
28+
}
29+
if c.cache == nil {
30+
c.cache = make(map[string]Zone, len(zones))
31+
}
32+
for name, z := range zones {
33+
c.cache[name] = z
34+
}
35+
return nil
36+
}
37+
38+
func (c *ZoneCache[Zone]) HasZone(name string) (bool, error) {
39+
c.mu.Lock()
40+
defer c.mu.Unlock()
41+
42+
if err := c.ensureCached(); err != nil {
43+
return false, err
44+
}
45+
_, ok := c.cache[name]
46+
return ok, nil
47+
}
48+
49+
func (c *ZoneCache[Zone]) GetZone(name string) (Zone, error) {
50+
c.mu.Lock()
51+
defer c.mu.Unlock()
52+
53+
if err := c.ensureCached(); err != nil {
54+
var z Zone
55+
return z, err
56+
}
57+
z, ok := c.cache[name]
58+
if !ok {
59+
return z, ErrZoneNotFound
60+
}
61+
return z, nil
62+
}
63+
64+
func (c *ZoneCache[Zone]) GetZoneNames() ([]string, error) {
65+
c.mu.Lock()
66+
defer c.mu.Unlock()
67+
68+
if err := c.ensureCached(); err != nil {
69+
return nil, err
70+
}
71+
names := make([]string, 0, len(c.cache))
72+
for name := range c.cache {
73+
names = append(names, name)
74+
}
75+
return names, nil
76+
}
77+
78+
func (c *ZoneCache[Zone]) SetZone(name string, z Zone) {
79+
c.mu.Lock()
80+
defer c.mu.Unlock()
81+
82+
if c.cache == nil {
83+
c.cache = make(map[string]Zone, 1)
84+
}
85+
c.cache[name] = z
86+
}

0 commit comments

Comments
 (0)