Skip to content

Commit

Permalink
FEAT: Add ZoneCache primitive (#3365)
Browse files Browse the repository at this point in the history
  • Loading branch information
das7pad authored Jan 15, 2025
1 parent 556926a commit 5c9b170
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions pkg/zoneCache/zoneCache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package zoneCache

import (
"errors"
"sync"
)

func New[Zone any](fetchAll func() (map[string]Zone, error)) ZoneCache[Zone] {
return ZoneCache[Zone]{fetchAll: fetchAll}
}

var ErrZoneNotFound = errors.New("zone not found")

type ZoneCache[Zone any] struct {
mu sync.Mutex
cached bool
cache map[string]Zone
fetchAll func() (map[string]Zone, error)
}

func (c *ZoneCache[Zone]) ensureCached() error {
if c.cached {
return nil
}
zones, err := c.fetchAll()
if err != nil {
return err
}
if c.cache == nil {
c.cache = make(map[string]Zone, len(zones))
}
for name, z := range zones {
c.cache[name] = z
}
return nil
}

func (c *ZoneCache[Zone]) HasZone(name string) (bool, error) {
c.mu.Lock()
defer c.mu.Unlock()

if err := c.ensureCached(); err != nil {
return false, err
}
_, ok := c.cache[name]
return ok, nil
}

func (c *ZoneCache[Zone]) GetZone(name string) (Zone, error) {
c.mu.Lock()
defer c.mu.Unlock()

if err := c.ensureCached(); err != nil {
var z Zone
return z, err
}
z, ok := c.cache[name]
if !ok {
return z, ErrZoneNotFound
}
return z, nil
}

func (c *ZoneCache[Zone]) GetZoneNames() ([]string, error) {
c.mu.Lock()
defer c.mu.Unlock()

if err := c.ensureCached(); err != nil {
return nil, err
}
names := make([]string, 0, len(c.cache))
for name := range c.cache {
names = append(names, name)
}
return names, nil
}

func (c *ZoneCache[Zone]) SetZone(name string, z Zone) {
c.mu.Lock()
defer c.mu.Unlock()

if c.cache == nil {
c.cache = make(map[string]Zone, 1)
}
c.cache[name] = z
}

0 comments on commit 5c9b170

Please sign in to comment.